Installing an SDE site with sde-install
Learn how to install and configure an SDE site on a GLServer host, including essential components like Guacamole and the SDE gateway. This guide is aimed at engineers and covers installation, configuration, and troubleshooting tips.
Install the core of an SDE site (Guacamole, the SDE gateway and the portal) on a GLServer host in one guided run, then check it, sign in and keep it backed up.
1. What gets installed
Every part of SDE runs as a GLServer unit (one Docker container each) under /var/glitch-units/. The units join one Docker network called sde and reach each other by name. From outside the host, only the portal's port 443 is reachable.
| Unit | Image | What it does | Reached at |
|---|---|---|---|
| guac-db | mysql:8.4.13 | Guacamole's database (MySQL 8.4 LTS). | guac-db:3306, network only |
| guacd | guacamole/guacd:1.6.0 | Guacamole's proxy: makes the RDP, SSH and VNC connections for browser sessions. Holds the Guacamole drive in data/drive. | guacd:4822, network only |
| guacamole | guacamole/guacamole:1.6.0 | The web portal and its REST API, served at /. | guacamole:8080, network only unless you publish it |
| sde-network | sde-network | SDE Network (private networks). Always installed; idle until an admin sets it up on its page. | sde-network:8099 |
| sde-gateway | sde-remote-gateway | The RD Gateway (rdpgw, port 9443) and the SDE broker (port 8095) in one container: sign-in checks, native RDP authorisation, streaming, the usage report. | sde-gateway:9443 and :8095 |
| sde-nginx | glitch-rproxy | The portal: TLS on 443 and the path routing to everything above. | Host port 443 |
nginx routes by path, so one address and one certificate serve everything:
| Path | Goes to |
|---|---|
/ | Guacamole, with its WebSocket tunnel |
/remoteDesktopGateway/ | rdpgw: native RDP over WebSocket (the SDE Remote app) |
/rpc/ | rdpgw: the legacy RD Gateway transport |
/sde-broker/ | The broker (prefix removed), including the usage report at /sde-broker/report/ |
/stream-agent, /stream-connect, /stream-player, /stream-available | The broker's streaming hub |
/sde-network/, /sde-vdi/, /sde-vapps/, /sde-redirector/ | Admin pages, added only for the units that are installed |
The add-ons (SDE VDI, SDE vApps, SDE Devices) are installed separately; see their own guides.
2. Before you start
| You need | Details |
|---|---|
| A GLServer host | An Ubuntu LTS VM with GLServer installed and licensed. gl -l must work: with an expired licence every gl command fails and nothing can be started. |
| Docker access to the images | The host must be able to pull the SDE images from the SDE image registry (SDE support provides the login). GLServer sets the Docker Hub login. |
| The SDE repository on the host | Run sde-install from a checkout of the repository: it copies the unit templates from deploy/glitch-units/, and Check runs the add-ons' own check scripts from there. |
| Tools | openssl, curl and jq. whiptail gives the menus; without it (or with --plain) you get plain prompts. |
| Root | Run every command with sudo. The units' settings files are root-only. |
| Disk and clock | At least 5 GB (and 10%) free under /var/glitch-units. The clock should be NTP-synchronised: sign-in tokens and AD depend on it. |
| The site address | The FQDN users browse to, for example sde.lab.local, as it appears on the public certificate. |
| Firewall and TLS | The firewall forwards only 443 to the host. A load balancer or reverse proxy in front presents the public certificate; see section 7. |
| Active Directory (optional) | The domain controller's name as on its certificate, LDAPS (port 636), the users' and groups' base DNs, a bind account and its password, and the AD CA certificate as a PEM file on the host. |
3. The sde-install commands
sudo deploy/installer/sde-install # the menu
sudo deploy/installer/sde-install install # a fresh site: Guacamole, then the core, then Check
sudo deploy/installer/sde-install guacamole # install or repair Guacamole only
sudo deploy/installer/sde-install core # gateway, nginx and SDE Network; the shared layout
sudo deploy/installer/sde-install check # every smoke test, read-only
sudo deploy/installer/sde-install status # components and versions
| Option | What it does |
|---|---|
--dry-run | Shows every change as a WOULD ... line and changes nothing. |
--answers FILE | Takes every answer from FILE (KEY=value lines) and asks nothing. The keys are in deploy/installer/answers.example. The file holds passwords: chmod 600 it and delete it after the run. |
--plain | Plain prompts instead of menus. |
In the menu, Install SDE, Check, Status and Add a component → Guacamole (install or repair) work today. Add a component for the add-ons, Upgrade, Settings and Backups aren't built yet: they show a message and change nothing.
Every change is shown before it's made, and every file the installer rewrites is first copied to <file>.bak-YYYYMMDD-HHMMSS. Secrets are never printed in full. Each run is logged to /var/log/sde-install/ (root-only). Running a step again repairs it: values that are already set are kept.
4. Run the install
- Copy or clone the repository onto the host and change to its folder.
- Preview the run:
sudo deploy/installer/sde-install --dry-run install. Answer the questions; nothing is changed. - Run it for real:
sudo deploy/installer/sde-install install. It runs the Guacamole step (section 5), then the core step (section 6), then Check. - Read the final Check. It ends with All OK or N to fix, with a
FIXline for each problem.
If the Guacamole step fails, the install stops there. Fix what it reports and run install again.
5. The Guacamole step
Questions
| Question | Answers key | Default |
|---|---|---|
| Guacamole administrator's username | GUAC_ADMIN_USER | admin |
| Its password | GUAC_ADMIN_PASSWORD | Enter = a random one |
| How do people sign in? | SIGNIN | Guacamole accounts only (guac); or Active Directory (LDAP) (ad) |
| Domain controller, LDAPS port, users' base DN, groups' base DN, bind account and password, AD CA certificate | AD_HOST, AD_PORT, AD_USER_BASE_DN, AD_GROUP_BASE_DN, AD_BIND_DN, AD_BIND_PASSWORD, AD_CA_FILE | Asked only with AD. Port 636. |
| Publish Guacamole on a host port? | GUAC_PUBLISH_PORT | Blank = no |
| Copy connections and users from an existing Guacamole | MIGRATE_FROM_URL, MIGRATE_FROM_USER, MIGRATE_FROM_PASSWORD | Blank = no |
What it does
- Installs the guac-db, guacd and guacamole units from their templates, unless they're already there (then their settings are kept).
- Sets random MySQL root and
guacamoleuser passwords inguac-db'senviroment(mode 600), once. - Writes Guacamole's MySQL schema (from the Guacamole image's
initdb.sh --mysql) toguac-db/data/initdb/initdb.sql. MySQL loads it on its first start only. - Sets Guacamole to match usernames whatever their case (
CASE_SENSITIVITY=disabled) and to serve at/(WEBAPP_CONTEXT=ROOT). - With AD: writes the
LDAP_*settings (LDAPS,sAMAccountNameusernames, group names fromcn), turns onMYSQL_AUTO_CREATE_ACCOUNTSso AD users get a database record on first sign-in, and builds a Java truststore with your AD CA inguacamole/data/trust. - Creates the
sdeDocker network if needed and starts the three units in order, waiting for MySQL and then Guacamole to answer. - Creates the accounts (below) and then deletes
guacadmin. Guacamole 1.6's API can't disable an account, so it's removed. - With a copy source: copies the connections and grants (below).
- With AD and an installed gateway: adds the Guacamole-only accounts to the gateway's
SDE_LOCAL_ACCOUNTSand offers to restart the gateway. - Runs the Guacamole checks.
Accounts
| Account | What it's for | Password |
|---|---|---|
admin (your choice of name) | The site's administrator: a full Guacamole administrator, and so an administrator of every SDE admin page. | The one you typed, or a random one kept in /etc/sde/secrets/guacamole-admin (root-only). |
gua_srv | The service account the broker and the add-ons use to read and manage connections. Not for people. | Random (or the gateway's existing SDE_GUAC_ADMIN_PASS), written only into the units' settings. |
guacadmin | Guacamole's default account. | Deleted. |
Both admin and gua_srv get every Guacamole system permission (ADMINISTER, create users, groups, connections, connection groups and sharing profiles).
Copying from an existing Guacamole
Give the old Guacamole's URL and an administrator account on it. The step reads, then copies:
- the connections at the root of the old connection tree, with their parameters (a connection with the same name already in the new Guacamole is left as it is);
- every user, each with READ on the copied connections they could use before.
Copied users get a random password. AD users sign in through AD as before; a local Guacamole user needs a new password set by an administrator. Connections in groups aren't copied: SDE VDI and SDE vApps re-create their own entries when they next start.
If another container already holds the port you chose to publish Guacamole on, the step offers to stop it (gl -d, answers key STOP_OLD_GUACAMOLE). Its data stays: gl -d guacamole then gl -s <old unit> brings it back.
6. The core step
Questions
| Question | Answers key | Default |
|---|---|---|
| Site name (for screens and logs) | SITE_NAME | SDE |
| Address users browse to (FQDN, as on the public certificate) | SITE_FQDN | The host's name |
| Who presents the public certificate? | TLS | A load balancer or reverse proxy in front (upstream); or nginx itself (nginx) |
| Certificate and private key (PEM files on the host) | CERT_FILE, KEY_FILE | Asked only for nginx |
| Turn off for every connection (gateway-wide lock-down): Clipboard, Drive / file transfer, Printing, Audio | LOCKDOWN (for example clipboard,drive) | None ticked. Not asked when a configured gateway is already there: its lock-down is kept. |
| Publish only sde-nginx's 443? | DROP_PORTS | Yes |
| SDE Network: address block, edge router's LAN address, LAN gateway | NETWORK_BLOCK, EDGE_IP, EDGE_GATEWAY | 10.250.0.0/16; edge address can be left empty for later |
What it does
- Installs the sde-gateway, sde-nginx and sde-network units from their templates where they're missing.
- Fills in the gateway's settings that aren't set yet: the service account (
SDE_GUAC_ADMIN_USER,SDE_GUAC_ADMIN_PASS),SDE_GATEWAY_HOST,SDE_GATEWAY_PORT=443, a 32-characterSDE_TOKEN_SIGNING_KEY, and with AD theSDE_LDAP_*settings (the CA is fetched from AD automatically). It writes the lock-down choices asSDE_DISABLE_*and the app version notice (SDE_APP_VERSION,SDE_APP_DOWNLOAD_URL) fromversions.conf. See Gateway settings. - Adds a volume for the usage report's history (
data/report), so it survives a container being recreated. - Puts every SDE unit on the
sdenetwork and points them at each other by name (http://guacamole:8080and so on). - If you answered Yes to 443 only: stops the other units publishing ports (their lines in each unit's
portsfile are commented out). sde-nginx publishes443. - Sets up SDE Network: its settings,
SDE_GUEST_NETWORKSin every unit, and a route on the host to the address block through the edge router (sde-network-route.service). - Writes the nginx configuration (
sde-nginx/data/config/default) fromdeploy/installer/templates/nginx-default.conf, with blocks for the installed units, and tests it withnginx -tbefore it goes live. A configuration that fails the test isn't installed. - Restarts the units that changed, in order: guac-db, guacd, guacamole, sde-network, the add-ons, sde-gateway, sde-nginx. A unit whose settings still contain
__SET_ON_HOST__isn't started. - Records the site in
/etc/sde/install.conf(no secrets), waits for the portal to answer and runs Check.
sde-install core also moves an existing site onto this layout: it keeps set values, backs up each file it changes and shows every change first. Preview it with --dry-run./var/glitch-units/sde-gateway/glitch/config/enviroment and check that SDE_GATEWAY_HOST is the site FQDN. The installer only fills it in when it's empty, and the app's native RDP connects to this address.7. Certificates and TLS
On SDE sites a load balancer or reverse proxy in front of the host presents the public certificate. Choose A load balancer or reverse proxy in front for these. nginx's own certificate is then internal: the core step makes a self-signed one for the FQDN (valid 10 years) in sde-nginx/data/certificates/ (cert.crt, cert.key). Check only warns if it is near expiry.
Choose nginx itself only where nothing sits in front and users see nginx's certificate. Give the full-chain certificate and its key as PEM files. Check then reports an expired or soon-expiring certificate as a FIX. To replace the certificate later, run sudo deploy/installer/sde-install core again, choose nginx itself and give the new files.
rdpgw also makes its own self-signed certificate on each start. Clients never see it: nginx talks to rdpgw over the internal network and doesn't check it.
8. Check and Status
sudo deploy/installer/sde-install check is read-only and safe to run at any time. Each line is OK, FIX, WARN or NOTE; the command exits with 1 when anything needs fixing. A copy is saved in /var/log/sde-install/.
| Section | What it checks |
|---|---|
| Host | Docker running, gl working, free disk, clock sync, /etc/sde/install.conf |
| Units | Each unit running and healthy, no __SET_ON_HOST__ left, settings files mode 600, each unit's /healthz |
| Guacamole | The three units; the API answers; the service account signs in and has ADMINISTER; with AD, each installer-made admin is in SDE_LOCAL_ACCOUNTS; guacadmin/guacadmin is refused |
| SDE gateway | The gateway's built-in self-test (docker exec sde-gateway /opt/rdpgw/sde-selftest.sh); old settings that are no longer used |
| Portal | nginx -t; the certificate's expiry; Guacamole, the broker, /sde-broker/clientconfig and the rdpgw WebSocket through 443; port 80 |
| SDE Network, add-ons, Proxmox | The route and unit; each installed add-on's own check; each Proxmox token |
| Lock-down | Which units still publish ports besides 443 |
sudo deploy/installer/sde-install status shows the site, whether gl works, each component with its running version against versions.conf, the last backup in /var/backups/sde/, and where the logs are.
nmap -Pn -p- sde.lab.local.9. First sign-in
- Get the admin password if the installer chose it:
sudo cat /etc/sde/secrets/guacamole-admin. Keep the file: Check uses it to find the installer-made admins. - Browse to
https://<FQDN>/and sign in asadmin. You'll see Guacamole's home page. - In Settings, create or check your connections and give users (or AD groups) access to them.
- In the SDE Remote app, enter
https://<FQDN>/as the Guacamole URL and sign in with a user account. Leave Broker URL empty: the app uses/sde-brokeron the same server. - Open a Windows connection with native RDP to test the gateway. Use an AD account for this, not
admin. - From inside the network, open the usage report at
https://<FQDN>/sde-broker/report/and sign in as a Guacamole administrator. See Using the usage report.
10. Updating images
sde-install upgrade isn't built yetThe Upgrade menu item and the upgrade command only show a message. Until they exist, update each unit by hand as below. Back up first (section 11).The SDE units' unit.conf files use the :latest image tag (sde-remote-gateway:latest and so on). To move a unit to the newest published image, pull it and recreate the container. The gateway is the example:
docker pull "$(sed -n 's/^container=//p' /var/glitch-units/sde-gateway/glitch/config/unit.conf)"
gl -d sde-gateway && docker rm -f sde-gateway && gl -s sde-gateway
docker logs --tail 15 sde-gateway # the start-up line shows the version
sudo deploy/installer/sde-install status
sudo deploy/installer/sde-install check
The docker rm -f matters: stopping and starting the unit alone can reuse the old container, with its old image and old settings.
- Status compares what's running with
deploy/installer/versions.conf, the list of versions for this release of SDE. A unit on a different version showsspec is x.y.z. - Guacamole and MySQL are pinned to exact tags in their
unit.conffiles (guacamole/guacamole:1.6.0,guacamole/guacd:1.6.0,mysql:8.4.13). The installer doesn't change these yet. - sde-nginx (
glitch-rproxy:latest) isn't versioned yet.
11. What to back up
sde-install doesn't take backups yet: the daily backup timer and the Backups menu come with the upgrade work. Until then, back these up yourself, and always before updating a unit:
| What | Where | Why |
|---|---|---|
| Guacamole's database | A dump: docker exec guac-db sh -c 'exec mysqldump --single-transaction -uroot -p"$MYSQL_ROOT_PASSWORD" guacamole_db' > guacamole_db.sql | Every user, group, connection, permission and the history. A dump is safer than copying guac-db/data/mysql while MySQL runs. |
| Every unit's settings | /var/glitch-units/<unit>/glitch/config/ (enviroment, unit.conf, ports, volumes) | All the secrets and choices. The enviroment files hold passwords: keep the backup root-only. |
| The gateway's report history | sde-gateway/data/report | The usage report's native RDP, streaming, pool and device history. |
| The portal | sde-nginx/data/config and sde-nginx/data/certificates | The nginx configuration and certificate. |
| Guacamole's AD trust | guacamole/data/trust | The LDAPS truststore (rebuilt from the CA file if lost). |
| Guacamole drive files | guacd/data/drive | Files people moved through the Guacamole drive. |
| The installer's record and secrets | /etc/sde/install.conf, /etc/sde/secrets/ | The site's answers and the admin password the installer chose. |
| Add-ons | Each add-on unit's glitch/config and data | See each add-on's guide. |
12. Troubleshooting
| Problem | Fix |
|---|---|
| Check: "GLServer: ..." and nothing starts | gl is failing, often because the GLServer licence has expired. Renew it, then run Check again. |
| "<unit> not started: placeholders left" | A required value is still __SET_ON_HOST__ in that unit's enviroment. On a fresh site, run install (it runs the Guacamole step first, which provides the service account's password) rather than core on its own. |
| "admin isn't in the gateway's SDE_LOCAL_ACCOUNTS" | With AD on, the app checks passwords with AD first and refuses accounts AD doesn't have. Run sudo deploy/installer/sde-install guacamole again (it adds them and offers to restart the gateway), or add the names to SDE_LOCAL_ACCOUNTS and recreate the gateway. |
| "guacadmin still has its default password" | Run sudo deploy/installer/sde-install guacamole: it deletes guacadmin. |
| "<old unit> is on port 8080: it has to stop" | You chose to publish Guacamole on a port another container holds. Let the step stop it, choose another port, or leave the port blank. |
| "the new nginx config fails nginx -t: not installed" | The live configuration is unchanged. Read the nginx -t lines above the message, usually a certificate or key that doesn't match. |
| A route answers 502 through the portal | nginx can't reach that unit. Check it runs (gl -l, docker ps) and is on the sde network. |
| "service account gua_srv can't sign in to Guacamole" | SDE_GUAC_ADMIN_PASS in the gateway doesn't match the account's password in Guacamole. As admin, set gua_srv's password in Guacamole (Settings → Users) to the gateway's value, or the other way round and recreate the gateway. The add-ons use the same password. |
| A settings change doesn't take effect | Recreate the container: gl -d <unit> && docker rm -f <unit> && gl -s <unit>. |
13. Related pages
- SDE gateway settings reference: every gateway setting
- Sign-in, passwords and SyOps: sign-in, passwords and SyOps
- Using the SDE Remote usage report: using the usage report
- SDE Network: setup guide: setting up SDE Network after the install
- Installing the SDE Remote app: installing the SDE Remote app
- Setting up SDE VDI desktop pools, Setting up SDE vApps (one-click apps), SDE Devices: setup guide: the add-ons
person people found this useful.