Back to Docs

Getting Started with DSO

This guide walks you through installing DSO and completing your first deployment in either Local or Cloud mode. All commands are verified against the actual codebase.


Prerequisites

Requirement Details
Docker 20.10+ (docker info must succeed)
OS Linux or macOS (amd64 or arm64)
Go ❌ Not required — DSO ships as a prebuilt binary
systemd Only required for Cloud Mode (production)
root / sudo Only required for Cloud Mode

Step 1 — Install DSO

The installer always downloads the latest stable release automatically.

User Install (no sudo — for Local Mode / development)

curl -fsSL https://raw.githubusercontent.com/docker-secret-operator/dso/main/scripts/install.sh | bash

Installs to ~/.docker/cli-plugins/docker-dso and ~/.local/bin/dso.

System-Wide Install (sudo — required for Cloud Mode)

curl -fsSL https://raw.githubusercontent.com/docker-secret-operator/dso/main/scripts/install.sh | sudo bash

Installs to /usr/local/lib/docker/cli-plugins/docker-dso, /usr/local/bin/dso, and /usr/local/lib/dso/plugins/ (provider plugins).

Verify

docker dso version

If docker dso is not found after install, run any docker command to reload the plugin cache:

docker ps && docker dso version

For a user install, add ~/.local/bin to your PATH if missing:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc

Step 2 — Choose Your Mode

Local Mode Cloud Mode
Best for Development, testing, single machine Production, cloud secrets, auto-rotation
Root required ❌ No ✅ Yes (systemd service)
Secret source Encrypted local vault (~/.dso/vault.enc) Cloud provider (AWS, Azure, Vault, Huawei)
Auto-rotation ❌ Manual ✅ Automatic (event-driven)
Config file ./dso.yaml (generated by setup) /etc/dso/dso.yaml (generated by setup)
Deploy command docker dso up docker dso up (auto-detected)

Not sure? Start with Local Mode. You can migrate to Cloud Mode at any time.


Local Mode Setup

Local Mode stores secrets in an AES-256 encrypted vault on your machine (~/.dso/vault.enc). No cloud account needed.

Step 2a — Run the Setup Wizard

docker dso setup --mode local

Or just run docker dso setup and choose Local when prompted.

What the wizard does:

  1. Generates ./dso.yaml (local config skeleton)
  2. Tells you the next steps

Expected output (end of wizard):

╔════════════════════════════════════════════════════╗
║                    Setup Complete!                 ║
╚════════════════════════════════════════════════════╝

📚 What's next:
  1. Start the local vault:
     docker dso up

  2. View vault status:
     docker dso status

  3. Configure secrets:
     docker dso secret set <name> <value>

Step 2b — Initialize the Vault

docker dso init

⚠️ Run without sudo. The vault (~/.dso/vault.enc) must be owned by your user account. Root-owned vaults cannot be decrypted as a regular user.

What was created:

Path Purpose
~/.dso/vault.enc AES-256 encrypted secret storage
~/.dso/master.key Vault master key (back this up!)

Step 2c — Store Secrets

# Interactive hidden prompt
docker dso secret set myapp/db_password
# Enter secret for 'myapp/db_password': (invisible input)

# From a pipe
echo "secret-value" | docker dso secret set myapp/api_key

# From a file
cat ./private.key | docker dso secret set myapp/tls_key

# Bulk import from a .env file
docker dso env import ./my-app.env myapp

List your secrets:

docker dso secret list myapp

Step 2d — Reference Secrets in docker-compose.yml

File injection (recommended — secret is mounted as a file, invisible to docker inspect):

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD_FILE: dsofile://myapp/db_password

Environment injection (for legacy containers that only read env vars):

services:
  api:
    image: my-api:latest
    environment:
      STRIPE_KEY: dso://myapp/stripe_key
      DB_PASSWORD: dso://myapp/db_password

Step 2e — Deploy

docker dso up -d

DSO reads your docker-compose.yml, resolves all dso:// and dsofile:// references from the encrypted vault, starts an inline agent, and passes a clean compose file to Docker. Secrets are never written to disk in plaintext.

Complete Local Mode Workflow

# 1. Install
curl -fsSL https://raw.githubusercontent.com/docker-secret-operator/dso/main/scripts/install.sh | bash

# 2. Run setup wizard
docker dso setup --mode local

# 3. Initialize vault (as your regular user, NOT sudo)
docker dso init

# 4. Store secrets
docker dso secret set myapp/db_password
docker dso secret set myapp/api_key

# 5. Add dso:// references to your docker-compose.yml
#    (see Step 2d above)

# 6. Deploy
docker dso up -d

# 7. Check health
docker dso doctor

Cloud Mode Setup

