DockUp has root-level access to Docker. Here's how to lock it down.
What DockUp can do:
- Start/stop/delete any container
- Read all container logs
- Modify compose files
- Access Docker socket (root access)
- Create/delete networks and volumes
What attackers could do:
- Deploy malicious containers
- Exfiltrate data
- Modify services
- Install backdoors
- Delete everything
Bottom line: Treat DockUp like SSH root access.
Requirements:
- 12+ characters
- Mix of case, numbers, symbols
- Not a dictionary word
- Not reused
Generate password:
openssl rand -base64 24Change password:
curl -X POST http://localhost:5000/api/auth/change-password \
-d '{
"current": "old_password",
"new_password": "new_password",
"confirm": "new_password"
}'Never disable unless:
- Completely isolated network
- Behind another auth layer
- Testing only
Regenerate monthly:
curl -X POST http://localhost:5000/api/config/regenerate-tokenBad:
ports:
- "5000:5000" # Accessible from anywhereBetter:
ports:
- "127.0.0.1:5000:5000" # Localhost onlyUFW:
# Allow from specific subnet
sudo ufw allow from 192.168.1.0/24 to any port 5000
# Deny all else
sudo ufw deny 5000firewalld:
sudo firewall-cmd --permanent --new-zone=management
sudo firewall-cmd --permanent --zone=management --add-source=192.168.1.0/24
sudo firewall-cmd --permanent --zone=management --add-port=5000/tcp
sudo firewall-cmd --reloadiptables:
sudo iptables -A INPUT -p tcp --dport 5000 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5000 -j DROP
sudo iptables-save > /etc/iptables/rules.v4Best practice: Only accessible via VPN.
Wireguard:
wg-quick up wg0
# Firewall
sudo ufw allow from 10.0.0.0/24 to any port 5000
sudo ufw deny 5000Tailscale:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
sudo ufw allow from 100.0.0.0/8 to any port 5000
sudo ufw deny 5000server {
listen 443 ssl http2;
server_name dockup.example.com;
ssl_certificate /etc/letsencrypt/live/dockup.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dockup.example.com/privkey.pem;
auth_basic "DockUp Access";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Create htpasswd:
sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd admindockup.example.com {
basicauth {
admin $2a$14$hashed_password
}
reverse_proxy localhost:5000
}
Generate hash:
caddy hash-passwordsudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx -d dockup.example.com
sudo systemctl enable certbot.timerdockup.example.com {
reverse_proxy localhost:5000
}
Caddy handles HTTPS automatically.
labels:
- "traefik.enable=true"
- "traefik.http.routers.dockup.rule=Host(`dockup.example.com`)"
- "traefik.http.routers.dockup.entrypoints=websecure"
- "traefik.http.routers.dockup.tls.certresolver=letsencrypt"Nginx:
location / {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://localhost:5000;
}Caddy:
dockup.example.com {
@allowed {
remote_ip 192.168.1.0/24 10.0.0.0/8
}
handle @allowed {
reverse_proxy localhost:5000
}
respond 403
}
services:
dockup:
deploy:
resources:
limits:
cpus: '1.0'
memory: 512MScan DockUp image:
trivy image your-registry/dockup:latestRegular scans:
# Cron: 0 2 * * 0
docker pull your-registry/dockup:latest
trivy image your-registry/dockup:latest# Failed logins
docker logs dockup | grep "Invalid password"
# API calls
docker logs dockup | grep "POST"
# Stack operations
docker logs dockup | grep "operation"services:
dockup:
logging:
driver: syslog
options:
syslog-address: "tcp://logserver:514"
tag: "dockup"# Watch for failed logins
docker logs -f dockup | grep --line-buffered "Invalid password" | while read line; do
curl https://gotify.example.com/message?token=TOKEN \
-F "title=DockUp Alert" \
-F "message=$line"
done# Create backup
curl -X POST http://localhost:5000/api/backup/create
# Encrypt
gpg --encrypt --recipient you@example.com backup.tar.gz
rm backup.tar.gz#!/bin/bash
BACKUP=$(curl -s -X POST http://localhost:5000/api/backup/create | jq -r '.backup_file')
gpg --encrypt --recipient you@example.com "$BACKUP"
rm "$BACKUP"Basic:
- Strong password (12+ characters)
- Password protection enabled
- HTTPS with valid certificate
- Firewall rules restricting access
- Regular backups
Intermediate:
- Reverse proxy with authentication
- VPN-only access
- IP whitelisting
- API token rotation
- Resource limits
- Monitoring and alerting
Advanced:
- Client certificate auth
- Geographic restrictions
- Centralized logging
- Encrypted backups
- Disaster recovery tested
If compromised:
-
Immediately:
docker stop dockup
-
Check logs:
docker logs dockup > dockup-logs.txt grep "Invalid password" dockup-logs.txt grep "POST" dockup-logs.txt
-
Check changes:
diff -r /stacks/ /backup/stacks/ docker ps -a docker images
-
Rotate credentials:
- Change password
- Regenerate API token
- Update peer tokens
-
Restore from backup:
curl -X POST http://localhost:5000/api/backup/restore \ -d '{"backup_file": "backup_before_incident.tar.gz"}' -
Investigate:
- Check firewall logs
- Review access logs
- Scan containers
Daily:
- Monitor logs for anomalies
- Check failed login attempts
Weekly:
- Review stack changes
- Check resource usage
Monthly:
- Rotate API tokens
- Review firewall rules
- Test backups
Quarterly:
- Review access controls
- Security scan DockUp image
- Test disaster recovery
Annually:
- Change password
- Full security audit
DockUp is for trusted internal use.
Not multi-tenant. Not internet-facing. Assumes legitimate Docker access.
For internet-facing: Use VPN + strong auth + monitoring.
Best practice: Don't expose publicly at all.