Docker Integration¶
This guide demonstrates how to integrate Go Overlay into Docker containers to manage multiple services within a single container. While the microservices pattern typically uses one service per container, there are valid use cases for running multiple processes in a container, and Go Overlay makes this simple and reliable.
Use Cases¶
Running multiple services in a single container is appropriate when:
- Legacy application migration: Transitioning monolithic applications to containers
- Tightly coupled services: Services that must run together (e.g., app + sidecar)
- Development environments: Simplified local development with multiple services
- Resource constraints: Reducing overhead in resource-limited environments
- Batch processing: Running multiple workers with a coordinator
Basic Docker Integration¶
Alpine-based Image¶
Alpine Linux provides a minimal base image, perfect for production containers.
FROM alpine:3.22
# Install runtime dependencies
RUN apk add --no-cache \
ca-certificates \
tzdata \
bash
# Install Go Overlay
ADD https://github.com/srelabz/go-overlay/releases/latest/download/go-overlay /go-overlay
# Make it executable
RUN chmod +x /go-overlay
# Create application directory
WORKDIR /app
# Copy your application binaries
COPY ./bin/server /app/server
COPY ./bin/worker /app/worker
# Copy Go Overlay configuration
COPY services.toml /services.toml
# Create non-root user
RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser && \
chown -R appuser:appuser /app
# Expose application port
EXPOSE 8080
# Use Go Overlay as entrypoint
ENTRYPOINT ["/go-overlay"]
Key Points:
- Uses Alpine 3.22 for minimal image size
- Downloads Go Overlay directly from GitHub releases
- Creates non-root user for security
- Sets Go Overlay as the container entrypoint
- Configuration file is copied into the image
Ubuntu-based Image¶
Ubuntu provides more packages and compatibility, useful for complex applications.
FROM ubuntu:22.04
# Prevent interactive prompts during build
ENV DEBIAN_FRONTEND=noninteractive
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
wget \
curl \
&& rm -rf /var/lib/apt/lists/*
# Install Go Overlay
RUN wget -O /go-overlay \
https://github.com/srelabz/go-entrypoint/releases/latest/download/go-overlay-linux-amd64 && \
chmod +x /go-overlay
# Install application dependencies (example: Node.js app)
RUN apt-get update && apt-get install -y \
nodejs \
npm \
nginx \
redis-server \
&& rm -rf /var/lib/apt/lists/*
# Create application directory
WORKDIR /app
# Copy application files
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# Copy Go Overlay configuration
COPY services.toml /services.toml
# Copy nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf
# Create non-root user
RUN useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app
# Expose ports
EXPOSE 80 8080
# Use Go Overlay as entrypoint
ENTRYPOINT ["/go-overlay"]
CMD ["daemon", "--config", "/services.toml"]
Key Points:
- Uses Ubuntu 22.04 for broader package availability
- Installs multiple services (Node.js, Nginx, Redis)
- Cleans up apt cache to reduce image size
- Suitable for applications with complex dependencies
Multi-Service Configuration Examples¶
Example 1: Web App + Nginx + Redis¶
This example runs a web application with Nginx as a reverse proxy and Redis for caching.
services.toml:
[timeouts]
service_shutdown_timeout = 10
global_shutdown_timeout = 30
# Redis cache
[[services]]
name = "redis"
command = "/usr/bin/redis-server"
args = ["--bind", "127.0.0.1", "--port", "6379"]
enabled = true
required = true
# Node.js application
[[services]]
name = "app"
command = "/usr/bin/node"
args = ["/app/server.js"]
enabled = true
required = true
depends_on = ["redis"]
wait_after = { redis = 2 }
user = "appuser"
# Nginx reverse proxy
[[services]]
name = "nginx"
command = "/usr/sbin/nginx"
args = ["-g", "daemon off;"]
enabled = true
required = true
depends_on = ["app"]
wait_after = { app = 3 }
Complete Dockerfile:
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
# Install all dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
wget \
nodejs \
npm \
nginx \
redis-server \
&& rm -rf /var/lib/apt/lists/*
# Install Go Overlay
RUN wget -O /go-overlay \
https://github.com/srelabz/go-entrypoint/releases/latest/download/go-overlay-linux-amd64 && \
chmod +x /go-overlay
WORKDIR /app
# Install Node.js dependencies
COPY package*.json ./
RUN npm ci --only=production
# Copy application code
COPY . .
# Copy configurations
COPY services.toml /services.toml
COPY nginx.conf /etc/nginx/nginx.conf
# Create user and set permissions
RUN useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app && \
mkdir -p /var/log/nginx /var/lib/nginx && \
chown -R appuser:appuser /var/log/nginx /var/lib/nginx
EXPOSE 80
ENTRYPOINT ["/go-overlay"]
CMD ["daemon", "--config", "/services.toml"]
Example 2: Python App + Celery Workers¶
This example runs a Flask application with Celery workers for background tasks.
services.toml:
[timeouts]
service_shutdown_timeout = 15
global_shutdown_timeout = 45
# Redis (used by Celery)
[[services]]
name = "redis"
command = "/usr/bin/redis-server"
args = ["--bind", "127.0.0.1"]
enabled = true
required = true
# Flask web application
[[services]]
name = "web"
command = "/usr/local/bin/gunicorn"
args = [
"--bind", "0.0.0.0:8000",
"--workers", "4",
"--timeout", "60",
"app:app"
]
enabled = true
required = true
depends_on = ["redis"]
wait_after = { redis = 2 }
user = "appuser"
# Celery worker
[[services]]
name = "celery-worker"
command = "/usr/local/bin/celery"
args = [
"-A", "app.celery",
"worker",
"--loglevel=info",
"--concurrency=2"
]
enabled = true
required = false
depends_on = ["redis"]
wait_after = { redis = 2 }
user = "appuser"
# Celery beat scheduler
[[services]]
name = "celery-beat"
command = "/usr/local/bin/celery"
args = [
"-A", "app.celery",
"beat",
"--loglevel=info"
]
enabled = true
required = false
depends_on = ["redis"]
wait_after = { redis = 2 }
user = "appuser"
Dockerfile:
FROM python:3.11-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
wget \
redis-server \
&& rm -rf /var/lib/apt/lists/*
# Install Go Overlay
RUN wget -O /go-overlay \
https://github.com/srelabz/go-entrypoint/releases/latest/download/go-overlay-linux-amd64 && \
chmod +x /go-overlay
WORKDIR /app
# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Copy Go Overlay configuration
COPY services.toml /services.toml
# Create non-root user
RUN useradd -m -u 1000 appuser && \
chown -R appuser:appuser /app
EXPOSE 8000
ENTRYPOINT ["/go-overlay"]
CMD ["daemon", "--config", "/services.toml"]
Docker Compose Integration¶
You can also use Go Overlay with Docker Compose for local development.
docker-compose.yml:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
- "80:80"
volumes:
- ./services.toml:/services.toml
- ./app:/app
environment:
- APP_ENV=development
- LOG_LEVEL=debug
restart: unless-stopped
# External database (not managed by Go Overlay)
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Key Points:
- Go Overlay manages services within the
appcontainer - External services like PostgreSQL run in separate containers
- Configuration can be mounted as a volume for easy updates
- Suitable for development environments
Advanced Patterns¶
Health Checks¶
Add Docker health checks to monitor Go Overlay:
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD /go-overlay status || exit 1
This checks if Go Overlay is running and services are healthy.
Multi-Stage Builds¶
Reduce image size with multi-stage builds:
# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /build
# Copy and build your application
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server
RUN CGO_ENABLED=0 GOOS=linux go build -o worker ./cmd/worker
# Runtime stage
FROM alpine:3.22
RUN apk add --no-cache ca-certificates tzdata bash
# Install Go Overlay
RUN wget -O /go-overlay \
https://github.com/srelabz/go-entrypoint/releases/latest/download/go-overlay-linux-amd64 && \
chmod +x /go-overlay
WORKDIR /app
# Copy only the built binaries
COPY --from=builder /build/server /app/server
COPY --from=builder /build/worker /app/worker
COPY services.toml /services.toml
RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser && \
chown -R appuser:appuser /app
EXPOSE 8080
ENTRYPOINT ["/go-overlay"]
CMD ["daemon", "--config", "/services.toml"]
Benefits:
- Smaller final image (no build tools)
- Faster deployment
- Improved security (fewer packages)
Environment-Specific Configuration¶
Use environment variables to customize behavior:
# Copy base configuration
COPY services.toml /services.toml
# Allow override via environment variable
ENV GO_SUPERVISOR_CONFIG=/services.toml
ENTRYPOINT ["/go-overlay"]
CMD ["daemon", "--config", "${GO_SUPERVISOR_CONFIG}"]
Then override when running:
Best Practices¶
-
Use specific base image versions: Avoid
latesttags for reproducible builds -
Minimize layers: Combine RUN commands to reduce image size
-
Run as non-root: Always create and use a non-root user
-
Clean up package managers: Remove cache after installing packages
-
Use .dockerignore: Exclude unnecessary files from build context
-
Pin Go Overlay version: Use specific version instead of
latest -
Add labels: Document your image with labels
-
Use health checks: Monitor container health
Building and Running¶
Build the Image¶
Run the Container¶
View Logs¶
# All logs
docker logs -f myapp
# Specific service logs (if using structured logging)
docker logs myapp 2>&1 | grep "service=web"
Check Service Status¶
Restart Services¶
Troubleshooting¶
Container Exits Immediately¶
Symptom: Container starts and exits right away.
Possible Causes:
- Go Overlay not found
- Check:
docker run myapp which go-overlay -
Solution: Verify installation path
-
Configuration file missing
- Check:
docker run myapp ls -la /services.toml -
Solution: Ensure COPY command in Dockerfile
-
Permission issues
- Check:
docker run myapp ls -la /go-overlay - Solution: Verify
chmod +xwas executed
Services Won't Start¶
Symptom: Container runs but services fail to start.
Check logs:
Common issues:
- Missing dependencies
-
Solution: Install required packages in Dockerfile
-
Permission denied
-
Solution: Check file ownership and user configuration
-
Port already in use
- Solution: Change port mapping or service configuration
High Memory Usage¶
Symptom: Container uses excessive memory.
Solutions:
-
Limit container memory:
-
Configure service-specific limits in services.toml
-
Use Alpine-based images for smaller footprint
Next Steps¶
- Explore Common Patterns for more configuration examples
- Learn about Service Lifecycle management
- Review Web Application Stack for complete examples