Docker Security Best Practices
Tiaki supports multiple security enhancements to protect your Docker infrastructure when running the Docker agent.
Docker Socket Proxy
By default, the Tiaki agent requires direct access to the Docker socket (/var/run/docker.sock). While mounted as read-only, this still grants significant privileges.
For enhanced security, use a socket proxy to limit the agent's Docker API access to only the required endpoints.
Setup
- Uncomment the
socket-proxyservice indocker-compose.yml:
socket-proxy:
image: tecnativa/docker-socket-proxy:latest
restart: unless-stopped
profiles:
- agent
- socket-proxy
privileged: true
environment:
- CONTAINERS=1
- IMAGES=1
- INFO=1
- NETWORKS=1
- VOLUMES=1
- POST=1 # Required for pulling images
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- tiaki-internal
- Update the agent configuration:
agent:
volumes:
# Comment out direct socket access
# - /var/run/docker.sock:/var/run/docker.sock:ro
environment:
DOCKER_HOST: tcp://socket-proxy:2375
depends_on:
- socket-proxy
- Start with both profiles:
docker compose --profile agent --profile socket-proxy up -d
Benefits
- Principle of least privilege: Agent only gets access to required Docker API endpoints
- Attack surface reduction: Limits potential damage if agent is compromised
- Audit trail: Socket proxy can log all Docker API requests
Limitations
The socket proxy itself runs with privileged: true and has full Docker socket access. Ensure it runs in a trusted environment.
Docker Secrets for Registry Credentials
Instead of storing registry credentials in environment variables or .env files, use Docker secrets for enhanced security.
❌ Insecure Method (Environment Variables)
agent:
environment:
REGISTRY_USERNAME: myuser
REGISTRY_PASSWORD: mypassword # Visible in docker inspect!
✅ Secure Method (Docker Secrets)
- Create the secrets directory and auth file:
mkdir -p secrets
cp secrets/registry_auth.json.example secrets/registry_auth.json
- Edit
secrets/registry_auth.jsonwith your credentials:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "dXNlcm5hbWU6cGFzc3dvcmQ="
},
"ghcr.io": {
"username": "github-username",
"password": "ghp_your_token"
}
}
}
For the auth field, use base64-encoded username:password:
echo -n "username:password" | base64
- Set file permissions:
chmod 600 secrets/registry_auth.json
- Uncomment the secrets section in
docker-compose.yml:
secrets:
registry_auth:
file: ./secrets/registry_auth.json
agent:
secrets:
- registry_auth
environment:
REGISTRY_AUTH_FILE: /run/secrets/registry_auth
- Restart the agent:
docker compose --profile agent up -d agent
Benefits
- Not visible in environment: Credentials don't appear in
docker inspector process lists - File-based security: Secrets are mounted as read-only files in
/run/secrets/ - Better for production: Industry standard for credential management
- Git-safe: Secrets directory is excluded from version control
Multiple Registries
You can configure multiple registries in a single registry_auth.json:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "base64-encoded-dockerhub-creds"
},
"ghcr.io": {
"username": "github-user",
"password": "ghp_token"
},
"registry.example.com": {
"username": "user",
"password": "pass"
}
}
}
Combined Setup (Maximum Security)
For production deployments, combine both features:
services:
socket-proxy:
image: tecnativa/docker-socket-proxy:latest
restart: unless-stopped
profiles: [agent, socket-proxy]
privileged: true
environment:
- CONTAINERS=1
- IMAGES=1
- INFO=1
- NETWORKS=1
- VOLUMES=1
- POST=1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- tiaki-internal
agent:
image: tiakidev/tiaki-agent-docker:latest
restart: unless-stopped
profiles: [agent]
environment:
CONTROL_URL: http://server:3001
AGENT_API_KEY: ${AGENT_API_KEY}
DOCKER_HOST: tcp://socket-proxy:2375
REGISTRY_AUTH_FILE: /run/secrets/registry_auth
TRIVY_ENABLED: ${TRIVY_ENABLED:-true}
secrets:
- registry_auth
networks:
- tiaki-internal
depends_on:
- server
- socket-proxy
secrets:
registry_auth:
file: ./secrets/registry_auth.json
Start with:
docker compose --profile agent --profile socket-proxy up -d
Additional Security Recommendations
- Network isolation: Use Docker networks to isolate services (already configured)
- Read-only mounts: All socket mounts use
:roflag - Minimal permissions: Socket proxy limits API access to required endpoints
- Credential rotation: Regularly rotate registry credentials and API keys
- Audit logging: Enable and monitor logs for suspicious activity
- Updates: Keep Tiaki and all images up to date
- Secrets management: Never commit secrets to version control
Kubernetes Alternative
For Kubernetes deployments, use native Kubernetes secrets instead:
apiVersion: v1
kind: Secret
metadata:
name: registry-credentials
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-auth-json>
See Kubernetes Agent Configuration for details.