Quick Start Guide#
Get started with podlift in 5 minutes. This guide shows common workflows without reading all documentation.
First Time Setup#
1. Install podlift#
curl -sSL https://raw.githubusercontent.com/ekinertac/podlift/main/install.sh | sh2. Initialize Your Project#
cd myapp/
podlift initCreates podlift.yml and .env.example.
3. Configure Server#
Edit podlift.yml:
service:
name: myapp
image: myapp
port: 8000
servers:
- host: 192.168.1.10 # Your server IP
user: root # SSH user4. Setup Server#
First time only - installs Docker, configures firewall:
podlift setup5. Deploy#
podlift deployDone! Your app is live at http://192.168.1.10
Common Workflows#
Daily Development#
# 1. Make changes
vim app/main.py
# 2. Test locally
docker-compose up
# 3. Commit
git add -A
git commit -m "Add feature"
# 4. Deploy
podlift deployMultiple Environments#
Project structure:
myapp/
├── docker-compose.yml # Local: docker-compose up
├── podlift.yml # Staging deployment
├── podlift.production.yml # Production deployment
├── .env
└── .env.productionDeploy to staging:
podlift deployDeploy to production:
podlift deploy --config podlift.production.ymlAdd SSL/HTTPS#
# podlift.yml
service:
name: myapp
domain: myapp.com # Add domain
servers:
- host: 1.2.3.4
ssl:
enabled: true
email: admin@myapp.compodlift ssl setupYour site is now at https://myapp.com
Add Database#
# podlift.yml
dependencies:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
services:
web:
env:
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@primary:5432/myapp# .env
DB_PASSWORD=your-secure-password
podlift deployDatabase is automatically deployed and connected.
Multiple Servers (Load Balancing)#
# podlift.yml
servers:
- host: 1.2.3.4
labels: [primary]
- host: 5.6.7.8podlift deployAutomatically sets up nginx load balancer across both servers.
Registry Instead of SCP#
# podlift.yml
registry:
server: ghcr.io
username: ${REGISTRY_USER}
password: ${REGISTRY_PASSWORD}# .env
REGISTRY_USER=myuser
REGISTRY_PASSWORD=ghp_xxxxx
podlift deployPushes to registry instead of uploading via SCP.
Rollback Deployment#
podlift rollbackInstantly reverts to previous version.
Common Patterns#
Pattern 1: Simple Web App#
Use case: Single server, no database, basic deployment
service:
name: myapp
image: myapp
port: 8000
servers:
- host: 1.2.3.4
user: deployDeploy:
podlift deployPattern 2: Web App + Database#
Use case: App with PostgreSQL, single server
service:
name: myapp
image: myapp
port: 8000
servers:
- host: 1.2.3.4
user: deploy
dependencies:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
services:
web:
env:
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@primary:5432/myappPattern 3: Production with SSL + Load Balancing#
Use case: Multiple servers, SSL, high availability
service:
name: myapp
domain: myapp.com
image: myapp
port: 8000
servers:
- host: 1.2.3.4
user: deploy
labels: [primary]
- host: 5.6.7.8
user: deploy
dependencies:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
services:
web:
replicas: 2
env:
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@primary:5432/myapp
REDIS_URL: redis://primary:6379
ssl:
enabled: true
email: admin@myapp.com
hooks:
after_deploy:
- docker exec myapp-web-1 python manage.py migratePattern 4: Worker Servers#
Use case: Web servers separate from background workers
service:
name: myapp
image: myapp
servers:
web:
- host: 1.2.3.4
- host: 5.6.7.8
worker:
- host: 9.10.11.12
- host: 13.14.15.16
services:
web:
port: 8000
worker:
command: celery -A myapp worker
replicas: 2Environment-Specific Configs#
Staging vs Production#
podlift.yml (staging):
service:
name: myapp-staging
domain: staging.myapp.com
image: myapp
env_file: .env.staging
servers:
- host: staging.myapp.com
services:
web:
replicas: 1
env:
DEBUG: "true"
ssl:
enabled: truepodlift.production.yml:
service:
name: myapp
domain: myapp.com
image: myapp
env_file: .env.production
servers:
- host: prod1.myapp.com
labels: [primary]
- host: prod2.myapp.com
dependencies:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
services:
web:
replicas: 3
env:
DEBUG: "false"
ssl:
enabled: trueDeploy:
podlift deploy # Staging
podlift deploy --config podlift.production.yml # ProductionSecrets Management#
Local .env Files#
# .env (for staging)
DB_PASSWORD=staging_password
SECRET_KEY=staging_secret
# .env.production (for production)
DB_PASSWORD=production_password
SECRET_KEY=production_secret
REGISTRY_PASSWORD=ghp_xxxxxIn podlift.yml:
env_file: .env.production # Point to specific env file
services:
web:
env:
SECRET_KEY: ${SECRET_KEY}
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@primary:5432/myappCI/CD Secrets#
GitHub Actions:
- name: Deploy
env:
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
SECRET_KEY: ${{ secrets.SECRET_KEY }}
run: podlift deploy --config podlift.production.ymlGitLab CI:
deploy:
script:
- export DB_PASSWORD=$DB_PASSWORD
- export SECRET_KEY=$SECRET_KEY
- podlift deploy --config podlift.production.ymlMonitoring & Maintenance#
Check Status#
podlift ps # Running services
podlift status # Detailed statusView Logs#
podlift logs web # Last 100 lines
podlift logs web --follow # Stream logs
podlift logs web --tail 500 # Last 500 linesExecute Commands#
podlift exec web bash # Interactive shell
podlift exec web python manage.py migrate # Run migrationHealth Checks#
podlift validate # Validate config and serversMakefile Shortcuts#
Add to Makefile:
deploy-staging:
podlift deploy
deploy-production:
podlift deploy --config podlift.production.yml
rollback-staging:
podlift rollback
rollback-production:
podlift rollback --config podlift.production.yml
logs:
podlift logs web --follow
status:
podlift status
shell:
podlift exec web bash
Usage:
make deploy-staging
make deploy-production
make logsTroubleshooting#
Deployment Failed#
# Check logs
podlift logs web
# Validate config
podlift validate
# Rollback
podlift rollbackHealth Check Failing#
# Adjust health check in podlift.yml
services:
web:
health_check:
path: /health
expect: [200, 301]
timeout: 60s # Increase timeoutPort Already in Use#
# Check what's running
podlift ps --all
# Clean up old containers if needed
ssh root@server 'docker ps -a'