Docker Setup Guide
This document explains how to build and run Yukinu services using Docker and Docker Compose.
Requirements
- Docker installed
- Docker Compose installed
.envfile properly configured
Build and Run
Run in project root directory:
docker compose up -d --build
# production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
Check running services:
docker ps
View logs:
docker compose logs -f
Stop Services
docker compose down
# production
docker compose -f docker-compose.yml -f docker-compose.prod.yml down
Rebuild After Code Changes
docker compose up -d --build --force-recreate
Data Persistence
PostgreSQL data is stored in Docker volume to prevent data loss. To remove all data:
docker compose down -v
Troubleshooting
| Issue | Possible Cause | Solution |
|---|---|---|
| container restarts repeatedly | wrong .env or missing variables | check logs & .env |
| cannot connect to db | host or password incorrect | update DB connection config |
| “port already in use” | service already running | stop previous stack or edit ports |
This setup is recommended for production deployment on VPS.
Docker Compose Configuration Explained
Below is the main docker-compose.yml configuration with explanation for each service.
Services Breakdown
web
- Builds the Yukinu Web App (Next.js)
- Uses
.envfile for runtime configuration - Waits for PostgreSQL to be healthy before starting
web:
build:
context: .
dockerfile: ./apps/web/Dockerfile
args:
TURBO_TEAM: ${TURBO_TEAM}
TURBO_TOKEN: ${TURBO_TOKEN}
NEXT_PUBLIC_APP_NAME: ${NEXT_PUBLIC_APP_NAME}
NEXT_PUBLIC_TRPC_USE_STREAMING: false
restart: unless-stopped
env_file: .env
environment:
POSTGRES_HOST: db
expose:
- '3000'
depends_on:
db:
condition: service_healthy
dashboard
- Builds Admin Dashboard (React Router app)
- Also waits for DB to be ready
dashboard:
build:
context: .
dockerfile: ./apps/dashboard/Dockerfile
args:
TURBO_TEAM: ${TURBO_TEAM}
TURBO_TOKEN: ${TURBO_TOKEN}
VITE_APP_NAME: ${VITE_APP_NAME}
VITE_TRPC_USE_STREAMING: false
restart: unless-stopped
env_file: .env
environment:
POSTGRES_HOST: db
expose:
- '3000'
depends_on:
db:
condition: service_healthy
nginx
- Acts as a reverse proxy for Web & Dashboard
- Supports SSL configuration (Certbot-ready)
- Maps HTTP/HTTPS ports
Development setup:
nginx:
image: nginx:trixie
restart: unless-stopped
ports:
- '80:80'
- '443:443'
volumes:
- ./tools/nginx/default.dev.conf:/etc/nginx/conf.d/default.conf
- ./tools/nginx/certbot-www:/var/www/certbot
- ./tools/nginx/certs:/etc/letsencrypt/live/localhost
depends_on:
- web
- dashboard
To create self-signed certificates for local development, run:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ./tools/nginx/certs/fullchain.pem \
-out ./tools/nginx/certs/privkey.pem \
-subj "/CN=localhost"
Production setup:
nginx:
image: nginx:latest
restart: unless-stopped
ports:
- '80:80'
- '443:443'
volumes:
- ./tools/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./tools/nginx/certbot-www:/var/www/certbot
- /etc/letsencrypt:/etc/letsencrypt
depends_on:
- web
- dashboard
db (PostgreSQL)
- Stores main application data
- Uses
.envfor credentials - Includes a
healthcheckto ensure Web & Dashboard wait for startup
db:
image: postgres:18.0
restart: unless-stopped
environment:
POSTGRES_USER: '${POSTGRES_USER}'
POSTGRES_PASSWORD: '${POSTGRES_PASSWORD}'
POSTGRES_DB: '${POSTGRES_DATABASE}'
ports:
- '${POSTGRES_PORT:-5432}:5432'
volumes:
- pg_data:/var/lib/postgresql
healthcheck:
test:
['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DATABASE}']
interval: 5s
timeout: 5s
retries: 5
start_period: 5s
Volumes
Stores persistent PostgreSQL data
volumes:
pg_data: