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=[email protected]

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 API
  • ai-engine — Frame analysis and AI inference
  • stream-worker — Camera stream processing
  • dashboard — Safety Officer web app
  • postgres — PostgreSQL database
  • redis — Cache and message broker
  • ollama — Local LLM for alert summaries
  • nginx — Reverse proxy with SSL termination
  • certbot — 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":

  1. Check that the VPS firewall (UFW) allows ports 80 and 443.
  2. Check the VPS provider's firewall panel — many providers (DigitalOcean, Hetzner, etc.) have their own firewall that blocks traffic before it reaches the server.
  3. Verify the A record in Cloudflare DNS points to the correct public IP of the VPS.
  4. If using Cloudflare Tunnel, ensure the tunnel is running and connected.

Let's Encrypt validation failed

If certbot fails with "Invalid response" or "404":

  1. The script now starts a temporary HTTP server on port 80 for the ACME challenge — no need to have nginx running beforehand.
  2. 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.
  3. 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).

Talk to Our Team

Tell us about your operation — we'll respond within 1 business day.