ข้ามไปยังเนื้อหาเอกสาร

กำลังดำเนินการแปล

เอกสารนี้แสดงเป็นภาษาอังกฤษชั่วคราว ขณะกำลังจัดเตรียมเนื้อหาฉบับแปลภาษาไทย

Docker Compose Deployment

Docker Compose offers the fastest and most reproducible method to deploy Aqiled on an individual server or cloud virtual machine.

พร้อมใช้งานแล้ว. ตรวจสอบล่าสุดเมื่อ: 26 October 2026.

Architecture in Docker

The Docker Compose setup launches three services in an isolated bridge network:

  • db: PostgreSQL 18 container pinned to postgres:18-bookworm.
  • api: .NET API service running Kestrel internally on port 5216.
  • web: Nginx web server serving the compiled dedicated front-end and reverse-proxying /api and /hubs.
graph LR
    Browser[Web Browser] -->|HTTPS: 443| Nginx[web: Nginx Container]
    Nginx -->|Static Assets| ReactApp[dist/dedicated]
    Nginx -->|/api and /hubs| ApiService[api: .NET Container]
    ApiService -->|Port 5432| Postgres[(db: PostgreSQL 18 Volume)]

1. Directory Setup

Create a deployment directory on your server:

mkdir -p /opt/aqiled && cd /opt/aqiled

2. Docker Compose File

Create docker-compose.yml:

version: '3.8'

services:
  db:
    image: postgres:18-bookworm
    container_name: aqiled_db
    restart: always
    environment:
      POSTGRES_DB: school_db
      POSTGRES_PASSWORD: DB_ROOT_PASSWORD_CHANGE_ME
    volumes:
      - postgres_data:/var/lib/postgresql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d school_db"]
      interval: 5s
      timeout: 5s
      retries: 5

  api:
    image: aqiled/api:latest
    container_name: aqiled_api
    restart: always
    depends_on:
      db:
        condition: service_healthy
    env_file:
      - api.env
    ports:
      - "127.0.0.1:5216:5216"

  web:
    image: aqiled/web:latest
    container_name: aqiled_web
    restart: always
    depends_on:
      - api
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt:ro
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

volumes:
  postgres_data:

3. Environment Variables (api.env)

Generate secure 32-character hexadecimal keys before launching:

openssl rand -hex 32 # For Encryption__MasterKey
openssl rand -hex 32 # For Jwt__Secret

Create api.env:

ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=http://+:5216

# Deployment Mode (Leave empty until provisioned)
Deployment__Mode=MultiTenant
Deployment__SchoolTenantId=

# Database Connections (target internal db container)
ConnectionStrings__DefaultConnection=Host=db;Port=5432;Database=school_db;Username=school_app;Password=APP_ROLE_PASSWORD;
ConnectionStrings__AdminConnection=Host=db;Port=5432;Database=school_db;Username=school_admin;Password=ADMIN_ROLE_PASSWORD;
ConnectionStrings__MigrationConnection=Host=db;Port=5432;Database=school_db;Username=school_migrator;Password=MIGRATOR_PASSWORD;

# Security & Secrets
Encryption__MasterKey=GENERATED_32_CHAR_MASTER_KEY
Jwt__Secret=GENERATED_32_CHAR_JWT_SECRET

4. Initialization & Provisioning

Run once to initialize the container database

  1. Start the database container:docker compose up -d db
  2. Create the database roles: Connect to the container and run the role creation SQL from the Prerequisites Guide.

  3. Run the EF database migration bundle:docker compose run --rm api dotnet School.Api.dll --migrate
  4. Provision your school:docker compose run --rm api dotnet School.Api.dll provision-school \ --name "Madrasah Al-Falah" \ --slug "alfalah" \ --country "TH" \ --school-type "kindergarten" \ --admin-email "admin@alfalah.ac.th" \ --admin-first-name "Ahmad" \ --admin-last-name "Dahlan"

    Enter your admin password when prompted. The command prints your School tenant ID.

  5. Switch to SingleSchool mode: In api.env, update:

    Deployment__Mode=SingleSchool Deployment__SchoolTenantId=PASTE_PRINTED_TENANT_ID
  6. Start all services:docker compose up -d

5. Validate Container Health

Verify that the API and database are running and healthy:

curl -i http://127.0.0.1:5216/health/ready

Response must return HTTP/1.1 200 OK.