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/DockerfileGokku will use your existing Dockerfile.
Auto-Generated Dockerfile
apps:
my-app:
lang: python
path: ./app
entrypoint: main.pyGokku generates a Dockerfile automatically based on language.
Language-Specific Examples
Python
apps:
python-app:
lang: python
path: .
entrypoint: app.py
image: python:3.11-slimGenerated 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-alpineGenerated 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/apiCustom 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: ./workerOption 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-productionAccess 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 filesShared 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:15Health 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-3For 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.11Login 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