Skip to main content
The Go Template includes a Docker setup with hot reload capabilities for efficient containerized development.

Docker Setup Overview

The project includes:
  • Multi-stage Dockerfile with dev, builder, and production targets
  • Docker Compose configuration with hot reload support
  • PostgreSQL service with health checks
  • Development mode with full Go toolchain

Dockerfile Stages

The Dockerfile uses a multi-stage build with three targets:

Dev Stage

Based on golang:1.26, includes the full Go toolchain for development:
FROM golang:1.26 AS dev
WORKDIR /app
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download
COPY . .
This stage is used by Docker Compose for local development with hot reload.

Builder Stage

Compiles the binary with optimizations:
FROM dev AS builder
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /bin/template ./cmd/template

Production Stage

Minimal Alpine-based image for deployment:
FROM alpine:3.23 AS production
RUN apk add --no-cache ca-certificates tzdata
COPY --from=builder /bin/template /bin/template
ENTRYPOINT ["/bin/template"]

Docker Compose Configuration

The compose.yaml defines two services:

App Service

services:
  app:
    build:
      context: .
      target: dev
    env_file:
      - .env
    develop:
      watch:
        - action: rebuild
          path: .
          ignore:
            - .git/
            - .llm/
The app service:
  • Builds using the dev target
  • Loads environment variables from .env
  • Supports hot reload via Docker Compose watch
  • Ignores .git/ and .llm/ directories during sync

PostgreSQL Service

postgres:
  profiles:
    - postgres
  image: postgres:18-alpine
  environment:
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: postgres
    POSTGRES_DB: app
  ports:
    - "5432:5432"
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U postgres -d app"]
    interval: 5s
    timeout: 5s
    retries: 5
The PostgreSQL service:
  • Uses the postgres profile (opt-in)
  • Runs PostgreSQL 18 on Alpine Linux
  • Exposes port 5432 to the host
  • Includes health checks for container orchestration

Running with Docker

Start Full Stack

Start both the application and PostgreSQL:
1

Ensure .env is configured

Copy and configure your environment file:
cp .env.example .env
2

Start all services

make up
This runs docker compose --profile postgres up -d which:
  • Builds the app container (dev stage)
  • Starts PostgreSQL with the postgres profile
  • Runs both services in detached mode
3

View logs

Check application logs:
docker compose logs -f app
Check PostgreSQL logs:
docker compose logs -f postgres

Hot Reload with Docker Compose Watch

For active development with automatic rebuilds:
make watch
This enables Docker Compose’s watch mode:
  • Monitors your source code for changes
  • Automatically rebuilds the container on file changes
  • Restarts the application with your updates
  • Ignores .git/ and .llm/ directories
The watch action is rebuild, which means the container is rebuilt on changes. For faster iteration, consider running the app locally with make dev instead.

Stop Services

Stop and remove all containers:
make down

Docker Commands Reference

CommandDescription
make upStart full stack (app + postgres)
make downStop all services
make watchHot reload via docker compose watch

Database-Only Mode

If you prefer to run the application locally but use Docker for PostgreSQL:
1

Start PostgreSQL only

make db
This starts just the PostgreSQL container on localhost:5432.
2

Run the app locally

make dev
The app will connect to PostgreSQL on localhost:5432 using the DATABASE_URL from your .env file.
3

Stop PostgreSQL

make db-down

Building for Production

Build the production image:
docker build --target production -t myapp:latest .
Run the production container:
docker run --env-file .env myapp:latest
The production image:
  • Is based on Alpine Linux (~10MB base)
  • Contains only the compiled binary and essential certificates
  • Has no development tools or source code
  • Uses CGO_ENABLED=0 for static linking

Troubleshooting

Container won’t start

Check logs for errors:
docker compose logs app

Database connection issues

Verify PostgreSQL is healthy:
docker compose ps postgres
Check the health status and ensure the DATABASE_URL in .env matches the container configuration.

Hot reload not working

Ensure you’re using Docker Compose with watch support (v2.22+):
docker compose version

Next Steps

Database Setup

Learn about migrations and sqlc

Testing

Run tests in Docker

Build docs developers (and LLMs) love