# REFERENCE ONLY — install.sh GENERATES the real unit at install time,
# substituting the actual PANEL_DIR/ports/user (see write_unit in install.sh).
# This static copy assumes the /opt/panel defaults; edit it by hand if you wire
# the units up yourself (e.g. via compose) instead of running install.sh.
[Unit]
Description=Panel controller (HTTP dashboard :8080 + agent gRPC :8443)
Documentation=https://github.com/dbledeez/panel
After=network-online.target docker.service
Wants=network-online.target

[Service]
Type=simple
# install.sh creates this user; change to taste. The controller does NOT
# need docker access — only the agent does.
User=panel
Group=panel
# The controller resolves ./data (CA, admin-token, cluster stores) and
# ./modules relative to its working directory — keep them together here.
WorkingDirectory=/opt/panel
# Defaults first; /opt/panel/panel.env (PANEL_DB_URL, PANEL_HTTP_PORT,
# PANEL_ADMIN_PASSWORD, ...) overrides them because it is applied later.
Environment=PANEL_HTTP_PORT=8080
Environment=PANEL_GRPC_PORT=8443
EnvironmentFile=-/opt/panel/panel.env
ExecStart=/opt/panel/bin/controller \
    -http :${PANEL_HTTP_PORT} \
    -grpc :${PANEL_GRPC_PORT} \
    -ca-dir ./data/ca
Restart=on-failure
RestartSec=3

# Hardening — the controller only needs its own tree + the network.
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/panel
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true

[Install]
WantedBy=multi-user.target
