Skip to main content
The AdonisJS Starter Kit includes complete Docker configuration for both development and production environments.

Development Setup

Prerequisites

  • Docker and Docker Compose installed
  • Git (to clone the repository)

Services Overview

The development environment includes the following services:

PostgreSQL

Production-grade database (PostgreSQL 18)

PgAdmin

Web-based database management

Mailpit

Email testing tool with web UI

Starting the Services

The development environment uses apps/web/docker-compose.yaml:
cd apps/web
docker compose up -d
The root docker-compose.yaml includes the web app’s compose file automatically.

Service Details

PostgreSQL Database

services:
  pgsql:
    container_name: '${COMPOSE_PROJECT_NAME}_pgsql'
    image: postgres:18
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: '${DB_DATABASE:-default}'
      POSTGRES_USER: '${DB_USER?:err}'
      POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
Key Features:
  • PostgreSQL 18 (latest stable)
  • Persistent volume for data
  • Health checks configured
  • Automatic initialization script
Accessing the Database:
# Connect via psql
docker exec -it ${COMPOSE_PROJECT_NAME}_pgsql psql -U root -d app

# Connection string
postgresql://root:root@localhost:5432/app

PgAdmin

Web-based PostgreSQL administration tool.
services:
  pgadmin:
    container_name: '${COMPOSE_PROJECT_NAME}_pgadmin'
    image: dpage/pgadmin4:latest
    ports:
      - "5050:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: '${PGADMIN_MAIL:[email protected]}'
      PGADMIN_DEFAULT_PASSWORD: '${PGADMIN_PW:-secret}'
Access PgAdmin:
PgAdmin servers are pre-configured using the servers.json file.

Mailpit

Local email testing tool with a web interface.
services:
  mailpit:
    container_name: '${COMPOSE_PROJECT_NAME}_mailpit'
    image: axllent/mailpit
    ports:
      - 8025:8025  # Web UI
      - 1025:1025  # SMTP server
    environment:
      MP_MAX_MESSAGES: 5000
      MP_DATABASE: /data/mailpit.db
      MP_SMTP_AUTH_ACCEPT_ANY: 1
      MP_SMTP_AUTH_ALLOW_INSECURE: 1
Features:
  • Web UI at http://localhost:8025
  • SMTP server on port 1025
  • Stores up to 5,000 messages
  • No authentication required (development only)
Configure AdonisJS to use Mailpit:
SMTP_HOST=localhost
SMTP_PORT=1025
[email protected]
SMTP_PASSWORD=XXX
SMTP_SECURE=0
SMTP_REJECTUNAUTHORIZED=false

Docker Compose Commands

docker compose up -d

Production Setup

The production setup uses docker-compose.prod.yaml with additional services.

Production Services

services:
  web:
    container_name: '${COMPOSE_PROJECT_NAME}_web'
    restart: always
    build:
      context: .
      dockerfile: apps/web/Dockerfile
    environment:
      HOST: web
      NODE_ENV: production
      DB_HOST: pgsql

  proxy:
    container_name: '${COMPOSE_PROJECT_NAME}_proxy'
    restart: always
    build:
      context: ./.github/docker/nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
      - 443:443

Dockerfile Explained

The production Dockerfile (apps/web/Dockerfile):
FROM node:22-alpine

# Install compatibility libraries
RUN apk add --no-cache libc6-compat

WORKDIR /app

# Enable pnpm
RUN npm install -g corepack@latest
RUN corepack enable pnpm

# Copy source code
COPY . .

# Install dependencies
ENV CI=true
RUN pnpm install --force --frozen-lockfile

# Build the application
WORKDIR /app/apps/web
RUN node ace build --ignore-ts-errors

# Run from build directory
WORKDIR /app/apps/web/build

EXPOSE 3333

CMD ["node", "bin/server.js"]
Build Stages:
  1. Base image: Node.js 22 Alpine (minimal size)
  2. Install pnpm via corepack
  3. Install dependencies with frozen lockfile
  4. Build AdonisJS application
  5. Expose port 3333
  6. Run the compiled server

Nginx Reverse Proxy

The proxy service uses Nginx to handle incoming requests:
server {
  listen 80;
  server_name localhost;
  client_max_body_size 100M;

  location / {
    proxy_pass http://web:3333;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_cache_bypass $http_upgrade;
  }
}
Features:
  • Reverse proxy to web service
  • 100MB upload limit
  • WebSocket support
  • Proper header forwarding

Running Production Stack

# Build and start production services
docker compose -f docker-compose.prod.yaml up -d --build

# View logs
docker compose -f docker-compose.prod.yaml logs -f

# Stop services
docker compose -f docker-compose.prod.yaml down
The production PostgreSQL service has no exposed ports for security. Database access is only available within the Docker network.

Networking

All services use a shared bridge network named sail:
networks:
  sail:
    driver: bridge
Service Communication:
  • Services communicate using container names
  • Web app connects to database at pgsql:5432
  • Nginx proxies to web:3333

Volumes

Persistent data is stored in named volumes:
volumes:
  pgsql:    # PostgreSQL data
  pgadmin:  # PgAdmin configuration
Volume Management:
# List volumes
docker volume ls

# Inspect volume
docker volume inspect <project>_pgsql

# Backup database
docker exec <project>_pgsql pg_dump -U root app > backup.sql

# Restore database
cat backup.sql | docker exec -i <project>_pgsql psql -U root app

Environment Variables

Docker Compose uses environment variables from .env files:
COMPOSE_PROJECT_NAME=myapp
DB_USER=root
DB_PASSWORD=secret
DB_DATABASE=app

Troubleshooting

Check if ports 5432, 5050, 8025, or 1025 are already in use:
# Check port usage
lsof -i :5432

# Change ports in docker-compose.yaml
ports:
  - "5433:5432"  # Use different host port
  1. Check if PostgreSQL is running:
    docker compose ps
    
  2. Check database logs:
    docker compose logs pgsql
    
  3. Verify environment variables in .env
Volume permissions issue:
# Reset volumes
docker compose down -v
docker compose up -d
Clear Docker cache and rebuild:
docker compose build --no-cache
docker compose up -d

Next Steps

Environment Configuration

Configure environment variables for different environments

Production Deployment

Deploy to production servers

Build docs developers (and LLMs) love