Skip to content

Deployment

Adam Comer edited this page Jan 26, 2026 · 1 revision

Deployment Guide

This guide covers deploying the Linguistics Tree Solver using Docker images from GitHub Container Registry.

Images

Docker images are automatically published to GitHub Container Registry:

Registry: ghcr.io/adambcomer/lin-tree-solver

Available tags:

  • v1.0.0, v1.0.1, etc. - Specific version tags
  • latest - Latest released version

Environment Variables

  • NODE_ENV - Set to production for production deployments (default in Docker)
  • DATABASE_PATH - Path to SQLite database file (default: ./database.sqlite)
  • PORT - Server port (default: 3000)

Docker Run

Basic Deployment

Pull and run the latest image:

docker pull ghcr.io/adambcomer/lin-tree-solver:latest
docker run -d \
  --name lin-tree-solver \
  -p 3000:3000 \
  ghcr.io/adambcomer/lin-tree-solver:latest

With Persistent Storage

For production deployments, mount a volume to persist the SQLite database:

docker run -d \
  --name lin-tree-solver \
  -p 3000:3000 \
  -v /path/to/persistent/storage:/app/data \
  -e DATABASE_PATH=/app/data/database.sqlite \
  --restart unless-stopped \
  ghcr.io/adambcomer/lin-tree-solver:latest

Docker Compose

Create a docker-compose.yml file for easier deployment management:

services:
  lin-tree-solver:
    image: ghcr.io/adambcomer/lin-tree-solver:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_PATH=/app/data/database.sqlite
    volumes:
      - ./data:/app/data

Docker Compose with Reverse Proxy

Example with Nginx reverse proxy for HTTPS:

services:
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - '443:443'
    volumes:
      - './nginx.conf/:/etc/nginx/nginx.conf:ro'
      - './website.crt:/etc/nginx/website.crt:ro'
      - './website.key:/etc/nginx/website.key:ro'
  lin-tree-solver:
    image: 'ghcr.io/adambcomer/lin-tree-solver:latest'
    restart: unless-stopped
    ports:
      - '3000:3000'
    environment:
      DATABASE_PATH: '/app/data/database.sqlite'
    volumes:
      - './data:/app/data'

Example Nginx configuration for HTTPS:

events {}

http {
	upstream node {
		server server:3000;
		keepalive 2;
	}

	proxy_cache_path /cache keys_zone=assetcache:10m max_size=100m;
	
	server {
		listen 443 ssl;
		
		http2 on;

		ssl_certificate website.crt;
		ssl_certificate_key website.key;

		location / {
			proxy_pass http://node;
			proxy_http_version 1.1;
			proxy_set_header Connection "";
		}
		location /assets/ {
			proxy_cache assetcache;
			add_header X-Proxy-Cache $upstream_cache_status; 
			proxy_pass http://node;
			proxy_http_version 1.1;
			proxy_set_header Connection "";
		}
		location ~* \.(png|jpeg|jpg|avif|jxl) {
			proxy_cache assetcache;
			add_header X-Proxy-Cache $upstream_cache_status; 
			proxy_pass http://node;
			proxy_http_version 1.1;
			proxy_set_header Connection "";
		}
	}
}

Kubernetes Deployment

Basic Deployment

Create deployment.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: lin-tree-solver

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: lin-tree-solver-data
  namespace: lin-tree-solver
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: lin-tree-solver
  namespace: lin-tree-solver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lin-tree-solver
  template:
    metadata:
      labels:
        app: lin-tree-solver
    spec:
      containers:
      - name: lin-tree-solver
        image: ghcr.io/adambcomer/lin-tree-solver:latest
        ports:
        - containerPort: 3000
          name: http
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_PATH
          value: "/app/data/database.sqlite"
        volumeMounts:
        - name: data
          mountPath: /app/data
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 10
          periodSeconds: 5
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: lin-tree-solver-data

---
apiVersion: v1
kind: Service
metadata:
  name: lin-tree-solver
  namespace: lin-tree-solver
spec:
  selector:
    app: lin-tree-solver
  ports:
  - port: 80
    targetPort: 3000
    protocol: TCP
  type: ClusterIP

Database Management

Database Backup

sqlite3 /path/to/persistent/storage/database.sqlite ".backup 'database_backeup.sqlite'"

Database Migrations

The database schema is automatically initialized on first run. No manual migrations are required.