DockLift
Deploy web applications to VPS using Docker Compose with automatic SSL via Caddy.
Features
- Simple Configuration: Lightweight YAML configuration for all deployment settings
- Automatic SSL: Automatic HTTPS certificates via Caddy's ACME integration
- Multi-App Support: Deploy multiple applications to the same VPS, each with its own domain
- Auto Port Assignment: Automatically assigns ports to applications (starts at 3000, increments)
- Idempotent Operations: All commands can be run multiple times safely
- Dependency Management: Built-in support for databases, caches, and other services
- Type-Safe: Full type hints throughout the codebase
- Beautiful CLI: Rich terminal output with progress indicators
Installation
Using UV (recommended):
uv tool install docklift
Using pip:
pip install docklift
Quick Start
1. Initialize Configuration
Run the interactive setup:
docklift init
Or provide values as arguments to skip prompts:
docklift init myapp --domain myapp.example.com --host 192.168.1.100
This creates a docklift.yml file. The wizard will prompt for:
- Application name and domain
- VPS host and SSH credentials
- Application port
- Email for SSL certificate notifications (optional)
2. Bootstrap VPS
First time setup - installs Docker, Caddy, and creates shared infrastructure:
docklift bootstrap
This step is idempotent. It will:
- Install Docker and Docker Compose (if not present)
- Create a shared network for all applications
- Set up Caddy reverse proxy with automatic HTTPS
3. Deploy Application
docklift deploy
This will:
- Upload your application code
- Generate docker-compose.yml
- Build the Docker image on the VPS
- Start the application
- Configure Caddy to route traffic
- Test the deployment
Configuration
Create a docklift.yml file:
vps:
host: 192.168.1.100
user: root
ssh_key_path: ~/.ssh/id_rsa
port: 22
email: admin@example.com # Optional: for Let's Encrypt SSL notifications
application:
name: myapp
domain: myapp.example.com
dockerfile: ./Dockerfile
context: .
# port: 3000 # Optional: auto-assigned if not specified
environment:
NODE_ENV: production
DATABASE_URL: postgres://postgres:password@postgres:5432/myapp
REDIS_URL: redis://redis:6379
dependencies:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD: changeme
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
Commands
Initialize
Create a new configuration file interactively:
docklift init
Or provide arguments to skip prompts:
docklift init myapp --domain app.example.com --host 192.168.1.100 --user deploy
Bootstrap
Set up VPS infrastructure (run once per VPS):
docklift bootstrap [--config docklift.yml]
Deploy
Deploy or update an application:
docklift deploy [--config docklift.yml] [--skip-bootstrap]
Status
Check application status:
docklift status [--config docklift.yml]
Remove
Remove an application:
docklift remove [--config docklift.yml] [--remove-volumes]
Environment Variables and Secrets
DockLift supports loading environment variables from .env files to keep secrets out of version control.
Using .env Files
- Create a
.envfile in your project:
# .env
DATABASE_PASSWORD=super-secret-password
API_KEY=sk-1234567890
STRIPE_SECRET=sk_test_abc123
- Reference it in
docklift.yml:
application:
environment:
NODE_ENV: production
DATABASE_URL: postgres://user:${DATABASE_PASSWORD}@postgres:5432/db
env_file: .env # Load additional variables from .env
- Add
.envto.gitignore:
echo ".env" >> .gitignore
Precedence Rules
- Variables defined in
docklift.ymltake precedence over.envfile - This allows you to override secrets for specific environments
- Use YAML for non-sensitive config,
.envfor secrets
Example
With this setup:
# docklift.yml
environment:
NODE_ENV: production
API_KEY: override-key
env_file: .env
# .env
API_KEY=secret-from-env
DATABASE_URL=postgres://localhost/db
The result will be:
NODE_ENV=production(from YAML)API_KEY=override-key(YAML overrides .env)DATABASE_URL=postgres://localhost/db(from .env)
How It Works
Architecture
DockLift creates the following structure on your VPS:
/opt/docklift/
├── caddy-compose.yml # Caddy reverse proxy
├── Caddyfile # Caddy configuration
└── apps/
├── app1/
│ ├── docker-compose.yml
│ └── [app files]
└── app2/
├── docker-compose.yml
└── [app files]
Network Architecture
- All applications and Caddy share a Docker network called
docklift-network - Caddy listens on ports 80 and 443
- Applications expose their internal ports only to the shared network
- Caddy routes traffic based on domain name to the appropriate application
SSL Certificates
- Caddy automatically obtains SSL certificates via Let's Encrypt
- Certificates are automatically renewed
- HTTP traffic is automatically redirected to HTTPS
Port Management
- Applications can specify a port or leave it blank for auto-assignment
- Auto-assigned ports start at 3000 and increment for each new application
- Ports are only exposed internally to the Docker network (no host port conflicts)
- When redeploying an existing app, the same port is reused
Example: Django Application
vps:
host: myserver.example.com
user: deploy
ssh_key_path: ~/.ssh/deploy_key
port: 22
email: admin@myserver.example.com
application:
name: django-app
domain: app.example.com
dockerfile: ./Dockerfile
context: .
port: 8000
environment:
DJANGO_SETTINGS_MODULE: myapp.settings.production
DATABASE_URL: postgres://django:secure_pass@postgres:5432/django_db
REDIS_URL: redis://redis:6379/0
SECRET_KEY: your-secret-key-here
dependencies:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: django_db
POSTGRES_USER: django
POSTGRES_PASSWORD: secure_pass
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
Example: Node.js Application
vps:
host: myserver.example.com
user: deploy
ssh_key_path: ~/.ssh/deploy_key
port: 22
email: admin@myserver.example.com
application:
name: nodejs-app
domain: app.example.com
dockerfile: ./Dockerfile
context: .
port: 3000
environment:
NODE_ENV: production
MONGODB_URL: mongodb://mongo:27017/myapp
dependencies:
mongo:
image: mongo:7
volumes:
- mongo_data:/data/db
Requirements
- Python 3.12+
- SSH access to a VPS running a modern Linux distribution
- Docker-compatible VPS (Ubuntu 20.04+, Debian 11+, etc.)
- Domain name(s) pointed to your VPS
Development
Built with:
- Python 3.12+ with type hints
- UV for package management
- Fabric for SSH operations
- Rich for beautiful CLI output
- Pydantic for configuration validation
- Click for CLI framework
Setup Development Environment
# Clone the repository
git clone https://github.com/amirkarimi/docklift.git
cd docklift
# Install dependencies
uv sync
# Run in development mode
uv run docklift --help
License
MIT
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Metadata
Release files for docklift 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| docklift-0.1.3.tar.gz | 61.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| docklift-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 76.9 kB
Release files / docklift-0.1.3.tar.gz
| Download URL | docklift-0.1.3.tar.gz |
|---|---|
| Size | 61.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de1eb5d092855cf77356dd6b5370ac814a152f041244327823a674cde3811b48
|
|
BLAKE2b-256 checksum How to use checksums |
1989f91e99bbe57d0470365f147362cd9a2afc8f8de1d02aa30802c5154681e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 23, 2026.
Transparency logRelease files / docklift-0.1.3-py3-none-any.whl
| Download URL | docklift-0.1.3-py3-none-any.whl |
|---|---|
| Size | 15.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2ea421f2cb1cca37ec3164c33623f500c9ca31aa8c558be1b44bb9be5db37b8
|
|
BLAKE2b-256 checksum How to use checksums |
bbf788f1a205edb326776445e6edebfa152ee92d16b57945dd4ff9766084e4c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 23, 2026.
Transparency log