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
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:
- Base image: Node.js 22 Alpine (minimal size)
- Install pnpm via corepack
- Install dependencies with frozen lockfile
- Build AdonisJS application
- Expose port 3333
- 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:
Required Variables
Optional Variables
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
Database connection refused
- Check if PostgreSQL is running:
- Check database logs:
docker compose logs pgsql
- 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