Cloud Mode runs dso-agent as a long-lived systemd service. The agent watches your cloud provider for secret changes and automatically rotates containers when secrets change.

Step 2a — Run the Setup Wizard (Recommended)

docker dso setup

Or with flags to skip interactive prompts:

# Auto-detect your cloud provider (AWS/Azure/Huawei from instance metadata)
docker dso setup --auto-detect

# Specify provider directly
docker dso setup --mode agent --provider aws
docker dso setup --mode agent --provider azure
docker dso setup --mode agent --provider vault
docker dso setup --mode agent --provider huawei

# Add non-root access so your user can run docker dso commands without sudo
docker dso setup --mode agent --provider aws --enable-nonroot

Note: If you run docker dso setup as a non-root user and it detects agent mode is needed, it automatically re-executes itself via sudo.

What the wizard does (agent mode):

  1. Detects or prompts for cloud provider
  2. Generates /etc/dso/dso.yaml (config skeleton with provider section)
  3. Installs provider plugin binary to /usr/local/lib/dso/plugins/
  4. Internally calls docker dso bootstrap agent which:
    • Creates /etc/dso/, /var/lib/dso/, /var/log/dso/, /run/dso/ directories
    • Writes /etc/systemd/system/dso-agent.service
    • Starts the agent service

Expected end of wizard:

╔════════════════════════════════════════════════════╗
║                    Setup Complete!                 ║
╚════════════════════════════════════════════════════╝

📚 What's next:
  1. Edit configuration for your secrets:
     sudo vi /etc/dso/dso.yaml

  2. Check agent status:
     sudo docker dso system status

  3. View agent logs:
     sudo docker dso system logs

Step 2b — Edit /etc/dso/dso.yaml and Add Your Secrets

The wizard generated a config skeleton. Open it and fill in your secrets:

sudo nano /etc/dso/dso.yaml

The file already has your provider section filled in. You need to populate the secrets: section:

AWS Secrets Manager

version: v1.0.0
mode: agent

providers:
  aws:
    type: aws
    region: us-east-1         # Your AWS region
    auth:
      method: iam_role        # Use EC2 instance role (recommended)

secrets:
  - name: database_credentials
    provider: aws
    inject:
      type: env
    targets:
      containers:
        - app                 # Container name(s) that need this secret
    mappings:
      DB_USER: prod/database/username    # container env var: aws secret path
      DB_PASSWORD: prod/database/password
      DB_HOST: prod/database/host

agent:
  watch:
    polling_interval: 5m
  rotation:
    enabled: true
    strategy: rolling         # restart | rolling | signal | none

HashiCorp Vault

version: v1.0.0
mode: agent

providers:
  vault:
    type: vault
    auth:
      method: token
      params:
        address: https://vault.example.com:8200
        token: YOUR_VAULT_TOKEN    # or use VAULT_TOKEN env var

secrets:
  - name: database_credentials
    provider: vault
    inject:
      type: env
    targets:
      containers:
        - app
    mappings:
      DB_USER: secret/data/database/username
      DB_PASSWORD: secret/data/database/password

agent:
  watch:
    polling_interval: 5m
  rotation:
    enabled: true
    strategy: rolling

Azure Key Vault

version: v1.0.0
mode: agent

providers:
  azure:
    type: azure
    region: eastus
    auth:
      method: managed_identity   # Use Azure Managed Identity (recommended)

secrets:
  - name: database_credentials
    provider: azure
    inject:
      type: env
    targets:
      containers:
        - app
    mappings:
      DB_USER: database-username
      DB_PASSWORD: database-password

agent:
  watch:
    polling_interval: 5m
  rotation:
    enabled: true
    strategy: rolling

Step 2c — Check Agent Status

# Service status
sudo docker dso system status

# Live logs
sudo docker dso system logs -f

# Last 50 lines of logs
sudo docker dso system logs -n 50

# Only errors
sudo docker dso system logs -p err

Step 2d — Manage the Service

# Enable + start (also done by setup wizard)
sudo docker dso system enable

# Restart after config changes
sudo docker dso system restart

# Stop and disable
sudo docker dso system disable

Step 2e — Deploy

docker compose up -d

docker dso up also works and auto-detects cloud mode from the presence of /etc/dso/dso.yaml:

docker dso up -d

In cloud mode, secrets are injected from the provider — no dso:// URIs needed in docker-compose.yml. All routing is defined in dso.yaml.

Complete Cloud Mode Workflow

# 1. Install (system-wide, with sudo)
curl -fsSL https://raw.githubusercontent.com/docker-secret-operator/dso/main/scripts/install.sh | sudo bash

# 2. Run setup wizard (auto-detects if on cloud VM, else prompts)
docker dso setup

# 3. Edit /etc/dso/dso.yaml to add your secrets
sudo nano /etc/dso/dso.yaml

