Skip to content

Server configuration

How a panel node is configured on disk. For the API surface, see the API overview.

Path Owner / mode Content
/etc/gisila/.env gisila:gisila, 0640 Environment for gisila-panel and gisila-worker. Written on first install only. Later runs only add or update specific keys.
/etc/gisila/database.yaml gisila:gisila, 0640 Connection to the panel’s Postgres. Rewritten on every install run.
/etc/gisila/secret.key gisila, 0600 32 random bytes (base64) used to encrypt env var values and deployment snapshots. Back it up with the database.
/usr/local/bin/gisila-panel, gisila-worker, gisila-migrate, gisila-agent root The binaries
/usr/local/share/gisila/migrations root Database migrations
/srv/gisila gisila Working directory. web/ holds the built UI.
/srv/apps/app_<id> the app’s user, 0750 One directory per app
/var/lib/gisila/artifacts Uploaded binaries and ZIPs (GISILA_ARTIFACT_DIR)
/var/lib/gisila/backups Database backups (GISILA_BACKUP_DIR)
/var/backups/gisila root Pre-upgrade backups made by upgrade.sh
/etc/nginx/sites-available/gisila-panel root The panel’s own vhost (proxies to 127.0.0.1:8000, 50 MB bodies, WebSocket upgrade)
default: default
connections:
default:
type: postgresql
host: 127.0.0.1
port: 5432
database: gisila_panel
username: gisila
password: <db-password>
ssl: false
connection_timeout: 30
query_timeout: 30
max_connections: 20
min_connections: 2
additional_params:
server_version: 16

server_version is detected by the installer. When set, the panel lists this cluster as the read-only system instance on the Databases page. The file is looked up at GISILA_DATABASE_FILE, then /etc/gisila/database.yaml, then ./database.yaml.

Set in /etc/gisila/.env. Restart after editing: sudo systemctl restart gisila-panel gisila-worker.

Variable Default Description
PORT 8000 Port the API listens on (all interfaces).
JWT_SECRET random at install HMAC key for session JWTs. Required: the panel refuses to start without it or with a placeholder. Changing it signs everyone out.
JWT_EXPIRE_DAYS 14 Session lifetime.
LOG_LEVEL info trace, debug, info, warning or error.
GISILA_SECRET_KEY_FILE /etc/gisila/secret.key Encryption key location.
GISILA_DATABASE_FILE Overrides the database.yaml location.
SUPERUSER_EMAIL, SUPERUSER_PASSWORD random at install Seed the first superuser when none exists.
PUBLIC_IP auto-detected Address shown for DNS records (/system/info, mail DNS). Set it behind NAT.
PANEL_PUBLIC_URL Public URL of the panel, used to link commit statuses to app pages.
FIREWALL_CONFIRM_MINUTES 5 Window to confirm a firewall change before it rolls back (1 to 10).
Variable Default Description
REDIS_HOST from install Panel Redis host.
REDIS_PORT from install Panel Redis port.
REDIS_PASSWORD from install Required by the installer (16+ characters).
REDIS_USERNAME empty ACL user, for managed providers. Empty authenticates as default.
REDIS_TLS false true for TLS. Set automatically from a rediss:// URL.
Variable Default Description
APPS_ROOT /srv/apps Where app directories are created.
NGINX_SITES_DIR /etc/nginx/sites-enabled Where app vhosts are written.
SYSTEMD_UNITS_DIR /etc/systemd/system Where app units are written.
APPARMOR_PROFILES_DIR /etc/apparmor.d Where AppArmor profiles are written.
AGENT_BIN /usr/local/bin/gisila-agent Agent binary.
AGENT_MODE direct (installer) direct runs the agent as is (the worker is root). sudo prefixes sudo --non-interactive. dev stubs the agent out (Docker development stack). The worker unit forces direct.
GISILA_ARTIFACT_DIR /var/lib/gisila/artifacts Upload storage. Both services read it.
GISILA_BACKUP_DIR /var/lib/gisila/backups Database backup storage.
NODE_ID short hostname Node identifier, reserved for multi-node setups.
APP_PORT_RANGE_MIN, APP_PORT_RANGE_MAX 4000, 4999 Written by the installer, but app ports are currently chosen per app (1024 to 65535) and not limited by this range.
Variable Default Description
STUDIO_ENABLED 0 1, true, yes or on mounts the database admin UI at /admin.
STUDIO_USERNAME admin Studio login.
STUDIO_PASSWORD random at install Studio password. The studio isn’t mounted if this is empty or a default (admin, password, changeme).
Unit Runs Notes
gisila-panel.service /usr/local/bin/gisila-panel as gisila Sandboxed (NoNewPrivileges, ProtectSystem=strict, …). One isolate per CPU on a shared port. Ordered after a local postgresql/redis-server if present, never Requires= them.
gisila-worker.service /usr/local/bin/gisila-worker as root Runs queued jobs through the agent, plus the cron, metrics, health, backup and alert loops. PartOf=gisila-panel.service.
gisila-apps.target Groups every app unit (gisila-app_<id>.service) for bulk start and stop.
Terminal window
sudo systemctl status gisila-panel gisila-worker
journalctl -fu gisila-panel
journalctl -fu gisila-worker
journalctl -fu gisila-app_ab12cd

