Odysseus
Zero-downtime Docker deployments over SSH with automatic HTTPS.
Beta: Odysseus is under active development. APIs and configuration may change. Feedback and contributions welcome!
Odysseus deploys containerized applications to your own servers using SSH, Docker, and Caddy. No Kubernetes. No container orchestration platform. Just simple, reliable deployments.
Why Odysseus?
- Zero-downtime deployments - New containers start before old ones stop
- Automatic HTTPS - Caddy handles SSL certificates via Let's Encrypt
- No registry required - Push images directly to servers via SSH with pussh
- Minimal server requirements - Just Docker and SSH access
- Familiar configuration - YAML config inspired by Kamal
How It Works
┌─────────────┐ SSH ┌─────────────────────────────────────┐
│ odysseus │─────────────▶│ Your Server │
│ CLI │ │ ┌───────────┐ ┌──────────────┐ │
└─────────────┘ │ │ Caddy │───▶│ App (new) │ │
│ │ (proxy) │ └──────────────┘ │
│ └───────────┘ ┌──────────────┐ │
│ │ │ App (old) │ │
│ └────────▶│ (draining) │ │
│ └──────────────┘ │
└─────────────────────────────────────┘
- Build your Docker image locally
- Push it to servers via SSH (or registry)
- Start new container, wait for health check
- Update Caddy routing to new container
- Drain connections from old container
- Stop and clean up old containers
Quick Start
Install the CLI:
gem install odysseus-cliCreate deploy.yml:
service: myapp
image: myapp
servers:
web:
hosts:
- app.example.com
proxy:
hosts:
- myapp.example.com
app_port: 3000
ssl: true
ssl_email: admin@example.com
ssh:
user: root
keys:
- ~/.ssh/id_ed25519Deploy:
odysseus deploy --build --image v1.0.0Features
Roles
Deploy different container configurations to different servers:
servers:
web:
hosts:
- web1.example.com
- web2.example.com
options:
memory: 4g
cpus: 2
jobs:
hosts:
- worker.example.com
cmd: bundle exec good_jobAccessories
Manage databases, Redis, and other services:
accessories:
db:
image: postgres:16
hosts:
- db.example.com
volumes:
- /var/lib/odysseus/myapp/postgres:/var/lib/postgresql/dataEncrypted Secrets
Store sensitive environment variables securely:
odysseus secrets generate-key
odysseus secrets encrypt --input secrets.yml --file secrets.yml.encHealth Checks
Configurable health checks ensure containers are ready before receiving traffic:
proxy:
healthcheck:
path: /health
interval: 10
timeout: 5
expect_status: 200AWS Auto Scaling Groups
Dynamically resolve hosts from AWS ASGs:
servers:
web:
aws:
asg: my-web-asg
region: us-east-1Documentation
See odysseus-cli/README.md for complete CLI documentation and configuration reference.
Project Structure
odysseus/
├── odysseus-core/ # Core library (config parsing, deployers, orchestrators)
└── odysseus-cli/ # Command-line interface
Development
cd odysseus-core
bundle install
bundle exec rspecRequirements
Local machine:
- Ruby 3.2+
- Docker (for building images)
Target servers:
- Docker
- SSH access
Caddy is automatically deployed as a container - no manual installation needed.
Roadmap
- Odysseus Pro (coming soon) - Web dashboard, team management, deployment history, and more
License
MIT
OpenSource is great. You can get inspiration from projects, do something different that fits your needs, and turn a page at the same time. — T.R^3