Coblyn installation and operations
Coblyn installs as an on-premise Docker appliance. Since v1.17.0 "Release Gate", production boot is intentionally strict: the stack should only start with safe secrets, pinned release images, and an operational path for diagnostics, backup, and upgrade.
No default credentials
Production mode fails fast when secrets are empty, placeholders are still present or CORS_ORIGINS=* is configured. Ignore older guides that mention admin/admin or admin/coblyn.
Supported scope
| Area | Current state |
|---|---|
| Recommended host | Ubuntu Server 24.04 LTS amd64 or Debian 12 amd64 |
| Runtime | Docker 24+ with Docker Compose V2 |
| PXE network | Physical or bridged NIC with L2 access to the deployment VLAN |
| Storage | Storage Hub pools configured from the UI using NFS or SMB/CIFS |
| Windows Server as host | Not a production target yet |
| Documented version | v1.17.0 "Release Gate" |
For a PoC without real DHCP/PXE, use --testing --wizard; the installer avoids the PXE plane and exposes the UI on a testing port.
Ports
| Service | Port | Protocol | Exposure |
|---|---|---|---|
| Web UI / API through nginx | ${WEB_PORT:-80} | TCP | Users and agents |
| TFTP | 69 | UDP | PXE clients |
| DHCP / Kea | 67/68 | UDP | Host network, PXE interface |
| RustDesk hbbs | 21115, 21116, 21118 | TCP | Remote support |
| RustDesk hbbs heartbeat | 21116 | UDP | Remote support |
| RustDesk hbbr | 21117, 21119 | TCP | Remote relay |
PostgreSQL, Redis and the backend live inside Docker network 10.150.0.0/24; do not expose those ports publicly. The backend controls Kea through the shared Unix socket /run/kea/kea-dhcp4-ctrl.sock, with no Control Agent or published HTTP API.
Clean installation
1. Prepare the server
Use a clean machine with a dedicated or bridged NIC for the deployment VLAN. Avoid NAT if you need DHCP/PXE.
ip -brief addr
ip routeWrite down:
- PXE interface, for example
eth0orens192. - Static server IP on that VLAN.
- Gateway, DNS and authorized DHCP range.
- Quarantine range for unknown devices.
2. Download and verify the bootstrapper
Download an explicit version into a private directory, verify its checksum, and inspect it before elevating privileges:
install -d -m 0700 "$HOME/coblyn-bootstrap"
cd "$HOME/coblyn-bootstrap"
curl --proto '=https' --tlsv1.2 -fSLO \
https://get.coblyn.gksistemas.es/releases/download/v1.17.0-rc.5/setup.sh
curl --proto '=https' --tlsv1.2 -fSLO \
https://get.coblyn.gksistemas.es/releases/download/v1.17.0-rc.5/setup.sh.sha256
sha256sum --check setup.sh.sha256
less setup.shFor the first installation, use the wizard and Web/API profile:
sudo bash ./setup.sh --release 1.17.0-rc.5 --testing --wizardThe bootstrap downloads the immutable tarball and checksum, rejects unsafe archive paths and file types, installs under /opt/coblyn, and delegates to coblyn/setup.sh. Do not use unattended mode until you have defined how to escrow secrets and create the first administrator without placing passwords in CLI arguments, cloud-init, or logs.
Pilot channel
The VPS-hosted get channel enables clean-host validation, and every release publishes a Sigstore manifest signed by the workflow OIDC identity. The initial bootstrap still enforces only the checksum, and a recoverable mirror outside the VPS is still required; until that verification is automated, this is not the production source. A checksum served by the same origin does not protect against full compromise of that origin.
3. Review .env
The operational file is:
cd /opt/coblyn/coblyn
sudo nano .envValues to review before production:
| Variable | Purpose |
|---|---|
PXE_INTERFACE | Physical or bridged interface used by Kea |
PXE_SERVER_IP | Server IP on the PXE network |
DHCP_MODE | dhcp for authoritative server, proxy to coexist with existing DHCP |
DHCP_RANGE_START / DHCP_RANGE_END | Authorized device range |
DHCP_QUARANTINE_START / DHCP_QUARANTINE_END | Isolated range for unknown devices |
WEB_PORT | nginx published port |
COBLYN_IMAGE_TAG | Must be a pinned version, for example v1.17.0; do not use latest |
RUSTDESK_IMAGE | Pinned image, for example rustdesk/rustdesk-server:1.1.14 |
CORS_ORIGINS | Allowed origins; never use * in production |
Required production secrets:
POSTGRES_PASSWORDREDIS_PASSWORDJWT_SECRETSTORAGE_ENCRYPTION_KEYDHCP_WEBHOOK_SECRETBOOT_PROGRESS_SECRETMDM_ENROLLMENT_TOKEN
The installer normally generates them. If you are upgrading an older .env, run:
sudo ./setup.sh doctor --fix4. Validate before startup
sudo ./setup.sh doctorThe doctor checks distribution, Docker, Compose V2, .env, secrets, Compose variable propagation, ports, RAM and disk.
To inspect the plan without changing the system:
sudo ./setup.sh install --dry-run5. Start the stack
In interactive mode the installer can start the stack at the end. To start manually:
docker compose up -d
docker compose ps
sudo ./setup.sh admin-bootstrapOpen:
http://<PXE_SERVER_IP>:<WEB_PORT>Bootstrap prompts for the username and password, only works while the database contains no users, and never persists the credential in .env. It accepts 15–128 characters, spaces and Unicode without artificial composition rules, rejects common or predictable values, and repeats the prompt after a mismatch or policy rejection.
Initial configuration after login
- Sign in with the persistent administrator you just created.
- Open Storage and create an NFS or SMB/CIFS pool from Storage Hub. Do not rely on the old flat NFS environment model.
- Upload or download the required boot assets under
tftpboot/. - Confirm
docker compose psdoes not show services restarting. - Boot a PXE client on the right VLAN and confirm it appears in inventory or quarantine.
Upgrade from v1.x
From /opt/coblyn/coblyn:
sudo ./setup.sh backup
sudo ./setup.sh upgrade --auto
sudo ./setup.sh doctorv1.17.0 introduces Alembic as the migration authority. For an existing installation, first verify that the legacy schema exactly matches the model, then adopt the baseline:
docker compose exec backend python -m utils.migrations adopt-legacy
docker compose exec backend python -m utils.migrations verifyDo not run alembic stamp directly: it bypasses the drift check that protects legacy data. On a fresh install or after deploying a revision, apply migrations as a deployment step and validate with python -m utils.migrations verify.
Minimum backup and restore set
Operational backup:
sudo ./setup.sh backupThe backup includes .env, license, keys, Compose files and relevant persistent data under backups/.
Before every upgrade:
sudo ./setup.sh backup
docker compose psFor a full restore on another host, keep at least:
- Backup generated by
setup.sh. - PostgreSQL volume or database dump.
license.key,keys/and.envsecrets.- RustDesk data if you need to preserve remote-support keys.
- Image repositories managed by Storage Hub.
Local release validation
On a Linux environment with Bash:
bash scripts/release-check.sh
bash scripts/package-release.shrelease-check.sh runs syntax checks, backend tests, Alembic heads, frontend lint/test/build, Compose validation and packaging. package-release.sh creates dist/coblyn-v<version>.tar.gz plus checksum.
Troubleshooting
Backend restarts with "Unsafe production configuration"
Secrets are empty, placeholders remain, or CORS is unsafe. Run:
sudo ./setup.sh doctor --fix
sudo ./setup.sh doctor
docker compose up -dDHCP does not respond
- Check
PXE_INTERFACE. - Use
DHCP_MODE=proxywhen a corporate DHCP server remains authoritative. - Inspect logs:
docker logs coblyn-dhcp-keaPXE menu does not load
curl http://<PXE_SERVER_IP>/tftpboot/menus/boot.ipxe
docker logs coblyn-tftp
docker logs coblyn-nginxStorage Hub cannot mount a pool
- Test NFS/SMB connectivity from the host.
- Verify credentials in the Storage UI.
- Run
sudo ./setup.sh doctorto confirmnfs-commonandcifs-utils.
Docker cannot pull images
Verify connectivity to the registry configured in COBLYN_REGISTRY. If your release images are private, authenticate first:
docker login registry.gitlab.com
docker compose pull