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 Setup
docker dso setup --mode local
The setup engine runs through five stages automatically:
| Stage | What it does |
|---|---|
| Detect | Discovers Docker version, OS capabilities, and your home directory |
| Validate | Confirms Docker is reachable and local mode is supported |
| Plan | Declares the config file and directory to create |
| Preview | Prints the plan for review before writing anything |
| Apply | Creates ~/.dso/dso.yaml transactionally; rolls back on failure |
Expected output (end of setup):
╔════════════════════════════════════════════════════╗
║ Setup Complete! ║
╚════════════════════════════════════════════════════╝
📚 What's next:
1. Initialize the local vault:
docker dso init
2. Store secrets:
docker dso secret set <name>
3. Deploy your services:
docker dso up -d
4. Check status:
docker dso status
Tip: Run
docker dso setup --dry-runto preview the plan without writing any files.
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 (preview first if you like)
docker dso setup --mode local --dry-run # see what will happen
docker dso setup --mode local # apply it
# 3. Run doctor to confirm setup is healthy
docker dso doctor
# 4. Initialize vault (as your regular user, NOT sudo)
docker dso init
# 5. Store secrets
docker dso secret set myapp/db_password
docker dso secret set myapp/api_key
# 6. Add dso:// references to your docker-compose.yml
# (see Step 2d above)
# 7. Deploy
docker dso up -d
# 8. Check status
docker dso status
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 Setup (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
# Preview the plan without writing anything
docker dso setup --mode agent --provider aws --dry-run
Note: If you run
docker dso setupas a non-root user and it detects agent mode is needed, it automatically re-executes itself viasudo.
What the setup engine does (agent mode):
| Stage | What it does |
|---|---|
| Detect | Reads cloud provider metadata, checks systemd, confirms Docker and root privileges |
| Validate | Confirms agent mode prerequisites are met |
| Plan | Declares config file, directories, systemd unit, service enable/start operations |
| Preview | Prints full plan for review |
| Apply | Creates all declared resources transactionally; rolls back automatically on any failure |
After apply, the engine enables and starts dso-agent.service via systemd.
Expected end of setup:
╔════════════════════════════════════════════════════╗
║ 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. Preview the setup plan before committing
docker dso setup --dry-run
# 3. Run setup (auto-detects provider if on cloud VM, else prompts)
docker dso setup
# 4. Validate the installation
docker dso doctor
# 5. Edit /etc/dso/dso.yaml to add your secrets
sudo nano /etc/dso/dso.yaml
# 6. Restart the agent after config changes
sudo docker dso system restart
# 7. Check agent is running
sudo docker dso system status
sudo docker dso system logs -f
# 8. 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
Something looks wrong after setup
# Run a full diagnostic — shows every check with pass/warn/fail status
docker dso doctor --level full
# The doctor describes the root cause and recovery steps for each failure.
# Safe repairs (permissions, missing runtime dirs) are applied automatically.
# Moderate repairs (service enable/start, config recreation) require confirmation.
Cloud mode: agent socket missing
# Let doctor diagnose and repair the service automatically
docker dso doctor
# 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
- CLI Reference — every command and flag documented
- Configuration Reference — full
dso.yamlschema - Providers Guide — AWS, Azure, Vault, Huawei auth details
- Operational Guide — Day-2 operations, monitoring, backup
- Quick Reference — one-page cheat sheet