Deployment Guide

Deploy LogWard on your infrastructure using pre-built Docker images or build from source.

Pre-built Images (Recommended)

No Build Required
Use our official pre-built images from Docker Hub or GitHub Container Registry. Just download the config, set your passwords, and run.

Quick Start (2 Minutes)

bash
# Create project directory
mkdir logward && cd logward

# Download docker-compose.yml and environment template
curl -O https://raw.githubusercontent.com/logward-dev/logward/main/docker/docker-compose.yml
curl -O https://raw.githubusercontent.com/logward-dev/logward/main/docker/.env.example
mv .env.example .env

# Edit .env with secure passwords
nano .env

# Start LogWard
docker compose up -d

Required Environment Variables

VariableDescriptionExample
DB_PASSWORDPostgreSQL passwordrandom_secure_password
REDIS_PASSWORDRedis passwordanother_secure_password
API_KEY_SECRETEncryption key (32+ chars)your_32_character_secret_key_here

Database migrations run automatically on first start.

Available Docker Images

ImageRegistry
logward/backendDocker Hub
logward/frontendDocker Hub
ghcr.io/logward-dev/logward-backendGitHub Container Registry
ghcr.io/logward-dev/logward-frontendGitHub Container Registry
Production Tip

Always pin to a specific version in production instead of using latest:

bash
# In your .env file
LOGWARD_BACKEND_IMAGE=logward/backend:0.3.0
LOGWARD_FRONTEND_IMAGE=logward/frontend:0.3.0

Ready to Go

Frontend: http://localhost:3000 | API: http://localhost:8080

Remote Deployment

Important: Configure API URL

When deploying on a remote server (not localhost), you must configure PUBLIC_API_URL so the frontend knows where to find the backend.

Without this, users accessing http://your-server:3000 will get errors because the frontend will try to connect to localhost:8080 (which doesn't exist on their machine).

Configure for Remote Access

In your .env file, set the public URL where the backend API is accessible:

bash
# .env file on your server

# Replace with your server's IP or domain
PUBLIC_API_URL=http://your-server-ip:8080

# Or if using a domain
PUBLIC_API_URL=https://api.yourdomain.com

Example: VPS Deployment

bash
# Server IP: 192.168.1.100

# .env configuration
DB_PASSWORD=secure_password
REDIS_PASSWORD=secure_password
API_KEY_SECRET=your_32_character_secret_key_here
PUBLIC_API_URL=http://192.168.1.100:8080

# Access points:
# Frontend: http://192.168.1.100:3000
# API: http://192.168.1.100:8080

With Reverse Proxy (nginx/Traefik)

If you're using a reverse proxy in front of LogWard, configure accordingly:

bash
# With nginx/Traefik proxying to LogWard

# If frontend and API are on same domain (recommended)
# nginx proxies / to frontend:3000 and /api to backend:8080
PUBLIC_API_URL=

# If API is on a subdomain
# frontend at example.com, api at api.example.com
PUBLIC_API_URL=https://api.example.com
Quick Reference: PUBLIC_API_URL
ScenarioPUBLIC_API_URL
Local developmenthttp://localhost:8080
Remote server (IP)http://192.168.1.100:8080
With domainhttps://api.example.com
Same-origin proxy(empty - uses relative URLs)
LogWard Cloudhttps://api.logward.dev

Horizontal Scaling

Scale Without Code Changes
LogWard is designed for horizontal scaling. Backend and worker services are stateless - all state is stored in PostgreSQL and Redis. For high availability, use the Traefik overlay to run multiple backend instances behind a load balancer.

Enable Horizontal Scaling

The default docker-compose.yml runs a single instance of each service. For horizontal scaling, download and use the Traefik overlay:

bash
# Download Traefik overlay (adds load balancer)
curl -O https://raw.githubusercontent.com/logward-dev/logward/main/docker/docker-compose.traefik.yml

# Start with horizontal scaling support
docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d

# Scale to 3 backend instances and 2 workers
docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d --scale backend=3 --scale worker=2

# Check running instances
docker compose ps
Traefik Changes Access URLs

When using the Traefik overlay, access changes to a single port:

  • With Traefik: http://localhost:3080 (frontend + API on same port)
  • Without Traefik: Frontend at :3000, API at :8080

The LOGWARD_PORT environment variable controls the Traefik port (default: 3080).

Architecture

ComponentDefaultWith TraefikNotes
Traefik-1 instanceLoad balancer, reverse proxy
Backend1 instanceN instancesStateless API servers
Worker1 instanceN instancesBackground job processors (BullMQ)
Frontend1 instanceN instancesSvelteKit SSR
Redis1 instance1 instanceRate limiting, job queues, cache
PostgreSQL1 instance1 instanceTimescaleDB for time-series data
Why Scaling Works
  • Rate limiting: Stored in Redis (shared across all backend instances)
  • Sessions: Stored in Redis (no sticky sessions required)
  • Job queues: BullMQ distributes work across all workers automatically
  • Health checks: Traefik removes unhealthy instances from rotation

Build from Source (Alternative)

For Contributors & Custom Builds
Build Docker images locally from source code. Useful for development or when you need custom modifications.

Clone and Build

bash
# Clone the repository
git clone https://github.com/logward-dev/logward.git
cd logward/docker

# Copy environment template
cp ../.env.example .env

# Edit .env with your configuration
nano .env

# Build and start all services
docker compose up -d --build

Services Running

Access LogWard at http://your-server-ip:3000

Monitoring & Maintenance

Health Checks

bash
# Check all services status
docker compose ps

# Check backend health
curl http://localhost:8080/health

# With Traefik overlay
curl http://localhost:3080/health

# Check database
docker compose exec postgres psql -U logward -d logward -c "SELECT COUNT(*) FROM logs;"

Common Commands

bash
# Restart a service
docker compose restart backend

# View service logs
docker compose logs --tail=100 -f backend

# Stop all services
docker compose down

# Update to latest version
docker compose pull
docker compose up -d

Database Backup

bash
# Create backup
docker compose exec postgres pg_dump -U logward logward > backup_$(date +%Y%m%d).sql

# Restore from backup
docker compose exec -T postgres psql -U logward logward < backup_20250115.sql