Docker Application Example
Deploy any application using Docker with Gokku.
Basic Docker Deployment
With Custom Dockerfile
apps:
my-app:
lang: python
path: ./app
dockerfile: ./app/Dockerfile
Gokku will use your existing Dockerfile.
Auto-Generated Dockerfile
apps:
my-app:
lang: python
path: ./app
entrypoint: main.py
Gokku generates a Dockerfile automatically based on language.
Language-Specific Examples
Python
apps:
python-app:
lang: python
path: .
entrypoint: app.py
image: python:3.11-slim
Generated Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE ${PORT:-8080}
CMD ["python", "app.py"]
Node.js
apps:
nodejs-app:
lang: nodejs
path: .
entrypoint: index.js
image: node:20-alpine
Generated Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json .
RUN npm ci --only=production
COPY . .
EXPOSE ${PORT:-8080}
CMD ["node", "index.js"]
Go (Docker Build)
apps:
go-app:
image: golang:1.25-alpine
path: ./cmd/api
Custom Dockerfile Examples
Multi-Stage Build (Go)
# Build stage
FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY go.* .
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o app ./cmd/api
# Runtime stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/app .
EXPOSE ${PORT:-8080}
CMD ["./app"]
Multi-Stage Build (Node.js)
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
RUN npm run build
# Runtime stage
FROM node:20-alpine
WORKDIR /app
COPY package*.json .
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE ${PORT:-8080}
CMD ["node", "dist/index.js"]
With System Dependencies
FROM python:3.11-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
gcc \
ffmpeg \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE ${PORT:-8080}
CMD ["python", "app.py"]
With Docker Compose (Not Supported Yet)
Gokku currently uses docker run
, not docker-compose
. For services requiring multiple containers:
Option 1: Deploy Separately
apps:
web:
lang: python
path: ./web
worker:
lang: python
path: ./worker
Option 2: Single Container with Multiple Processes
Use a process manager like supervisord
:
FROM python:3.11-slim
RUN apt-get update && apt-get install -y supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["/usr/bin/supervisord"]
Environment Variables
Set via gokku config:
gokku config set DATABASE_URL=postgres://... -a my-app-production
Access in container:
import os
db_url = os.getenv('DATABASE_URL')
External port is managed by Gokku (incremental: 8080, 8081, 8082...).
Volumes (Persistent Data)
Gokku supports Docker volumes through the volumes
field in your gokku.yml
:
Basic Volume Configuration
apps:
my-app:
path: ./cmd/my-app
volumes:
- "/host/path:/container/path" # Bind mount
- "/usr/lib/data:/app/data" # Shared data folder
- "/var/log/app:/app/logs" # Log files
Shared Volumes Between Apps
Perfect for microservices that need to share data:
apps:
recorder:
path: ./cmd/recorder
volumes:
- "/usr/lib/recordings:/app/recordings" # Write files here
- "/var/log/recordings:/app/logs"
processor:
path: ./cmd/processor
volumes:
- "/usr/lib/recordings:/app/recordings" # Read files from here
- "/var/log/recordings:/app/logs"
webhook:
path: ./cmd/webhook
volumes:
- "/usr/lib/recordings:/app/recordings" # Access processed files
- "/var/log/recordings:/app/logs"
Volume Types Supported
- Bind Mounts:
/host/path:/container/path
- Named Volumes:
volume_name:/container/path
- Read-only Mounts:
/host/path:/container/path:ro
External Storage Options
For cloud-native apps, consider:
- S3: For file storage
- PostgreSQL: For structured data
- Redis: For caching
Database Container Example
Run database outside Gokku:
# On server
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=secret \
-v /data/postgres:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:15
Health Checks
Add health check to your Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY . .
EXPOSE ${PORT:-8080}
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:${PORT:-8080}/health || exit 1
CMD ["python", "app.py"]
Image Tagging
Gokku automatically tags images with release number:
my-app:release-1
my-app:release-2
my-app:release-3
For rollback:
ssh ubuntu@server "cd /opt/gokku && ./rollback.sh my-app production 2"
This switches back to my-app:release-2
.
Registry Support (Private Images)
docker:
registry: "registry.example.com"
apps:
my-app:
image: registry.example.com/python:3.11
Login on server first:
ssh ubuntu@server "docker login registry.example.com"
Debugging
View Container Logs
ssh ubuntu@server "docker logs -f my-app-production"
Inspect Container
ssh ubuntu@server "docker inspect my-app-production"
Access Container Shell
ssh ubuntu@server "docker exec -it my-app-production /bin/sh"
View Build Logs
ssh ubuntu@server "cat /opt/gokku/apps/my-app/production/deploy.log"
Docker Benefits
Docker provides several advantages for application deployment:
- Isolation: Each app runs in its own container
- Consistency: Same environment in dev and production
- Dependencies: All dependencies bundled in the image
- Portability: Easy to move between servers
- Zero-Downtime: Built-in blue-green deployment support
Complete Examples
Full working examples:
Next Steps
- Configuration - Customize Docker settings
- Environment Variables - Manage secrets