Skip to content

Production Guide

A checklist and guide for deploying ArchSmith to a production environment.

Pre-Deployment Checklist

#TaskPriorityNotes
1Change JWT secretCriticalGenerate a new HMAC-SHA512 key
2Change RSA private keyCriticalGenerate a new RSA key pair
3Change PostgreSQL passwordCriticalUse a strong password
4Enable captchaHighSet arch-smith.captcha.enabled: true
5Configure PostgreSQL (master/slave)HighSet up replication if needed
6Configure RedisHighUse a dedicated Redis instance
7Enable FlywayHighSet arch-smith.flyway.enabled: true
8Set JPA DDL to validateHighspring.jpa.hibernate.ddl-auto: validate
9Configure HTTPSHighTerminate SSL at Nginx or load balancer
10Set up database backupsHighAutomated daily backups
11Adjust OTLP samplingMediumSet to 10% for production
12Review log levelsMediumAvoid DEBUG in production
13Set memory limitsMediumJVM flags or Docker resource limits

Generate Secrets

JWT Secret

Generate a secure Base64-encoded key:

bash
openssl rand -base64 64

Set it in your application-prod.yaml or as an environment variable:

yaml
arch-smith:
  jwt:
    secret: "YOUR_GENERATED_BASE64_KEY"

Or via Docker:

bash
JWT_SECRET="YOUR_GENERATED_BASE64_KEY" docker compose up -d

RSA Key Pair

Generate a new RSA private key:

bash
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:1024
openssl pkcs8 -topk8 -inform PEM -outform DER -in private.pem -out private.der -nocrypt
base64 private.der

Set the Base64-encoded private key in arch-smith.rsa-private-key. Share the corresponding public key with the frontend.

Production Configuration

Create server-admin/src/main/resources/application-prod.yaml from the example:

bash
cp application-prod.yaml.example application-prod.yaml

Key Settings

yaml
server:
  port: 8080

spring:
  jpa:
    hibernate:
      ddl-auto: validate         # Flyway manages DDL
  datasource:
    dynamic:
      primary: user_master
      datasource:
        user_master:
          driver-class-name: org.postgresql.Driver
          url: jdbc:postgresql://master:5432/archsmith
          username: ${DB_USERNAME}
          password: ${DB_PASSWORD}
        user_slave:
          driver-class-name: org.postgresql.Driver
          url: jdbc:postgresql://slave:5432/archsmith
          username: ${DB_USERNAME}
          password: ${DB_PASSWORD}
  data:
    redis:
      host: ${REDIS_HOST:redis}
      port: 6379

arch-smith:
  jwt:
    secret: ${JWT_SECRET}
    expire-seconds: 86400        # 24 hours for production
  captcha:
    enabled: true
  flyway:
    enabled: true
  monitor:
    enabled: true
  embedded:
    redis: false                 # Use real Redis
    postgresql: false            # Use real PostgreSQL

management:
  tracing:
    sampling:
      probability: 0.1           # 10% sampling in production

Database Setup

Install PostgreSQL 17

Option A: Docker (recommended for most deployments):

bash
docker run -d --name archsmith-pg \
  --restart unless-stopped \
  -e POSTGRES_USER=archsmith \
  -e POSTGRES_PASSWORD=${DB_PASSWORD} \
  -e POSTGRES_INITDB_ARGS="--encoding=UTF8 --locale=en_US.UTF-8" \
  -v postgres-data:/var/lib/postgresql/data \
  -p 5432:5432 postgres:17-alpine

Option B: Native install (Ubuntu):

bash
sudo apt install -y postgresql-17
sudo -u postgres createuser --createdb archsmith
sudo -u postgres psql -c "ALTER USER archsmith PASSWORD '<your-password>';"

Create Databases

bash
psql -h <master-host> -U archsmith -c \
  "CREATE DATABASE archsmith_user ENCODING 'UTF8' LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';"

Master/Slave Replication

For read/write split with dynamic-datasource, set up PostgreSQL streaming replication between master and slave instances. ArchSmith routes queries automatically via the @DS annotation and datasource groups configured in application-prod.yaml.

Refer to the PostgreSQL Replication Documentation for detailed setup instructions.

First Deployment

On first startup, Flyway creates all tables and seeds initial data automatically:

bash
# Start application — Flyway runs V1 (schema), V2 (data), V3 (menus)
SPRING_PROFILES_ACTIVE=prod java -jar server-admin.jar

Subsequent Deployments

Flyway automatically detects and runs new migration scripts. Always:

  1. Backup the database before deploying
  2. Review migration scripts via code review
  3. Test migrations in the test environment first

See Database Migration for the full guide.

HTTPS Setup

Option A: Nginx SSL Termination

nginx
server {
    listen 443 ssl http2;
    server_name admin.yourdomain.com;

    ssl_certificate     /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://archsmith:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

server {
    listen 80;
    server_name admin.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

Option B: Cloud Load Balancer

If using AWS ALB, GCP Load Balancer, or similar, terminate SSL at the load balancer and proxy HTTP to Nginx on port 80.

Backup Strategy

Database Backup

bash
# Daily automated backup
pg_dump -h <master-host> -U archsmith archsmith_user | gzip > backup_$(date +%Y%m%d).sql.gz

Schedule via cron for daily backups and retain 30 days:

bash
# /etc/cron.d/archsmith-backup
0 2 * * * archsmith pg_dump -h localhost -U archsmith archsmith_user | gzip > /backups/archsmith_$(date +\%Y\%m\%d).sql.gz && find /backups -name "archsmith_*.sql.gz" -mtime +30 -delete

Application Backup

  • Docker volumes for PostgreSQL data: postgres-data
  • Application logs: docker/logs/
  • Configuration: application-prod.yaml (keep in a secure vault, not git)

Monitoring

Health Check

bash
curl http://localhost:8080/actuator/health

Prometheus Metrics

Expose to your Prometheus scraper:

Released under the MIT License.