[Unit] Description=RedHaze Range bare-metal supervisor (redhaze_run, all roles in one process) Documentation=https://github.com/yaklang/redhaze-range After=network-online.target Wants=network-online.target # Legacy docker compose form lives in git history if you need to roll back. # Allow many short-lived crashes during a problematic deploy so journal can # capture the real reason instead of systemd freezing the unit after 5 hits. StartLimitBurst=20 StartLimitIntervalSec=200 [Service] Type=simple # Run as root: simpler ops, no useradd dance during cold-start. The systemd # sandbox (ProtectSystem=strict + ReadWritePaths) below still confines what # the supervisor can touch on disk to /var/lib/redhaze + /var/log/redhaze. User=root Group=root WorkingDirectory=/var/lib/redhaze # Defaults are applied first; EnvironmentFile (loaded after) can override. # Keeping defaults here means the unit still works if redhaze.env is absent # or missing keys — important for bare-metal cold-start before bootstrap.sh # has populated /etc/redhaze/redhaze.env. Environment=PUBLIC_HOST= Environment=LOG_LEVEL=info EnvironmentFile=-/etc/redhaze/redhaze.env # Make sure persistent dirs exist before the supervisor opens SQLite. These # paths are inside ReadWritePaths so root may create them under the sandbox. ExecStartPre=/bin/mkdir -p /var/lib/redhaze/data /var/lib/redhaze/uploads /var/log/redhaze # IMPORTANT: use --flag=${VAR} (single token) instead of --flag ${VAR} so an # empty VAR collapses to an empty value rather than swallowing the next flag. ExecStart=/opt/redhaze/current/redhaze_run --addr=127.0.0.1 --base-port=18080 --db=/var/lib/redhaze/data/range.db --public-host=${PUBLIC_HOST} --log-level=${LOG_LEVEL} --service=* Restart=on-failure RestartSec=5s TimeoutStopSec=20 LimitNOFILE=65536 NoNewPrivileges=yes ProtectSystem=strict ProtectHome=yes PrivateTmp=yes ReadWritePaths=/var/lib/redhaze /var/log/redhaze StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target