Skip to content

Coblyn installation and operations

●  Installationv1.17.0 Release GateLevel · AdministratorLast rev · 27 Jun 2026

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

AreaCurrent state
Recommended hostUbuntu Server 24.04 LTS amd64 or Debian 12 amd64
RuntimeDocker 24+ with Docker Compose V2
PXE networkPhysical or bridged NIC with L2 access to the deployment VLAN
StorageStorage Hub pools configured from the UI using NFS or SMB/CIFS
Windows Server as hostNot a production target yet
Documented versionv1.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

ServicePortProtocolExposure
Web UI / API through nginx${WEB_PORT:-80}TCPUsers and agents
TFTP69UDPPXE clients
DHCP / Kea67/68UDPHost network, PXE interface
RustDesk hbbs21115, 21116, 21118TCPRemote support
RustDesk hbbs heartbeat21116UDPRemote support
RustDesk hbbr21117, 21119TCPRemote 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.

bash
ip -brief addr
ip route

Write down:

  • PXE interface, for example eth0 or ens192.
  • 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:

bash
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.sh

For the first installation, use the wizard and Web/API profile:

bash
sudo bash ./setup.sh --release 1.17.0-rc.5 --testing --wizard

The 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:

bash
cd /opt/coblyn/coblyn
sudo nano .env

Values to review before production:

VariablePurpose
PXE_INTERFACEPhysical or bridged interface used by Kea
PXE_SERVER_IPServer IP on the PXE network
DHCP_MODEdhcp for authoritative server, proxy to coexist with existing DHCP
DHCP_RANGE_START / DHCP_RANGE_ENDAuthorized device range
DHCP_QUARANTINE_START / DHCP_QUARANTINE_ENDIsolated range for unknown devices
WEB_PORTnginx published port
COBLYN_IMAGE_TAGMust be a pinned version, for example v1.17.0; do not use latest
RUSTDESK_IMAGEPinned image, for example rustdesk/rustdesk-server:1.1.14
CORS_ORIGINSAllowed origins; never use * in production

Required production secrets:

  • POSTGRES_PASSWORD
  • REDIS_PASSWORD
  • JWT_SECRET
  • STORAGE_ENCRYPTION_KEY
  • DHCP_WEBHOOK_SECRET
  • BOOT_PROGRESS_SECRET
  • MDM_ENROLLMENT_TOKEN

The installer normally generates them. If you are upgrading an older .env, run:

bash
sudo ./setup.sh doctor --fix

4. Validate before startup

bash
sudo ./setup.sh doctor

The doctor checks distribution, Docker, Compose V2, .env, secrets, Compose variable propagation, ports, RAM and disk.

To inspect the plan without changing the system:

bash
sudo ./setup.sh install --dry-run

5. Start the stack

In interactive mode the installer can start the stack at the end. To start manually:

bash
docker compose up -d
docker compose ps
sudo ./setup.sh admin-bootstrap

Open:

text
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

  1. Sign in with the persistent administrator you just created.
  2. Open Storage and create an NFS or SMB/CIFS pool from Storage Hub. Do not rely on the old flat NFS environment model.
  3. Upload or download the required boot assets under tftpboot/.
  4. Confirm docker compose ps does not show services restarting.
  5. Boot a PXE client on the right VLAN and confirm it appears in inventory or quarantine.

Upgrade from v1.x

From /opt/coblyn/coblyn:

bash
sudo ./setup.sh backup
sudo ./setup.sh upgrade --auto
sudo ./setup.sh doctor

v1.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:

bash
docker compose exec backend python -m utils.migrations adopt-legacy
docker compose exec backend python -m utils.migrations verify

Do 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:

bash
sudo ./setup.sh backup

The backup includes .env, license, keys, Compose files and relevant persistent data under backups/.

Before every upgrade:

bash
sudo ./setup.sh backup
docker compose ps

For a full restore on another host, keep at least:

  • Backup generated by setup.sh.
  • PostgreSQL volume or database dump.
  • license.key, keys/ and .env secrets.
  • 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
bash scripts/release-check.sh
bash scripts/package-release.sh

release-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:

bash
sudo ./setup.sh doctor --fix
sudo ./setup.sh doctor
docker compose up -d

DHCP does not respond

  • Check PXE_INTERFACE.
  • Use DHCP_MODE=proxy when a corporate DHCP server remains authoritative.
  • Inspect logs:
bash
docker logs coblyn-dhcp-kea

PXE menu does not load

bash
curl http://<PXE_SERVER_IP>/tftpboot/menus/boot.ipxe
docker logs coblyn-tftp
docker logs coblyn-nginx

Storage Hub cannot mount a pool

  • Test NFS/SMB connectivity from the host.
  • Verify credentials in the Storage UI.
  • Run sudo ./setup.sh doctor to confirm nfs-common and cifs-utils.

Docker cannot pull images

Verify connectivity to the registry configured in COBLYN_REGISTRY. If your release images are private, authenticate first:

bash
docker login registry.gitlab.com
docker compose pull

Coblyn · documentación, demo aislada y canal de instalación separados