infra/install-prebuilt.sh (prebuilt release) and infra/install.sh (build from source) take the same connection and domain options as env vars:

Variable Description
DATABASE_URL postgresql://user:pass@host:5432/db, optionally ?sslmode=require. Replaces the DB_* variables.
DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD, DB_SSL Override fields of the URL.
REDIS_URL redis://[:pass@]host:6379, or rediss:// for TLS.
REDIS_HOST, REDIS_PORT, REDIS_PASSWORD Override fields of the URL.
PANEL_DOMAIN Hostname written into the panel’s Nginx vhost and used for the superuser email.
ISSUE_TLS=1 Run certbot for PANEL_DOMAIN once Nginx is up.
ENABLE_STUDIO=1 Mount GisilaStudio. On a re-run, 0 or 1 flips it in the existing .env.
GISILA_ALLOW_INSECURE=1 Turn the connection-security refusals into warnings. Test machines only.
SKIP_OS_CHECK=1 Skip the Ubuntu/Debian version check (unsupported).

Prebuilt installer only:

Variable Description
VERSION Release to install (default latest, falling back to the newest prerelease when no stable release exists).
RELEASE_FILE Install from a local release tarball.
RELEASE_URL, GITHUB_REPO Download from another URL or repository.

Source installer only:

Variable Description
BUILD_FRONTEND=1 Rebuild the web UI from source (needs Node.js and pnpm) instead of using the committed build.

Both installers are idempotent. A re-run rewrites database.yaml, updates the Redis keys in .env only when you pass Redis settings, and replaces the binaries.

Refused Unless
Redis without a password, or with one under 16 characters GISILA_ALLOW_INSECURE=1
A well-known Postgres password or one under 12 characters GISILA_ALLOW_INSECURE=1
Postgres or Redis on a public address without TLS GISILA_ALLOW_INSECURE=1

A private-network address without TLS, or a local server listening on a public interface, is allowed with a warning.

Script Use
infra/upgrade.sh Upgrade to a release with backup and automatic rollback. Options VERSION, RELEASE_FILE, FORCE, SKIP_DB_BACKUP, ROLLBACK, BACKUP. See Back up and upgrade.
infra/uninstall.sh Remove the panel. --apps also removes apps, --purge drops the panel database and role (same host) and gisila:* Redis keys, --all does both.
infra/build-release.sh Build the release tarball (maintainers).
scripts/dev.sh Docker development stack: up, logs, down, reset. The worker runs with AGENT_MODE=dev.
scripts/migrate.sh, scripts/psql.sh, scripts/redis-cli.sh, scripts/build_runner.sh Development helpers.