Every public lab service is routed through one Nginx reverse proxy on VM 101
(crc-proxy-gateway-01) at 192.168.1.55. It terminates TLS with Let's Encrypt
certificates and forwards to the internal service VMs by server_name.
Internet -> Dreamwall (108.31.169.90) -> VM 101 (192.168.1.55:80/443) -> Internal Service VMs
108.31.169.90192.168.1.55server_nameThe portal is not here.
my.digitalrcc.comis served by Vercel, not by
this edge.
The lab moved from *.tcecure.com to *.digitalrcc.com. Both names serve the
same backend — the old vhosts are kept as the rollback path and will be retired
once a cohort has run entirely on the new names.
| Service | Current name | Legacy name (still serving) | Backend |
|---|---|---|---|
| Moodle LMS | lms.digitalrcc.com |
crc.lms.tcecure.com |
https://192.168.1.169 (proxy_ssl_verify off) |
| AWX | awx.digitalrcc.com |
crc.awx.tcecure.com |
http://192.168.1.103:30080 |
| Guacamole (lab) | guac.01.digitalrcc.com |
crc.guac.01.tcecure.com |
http://192.168.1.51:8080/guacamole/ |
| Guacamole (CDW) | guac.02.digitalrcc.com |
crc.guac.02.tcecure.com |
http://192.168.50.10:8080/guacamole/ |
| Wiki.js (this wiki) | wiki.digitalrcc.com |
crc.wiki.tcecure.com, drcc.wiki.digitalrcc.com |
http://192.168.1.42:80 |
| Training tracker | training.digitalrcc.com |
training.status.tcecure.com |
http://192.168.1.61:4000 |
| LabOps console / LabOps AI | labops.digitalrcc.com |
labops.drcc.digitalrcc.com |
http://192.168.1.65:3100 |
| IDE (OpenHands) | ide.digitalrcc.com |
crc.ide.tcecure.com |
http://192.168.1.61:3000 — backend down |
| Legacy AI portal | — | crc.ai.tcecure.com |
http://192.168.1.61:4000 — superseded by LabOps |
Application-side base URLs were moved with the names: Moodle wwwroot plus its
stored links and caches, AWX hostname and CSRF_TRUSTED_ORIGINS (both origins
trusted), the Wiki.js Site URL, the Live Ops collector's GUAC_WEB_URL, and the
Vercel MOODLE_BASE_URL / TRAINING_TRACKER_BASE_URL.
ide.digitalrcc.com answers at the edge but its backend (192.168.1.61:3000)
is not running, so the name times out or returns 504 — the same as the legacy
name, and unrelated to the rename.
All names have their own Let's Encrypt certificate and certbot auto-renews them.
Current state (checked September 22, 2026):
| Certificate | Expires |
|---|---|
| awx.digitalrcc.com | 2026-12-17 |
| guac.01.digitalrcc.com | 2026-12-17 |
| guac.02.digitalrcc.com | 2026-12-17 |
| ide.digitalrcc.com | 2026-12-17 |
| lms.digitalrcc.com | 2026-12-17 |
| wiki.digitalrcc.com | 2026-12-17 |
| labops.digitalrcc.com | 2026-12-17 |
| training.digitalrcc.com | 2026-12-17 |
| crc.awx.tcecure.com | 2026-11-10 |
| crc.guac.01.tcecure.com | 2026-11-09 |
| crc.guac.02.tcecure.com | 2026-11-26 |
| crc.ide.tcecure.com | 2026-11-03 |
| crc.lms.tcecure.com | 2026-11-09 |
| crc.wiki.tcecure.com | 2026-11-04 |
| training.status.tcecure.com | 2026-11-11 |
| drcc.wiki.digitalrcc.com | 2026-11-05 |
| labops.drcc.digitalrcc.com | 2026-11-23 |
| crc.ai.tcecure.com | 2026-10-29 |
sudo certbot certificates # list
sudo certbot renew --dry-run # test renewal
| Property | Value |
|---|---|
| VM ID | 101 (on PVE1) |
| Hostname | crc-proxy-gateway-01 |
| Internal IP | 192.168.1.55 |
| Admin user | crc-adm |
| Public IP | 108.31.169.90 (via Dreamwall NAT) |
| Path | Purpose |
|---|---|
/etc/nginx/sites-available/ |
Site configuration files (one per public name) |
/etc/nginx/sites-enabled/ |
Symlinks to active configs |
/etc/letsencrypt/live/ |
Certificates per domain |
Notable per-site details:
/guac-assets/progress-link.js with sub_filter andUpgrade / Connection headers plus a long proxy_read_timeout.127.0.0.1:3000, not exposed) and sets client_max_body_size 50M.proxy_ssl_verify off andclient_max_body_size 256M./ → /training/status and /pod/XX →/training/status/pod/XX.The dual-serve pattern used for the cutover: copy the existing vhost, change the
server_name, issue a certificate, leave the old vhost in place.
/etc/nginx/sites-available/<new-name> with the same proxy body as thesudo ln -s /etc/nginx/sites-available/<new-name> /etc/nginx/sites-enabled/sudo nginx -t && sudo systemctl reload nginx108.31.169.90sudo certbot --nginx -d <new-name> --non-interactive --agree-tos --email admin@digitalrcc.comcurl -I https://<new-name>wwwroot, AWX hostname andCSRF_TRUSTED_ORIGINS, Wiki.js Site URL, Vercel env) — proxying alone is notRollback: rm /etc/nginx/sites-enabled/<new-name> then
nginx -t && systemctl reload nginx. Old DNS records stay in place throughout,
so rollback never waits on propagation.
ssh devin-adm@108.31.169.90 -p 2225, thenssh crc-adm@192.168.1.55sudo qm guest exec 101 -- <command>| Problem | Solution |
|---|---|
| 502 Bad Gateway | Backend service is down. Check the internal VM and its service. |
| 504 Gateway Timeout | Backend is slow or not listening (this is what ide.digitalrcc.com shows today). |
| Certificate expired | Run sudo certbot renew on VM 101. |
| New name not working | Verify: symlink exists, nginx -t passes, nginx reloaded, DNS resolves. |
| App links point at the old name | The application's own base URL was not updated — proxying does not rewrite absolute links. |
| WebSocket not connecting | Ensure Upgrade and Connection headers are set. |
| Large upload fails | Add/increase client_max_body_size. |