Binary Deployment

Run the binaries directly only for debugging, offline troubleshooting, or unusual environment validation. For regular use, prefer Kubernetes (Helm) or Docker Compose.

With binaries, PostgreSQL, Redis, process supervision, logs, and upgrades are all your responsibility. Containerized deployment already handles much of that repeated work.

Before You Start

You need:

  • PostgreSQL.
  • Redis.
  • API and worker binaries.
  • Environment variables for API and worker.
  • A process manager such as systemd, supervisor, or your own startup scripts.

Build Binaries

Run this from the repository root:

go build -o bin/luna-devops-api ./cmd/api
go build -o bin/luna-devops-worker ./cmd/worker

API also serves the web console, so no separate frontend service is required.

Prepare Configuration

At minimum, configure PostgreSQL, Redis, the public URL, the secret encryption key, and the first administrator:

export APP_ENV=production
export DATABASE_URL='postgres://devops:password@127.0.0.1:5432/devops?sslmode=disable'
export REDIS_ADDR='redis://default:password@127.0.0.1:6379/0'
export PUBLIC_BASE_URL='https://devops.example.com'
export SECRET_ENCRYPTION_KEY='replace-with-a-stable-random-value'
export INITIAL_ADMIN_EMAIL='admin@example.com'
export INITIAL_ADMIN_PASSWORD='replace-with-a-strong-8-to-72-byte-password'
export INITIAL_ADMIN_NAME='Platform Admin'
export INITIAL_ADMIN_LANGUAGE='en-US'

SECRET_ENCRYPTION_KEY encrypts Git, registry, and OIDC secrets. Keep it stable after deployment, otherwise old secrets may not decrypt.

INITIAL_ADMIN_* is for API only and creates the first administrator in a fresh database. It never overwrites an active administrator; if users exist but no active administrator remains, API refuses to start until one is restored. Worker does not need and must not receive the administrator password.

Start API

./bin/luna-devops-api

The default listening port follows the project configuration. Check health:

curl http://127.0.0.1:8080/healthz

For public access, put Caddy, Nginx, or another reverse proxy in front of API, then set PUBLIC_BASE_URL to the real browser-facing URL.

Start Worker

Start worker as a separate process:

./bin/luna-devops-worker

The worker handles builds, deployments, status sync, certificate issuance, and cleanup tasks. API alone can open the console, but the full delivery path requires worker.

Example systemd Shape

Use this as a starting point rather than a universal production file. Adjust paths and environment variables for your server:

[Unit]
Description=Luna DevOps API
After=network.target postgresql.service redis.service

[Service]
WorkingDirectory=/opt/luna-devops
Environment=APP_ENV=production
Environment=DATABASE_URL=postgres://devops:password@127.0.0.1:5432/devops?sslmode=disable
Environment=REDIS_ADDR=redis://default:password@127.0.0.1:6379/0
Environment=PUBLIC_BASE_URL=https://devops.example.com
Environment=SECRET_ENCRYPTION_KEY=replace-with-a-stable-random-value
Environment=INITIAL_ADMIN_EMAIL=admin@example.com
Environment=INITIAL_ADMIN_PASSWORD=replace-with-a-strong-8-to-72-byte-password
Environment=INITIAL_ADMIN_NAME=Platform Admin
Environment=INITIAL_ADMIN_LANGUAGE=en-US
ExecStart=/opt/luna-devops/bin/luna-devops-api
Restart=always

[Install]
WantedBy=multi-user.target

For worker, reuse the database, Redis, public URL, and encryption settings, but do not pass INITIAL_ADMIN_*. Change ExecStart to:

ExecStart=/opt/luna-devops/bin/luna-devops-worker

Upgrade

  1. Stop API and worker.
  2. Replace the binaries.
  3. Confirm environment variables are still present.
  4. Start API and worker.
  5. Open the console and check worker logs.

When Not To Use This

  • You do not want to maintain PostgreSQL and Redis manually.
  • You want simpler upgrades, rollbacks, and log collection.
  • You are not sure about platform configuration yet.
  • You only want to try the product first.

These cases are better served by containerized deployment.