On-Premise Installation
Deploy Lokawatch on your own infrastructure using Docker Compose. Before starting, make sure you have completed the Server Preparation checklist.
All commands below should be run as the deploy user. The Lokawatch team will help with the initial setup — this guide is here so you understand every step.
1. Clone the Repository
Your account manager will provide you with the Git repository URL. Clone it on the server:
git clone REPO_URL_PROVIDED_BY_ACCOUNT_MANAGER LokaWatch cd LokaWatch 2. Configure Environment Variables
All deployment files live under infrastructure/on-premise/. Copy the example environment file and fill in your values:
cp infrastructure/on-premise/.env.example infrastructure/on-premise/.env nano infrastructure/on-premise/.env Key values to set in .env:
| Variable | Description | Example |
|---|---|---|
DOMAIN | Your domain or subdomain (used for SSL cert and nginx) | lokawatch.yourcompany.com |
POSTGRES_PASSWORD | Database password — choose a strong random string | openssl rand -hex 32 |
JWT_SECRET_KEY | JWT signing key — at least 32 random characters | openssl rand -hex 32 |
ALLOWED_ORIGINS | JSON array of allowed CORS origins (your domain) | ["https://lokawatch.yourcompany.com"] |
Never commit the .env file. It contains secrets and is already listed in .gitignore.
3. Generate SSL Certificate
Lokawatch always runs with HTTPS. Generate an SSL certificate for your domain:
make ssl-generate DOMAIN=yourdomain.com EMAIL=admin@yourcompany.com The script will present three options. Choose based on your setup:
| # | Method | When to use |
|---|---|---|
| 1 | Let's Encrypt | Public VPS with a direct A record (domain resolves to your server IP). Requires ports 80 and 443 open. |
| 2 | Self-signed | Behind Cloudflare proxy (orange cloud) — Cloudflare handles the public SSL certificate at the edge. The origin only needs a self-signed cert for the encrypted Cloudflare-to-VPS connection. |
| 3 | mkcert | Local development only (localhost). The certificate is trusted only on the machine that ran mkcert -install. |
Using Cloudflare proxy (orange cloud)? Choose option 2 (self-signed). Cloudflare terminates SSL at its edge with its own trusted certificate. Your server only needs any certificate for the connection between Cloudflare and your origin — a self-signed cert is perfectly sufficient.
4. Start the Services
Pull all Docker images and start the stack:
make down make up Verify all containers are running:
docker ps All services should show Up status. Expected containers:
backend-api— Core REST APIai-engine— Frame analysis and AI inferencestream-worker— Camera stream processingdashboard— Safety Officer web apppostgres— PostgreSQL databaseredis— Cache and message brokerollama— Local LLM for alert summariesnginx— Reverse proxy with SSL terminationcertbot— Automatic SSL renewal (background)
5. Run Database Migrations & Seed
Once all services are healthy, initialise the database:
make db-migrate make db-seed After seeding, copy the printed tenant UUID and set it in your .env:
nano infrastructure/on-premise/.env Then restart the services so the tenant ID takes effect:
make down && make up 6. Access the Dashboard
Open a browser and navigate to your domain:
https://yourdomain.com Log in with the credentials created by make db-seed (displayed in the seed output).
Deployment Scenarios
Lokawatch supports three deployment modes. The make up command above uses the default all-in-one mode. For other setups:
All-in-One (default)
Dashboard and backend on the same server, same domain. Uses docker-compose.yml.
Backend Only
Use when the dashboard is hosted elsewhere (e.g. Cloudflare Pages).
make up-backend make db-migrate-be make db-seed-be Dashboard Only
Use when the backend is on a separate server. The dashboard connects to it via NEXT_PUBLIC_API_URL.
make up-dashboard 7. Updating Lokawatch
When a new version is available, pull the latest code and rebuild:
git pull make build make down make up make db-migrate Always back up your PostgreSQL data before running a major update. Run docker exec on-premise-postgres-1 pg_dump -U lokawatch lokawatch > ~/backup.sql first.
Troubleshooting
Check service logs
make logs make logs s=backend-api Restart a service
make restart s=backend-api Health check
make health Cloudflare timeout (522)
If Cloudflare shows "522 Connection Timed Out":
- Check that the VPS firewall (UFW) allows ports 80 and 443.
- Check the VPS provider's firewall panel — many providers (DigitalOcean, Hetzner, etc.) have their own firewall that blocks traffic before it reaches the server.
- Verify the A record in Cloudflare DNS points to the correct public IP of the VPS.
- If using Cloudflare Tunnel, ensure the tunnel is running and connected.
Let's Encrypt validation failed
If certbot fails with "Invalid response" or "404":
- The script now starts a temporary HTTP server on port 80 for the ACME challenge — no need to have nginx running beforehand.
- If using Cloudflare proxy (orange cloud), use self-signed certificates instead (option 2). Cloudflare terminates SSL at the edge, so Let's Encrypt on the origin is unnecessary.
- Ensure port 80 is open in both UFW and the VPS provider's firewall.
Containers restart in a loop
Check make logs for specific error messages. Common causes:
- PostgreSQL not ready yet — the other services will retry automatically.
- Health checks failing — check the dependent service is actually running.
- Out of memory — verify your server meets the minimum requirements (8 GB RAM).