BAPBA Protocol
Deployment

Docker Compose Deployment

Complete guide to deploying Burning Ash Protocol using Docker Compose.

Docker Compose Deployment

This guide covers deploying BAP using Docker Compose for development and production.

Prerequisites

  • Docker 24.0+
  • Docker Compose 2.20+
  • 2GB RAM available
  • 10GB storage

Quick Start

1. Clone Repository

git clone https://github.com/baprotocol/burning-ash-protocol.git
cd burning-ash-protocol

2. Configure Environment

make env           # Copy .env.example → .env
make generate-key  # Generate JWT_SECRET and MASTER_KEY

Or manually:

cp .env.example .env

Edit .env:

# Required
JWT_SECRET=$(openssl rand -hex 32)
MASTER_KEY=$(openssl rand -hex 32)
DOMAIN=your-domain.com

3. Start Services

# SQLite (simplest — single instance)
docker compose -f deploy/docker-compose.sqlite.yml up -d --build

# With documentation site
docker compose -f deploy/docker-compose.sqlite.yml --profile docs up -d --build

4. Verify

# Check services
docker compose -f deploy/docker-compose.sqlite.yml ps

# API health
curl http://localhost:8080/api/health

# Web interface
open http://localhost:3000

Compose File Variants

BAP provides multiple compose files in the deploy/ directory for different deployment scenarios:

FileDatabaseUse Case
docker-compose.sqlite.ymlSQLite (bundled)Simple single-instance deployments
docker-compose.postgres.ymlPostgreSQL (bundled)Production with bundled database
docker-compose.external-db.ymlPostgreSQL (external)Production with existing database + Traefik labels
docker-compose.dokploy.ymlPostgreSQL (external)Dokploy Compose (UI routing, dokploy-network)
docker-compose.swarm.ymlPostgreSQL (external)Multi-node Docker Swarm

SQLite

docker compose -f deploy/docker-compose.sqlite.yml up -d --build

Simplest deployment. SQLite limits the API to 1 replica (no concurrent writes). Suitable for self-hosted, low-traffic deployments.

Bundled PostgreSQL

docker compose -f deploy/docker-compose.postgres.yml up -d --build

Runs PostgreSQL as a container alongside the app. Supports multiple API replicas. Requires POSTGRES_PASSWORD in your .env.

External PostgreSQL

docker compose -f deploy/docker-compose.external-db.yml up -d --build

Connects to an existing PostgreSQL instance. Requires DATABASE_URL in your .env. Includes Traefik labels on the bap Docker network. Supports scaling:

docker compose -f deploy/docker-compose.external-db.yml up --scale api=3 --scale web=2 -d

Dokploy (External PostgreSQL)

For Dokploy deployments with a managed or external database:

  1. Create a Compose project and set the compose path to deploy/docker-compose.dokploy.yml
  2. Set JWT_SECRET, MASTER_KEY, DATABASE_URL, and DOMAIN in the Dokploy UI (written to .env beside the compose file)
  3. Configure routes in Dokploy for /, /docs, and /api

Dokploy attaches services to dokploy-network and handles TLS; this file intentionally omits Traefik labels.

Docker Swarm

docker stack deploy -c deploy/docker-compose.swarm.yml bap

Requires pre-built images pushed to a registry. Set REGISTRY and TAG in your .env. Scale with:

docker service scale bap_api=4 bap_web=2

Profiles

Docker Compose profiles control optional services. By default, only the core services (api and web) start. Optional services must be explicitly enabled.

Documentation Site

The documentation site is optional. To include it:

# With docs
docker compose -f deploy/docker-compose.sqlite.yml --profile docs up -d --build

# Without docs (default)
docker compose -f deploy/docker-compose.sqlite.yml up -d --build

For Swarm deployments, set DOCS_REPLICAS=0 to disable docs:

DOCS_REPLICAS=0 docker stack deploy -c deploy/docker-compose.swarm.yml bap

Core Services

API Service

Go backend serving the REST API on port 8080.

api:
  build:
    context: ./api
    dockerfile: Dockerfile
  environment:
    - DB_TYPE=sqlite
    - DATABASE_PATH=/data/bap.db
    - JWT_SECRET=${JWT_SECRET}
    - MASTER_KEY=${MASTER_KEY}
  volumes:
    - api-data:/data

Web Service

Next.js frontend on port 3000. Serves the application dashboard, landing page, blog, and guides.

web:
  build:
    context: ./web
    dockerfile: Dockerfile
    args:
      - NEXT_PUBLIC_API_URL=https://${DOMAIN}/api
      - NEXT_PUBLIC_DOCS_URL=https://${DOMAIN}/docs
  environment:
    - NEXT_PUBLIC_API_URL=https://${DOMAIN}/api
    - NEXT_PUBLIC_DOCS_URL=https://${DOMAIN}/docs

Docs Service (Optional)

Fumadocs documentation site on port 3001, served at /docs.

docs:
  profiles: [docs]
  build:
    context: ./documentation
    dockerfile: Dockerfile

Environment Variables

VariableRequiredDefaultDescription
JWT_SECRETYes-JWT signing secret (64 hex chars)
MASTER_KEYYes-Encryption master key (64 hex chars)
DOMAINYesbaprotocol.comYour domain
DB_TYPENosqlitesqlite or postgres
DATABASE_URLFor postgres-PostgreSQL connection string
DATABASE_PATHFor sqlite/data/bap.dbSQLite database path
DEPLOY_MODENoselfhostedselfhosted or saas
CORS_ORIGINSNohttps://$DOMAINAllowed CORS origins
LOG_LEVELNoinfoLogging level
ADMIN_BOOTSTRAP_SECRETNo-Secret for creating first admin

See .env.example for the full list including OAuth, Stripe, and connector credentials.

Data Persistence

Volumes

VolumePurpose
api-dataSQLite database, uploaded files
postgres-dataPostgreSQL data (bundled postgres variant)

Backup

# Backup SQLite
docker cp $(docker compose -f deploy/docker-compose.sqlite.yml ps -q api):/data/bap.db ./backup-$(date +%Y%m%d).db

# Backup PostgreSQL
docker compose -f deploy/docker-compose.postgres.yml exec postgres pg_dump -U bap bap > backup-$(date +%Y%m%d).sql

Management

Logs

# All services
docker compose -f deploy/docker-compose.sqlite.yml logs -f

# Specific service
docker compose -f deploy/docker-compose.sqlite.yml logs -f api
docker compose -f deploy/docker-compose.sqlite.yml logs -f web

Update

git pull
docker compose -f deploy/docker-compose.sqlite.yml up -d --build

Stop

docker compose -f deploy/docker-compose.sqlite.yml down

Security Hardening

Secrets

# Set proper permissions on .env
chmod 600 .env

Firewall

# Only expose necessary ports
sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS
sudo ufw allow 22/tcp   # SSH

Next Steps

On this page