# 4. Check agent is running
sudo docker dso system status
sudo docker dso system logs -f

# 5. Check health
docker dso doctor

# 6. Deploy
docker compose up -d

Step 3 — Verify Everything is Working

# Check DSO binary
docker dso version

# Environment health check (all checks should show ✓)
docker dso doctor

# Real-time metrics
docker dso status --watch

# Verify secrets were injected into containers
docker exec <container_name> env | grep DB_PASSWORD

All CLI Commands Reference

Setup & Initialization

Command Purpose Requires root
docker dso setup Interactive wizard (recommended first step) Auto-escalates for agent mode
docker dso setup --mode local Local mode setup (no prompts) No
docker dso setup --mode agent --provider aws Cloud mode setup (no prompts) Yes
docker dso bootstrap local Lower-level: init local dirs + vault skeleton No
docker dso bootstrap agent Lower-level: init systemd service + dirs Yes
docker dso init Initialize local vault only (~/.dso/vault.enc) No (must NOT be root)

Secret Management (Local Mode)

Command Purpose
docker dso secret set myapp/key Store a secret (interactive prompt)
`echo "val" docker dso secret set myapp/key`
docker dso secret get myapp/key Retrieve a secret
docker dso secret list [project] List all secrets in a project
docker dso env import file.env myapp Bulk import from .env file

Deployment

Command Purpose
docker dso up -d Deploy (auto-detects local vs cloud mode)
docker dso up -f custom-compose.yml -d Deploy with specific compose file
docker dso down Stop containers

Health & Monitoring

Command Purpose
docker dso doctor Health check (all checks)
docker dso doctor --level full Full diagnostics including provider
docker dso status Runtime status snapshot
docker dso status --watch Live status (refreshes every 2s)
docker dso status --json JSON output for scripts

Configuration

Command Purpose
docker dso config show Display current config file
docker dso config edit Open config in $EDITOR
docker dso config validate Validate config syntax
docker dso validate Alias: validate config

Service Management (Cloud Mode — requires sudo)

Command Purpose
sudo docker dso system enable Enable + start dso-agent service
sudo docker dso system disable Disable + stop dso-agent service
sudo docker dso system restart Restart dso-agent service
sudo docker dso system status Show service status
docker dso system logs View service logs
docker dso system logs -f Follow logs in real-time
docker dso system logs -n 50 Show last 50 lines
docker dso system logs -p err Show only errors
docker dso system logs --since 1h Logs from last hour

File Locations Reference

Item Local Mode Cloud Mode
Config (setup-generated) ./dso.yaml /etc/dso/dso.yaml
Vault ~/.dso/vault.enc Cloud provider
Master key ~/.dso/master.key N/A
State ~/.dso/state/ /var/lib/dso/state/
Cache ~/.dso/cache/ /var/lib/dso/cache/
Logs Console /var/log/dso/dso-agent.log
Socket N/A /run/dso/dso.sock
Service N/A /etc/systemd/system/dso-agent.service
Plugin (binary) ~/.dso/plugins/ /usr/local/lib/dso/plugins/

Common Troubleshooting

docker dso command not found

# Check plugin installed
ls ~/.docker/cli-plugins/docker-dso          # user install
ls /usr/local/lib/docker/cli-plugins/docker-dso  # system install

# Reload plugins
docker ps

# Check PATH
echo $PATH | grep -o "$HOME/.local/bin"

docker dso init — vault already exists

# The vault is already initialized. Proceed directly to:
docker dso secret set myapp/my_secret

Cloud mode: agent socket missing

# Run setup again to start the agent
docker dso setup

# Or start the service manually
sudo docker dso system enable

# Check if socket exists
ls -la /run/dso/dso.sock

Cloud mode: provider plugin missing

# Check plugin directory
ls -la /usr/local/lib/dso/plugins/

# Re-run installer to get plugins
curl -fsSL https://raw.githubusercontent.com/docker-secret-operator/dso/main/scripts/install.sh | sudo bash

Service fails to start

# View full startup logs
sudo journalctl -u dso-agent -n 100

# Common causes:
# 1. Invalid YAML in /etc/dso/dso.yaml
docker dso config validate

# 2. Provider plugin binary missing from /usr/local/lib/dso/plugins/
ls -la /usr/local/lib/dso/plugins/

# 3. Wrong credentials — check provider auth section in dso.yaml
sudo cat /etc/dso/dso.yaml | grep -A10 providers

Secret not injected into container

# Check container is listed in secrets[].targets.containers
# (leave targets empty to target all running containers)
sudo cat /etc/dso/dso.yaml | grep -A5 targets

# Check agent is watching the secret
sudo docker dso system logs -f | grep -i "rotation|secret|inject"

# Check agent health
docker dso doctor --level full

Next Steps