Repository navigation
Expand file tree
/
Copy pathdocker-compose.dev.yml
More file actions
162 lines (155 loc) · 6.28 KB
/
Copy pathdocker-compose.dev.yml
File metadata and controls
162 lines (155 loc) · 6.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
services:
guacd:
# Custom guacd build with H.264 (OpenH264) enabled. The official
# guacamole/guacd image builds FreeRDP with -DWITH_OPENH264=OFF, so it
# cannot decode the RDP Graphics Pipeline that Windows 10/11 and Server
# 2016+ default to: the desktop renders fully BLACK while the cursor
# still moves. Only docker-compose.deploy.yml used this build until 2.1,
# so RDP was broken in every other deployment, including all-in-one.
# See docker/Dockerfile.guacd. First build takes a few minutes; it is
# cached after that.
build:
context: .
dockerfile: docker/Dockerfile.guacd
image: shellius-guacd:h264
restart: unless-stopped
# Published ONLY in dev, and only on the loopback interface.
#
# In every other compose file the backend is a container on this network
# and reaches guacd by service name (GUACD_HOST=guacd). In dev the backend
# runs on the host, so it looks for guacd at 127.0.0.1:4822 — which
# nothing was listening on, because no dev compose file published the
# port. The symptom was every local RDP attempt failing with "Desktop
# service unavailable (SERVICE_UNAVAILABLE)" and ECONNREFUSED in the
# backend log, i.e. RDP could not be exercised locally at all.
ports:
- "127.0.0.1:4822:4822"
networks:
- default
# RDP session recordings. In dev the backend runs on the HOST, not in a
# container, so this is a bind mount to a host path rather than the named
# volume the other compose files share between two containers — the
# backend has to be able to read the files guacd writes, and a named
# volume is not visible from outside Docker.
#
# The host side matches the backend's own default (RDP_RECORDINGS_DIR,
# ./data/rdp-recordings) so a dev instance needs no extra configuration.
volumes:
- ./data/rdp-recordings:/var/lib/shellius/rdp-recordings
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER:-shellius}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-shellius_dev}
POSTGRES_DB: ${POSTGRES_DB:-shellius}
ports:
- "5433:5432"
volumes:
- postgres_dev_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-shellius}"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6380:6379"
volumes:
- redis_dev_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
# Keycloak — a REAL SAML identity provider for backend/scripts/e2e-saml.mjs.
#
# WHY IT IS BEHIND A PROFILE: nothing in normal development talks to it. It
# exists so the SAML happy path can be proven against an IdP that does its
# own XML signing, publishes its own metadata and runs on its own clock,
# instead of against fixtures our own code produced. Profiled services are
# not started by a bare `docker compose up`, so a developer who never runs
# the SAML e2e never pays for a JVM. Start it explicitly:
#
# docker compose -f docker-compose.dev.yml --profile saml up -d keycloak
# cd backend && npm run test:e2e:saml
#
# TESTING ONLY. `start-dev` means dev mode: an in-memory H2 database that is
# thrown away with the container, HTTP with no TLS, and no production
# hardening. Never use this service, this mode or these credentials for
# anything real.
#
# The admin credentials below are deliberately in the file and deliberately
# trivial. This is a throwaway local IdP bound to 127.0.0.1 with no data in
# it beyond what the e2e script creates; there is no secret here to leak,
# and the script needs them with no extra setup step.
keycloak:
profiles: ["saml"]
image: quay.io/keycloak/keycloak:26.7.4
command: ["start-dev", "--http-port=8081"]
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN:-admin}
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin}
# Loopback only — same rule as guacd above. The e2e script drives it from
# the host; nothing in a container needs to reach it.
ports:
- "127.0.0.1:8081:8081"
# ── SSH targets for the Playwright terminal suite ────────────────────────
#
# Three throwaway Debian boxes running sshd, for
# frontend/e2e/terminal.spec.js. Behind the `e2e` profile for the same
# reason Keycloak is: nothing in normal development talks to them, and a
# developer who never runs the browser suite should not be running three
# extra containers. Start them with the wrapper, which also creates the
# bind-mounted key directory before Docker does (as root):
#
# ./scripts/e2e-ssh-targets.sh up
# (cd backend && node scripts/e2e-ssh-setup.mjs)
# ./scripts/e2e-browser.sh terminal.spec.js
#
# Distinct hostnames on purpose: the shell prompt is `e2e@ssh-alpha:~$`,
# so a test with two tabs open can prove a keystroke went to the tab it
# was aimed at and not the other one.
#
# NO published ports. The dev backend runs on the host and dials the
# container's address on this Docker network directly (a private 172.x
# address, which sshConnect.resolveTarget allows); nothing outside the
# host needs to reach these, and an sshd on 0.0.0.0 is not something to
# leave lying around. The setup script resolves the addresses with
# `docker inspect`.
#
# TESTING ONLY: key-only auth, host keys regenerated on every recreate,
# no data worth keeping. See docker/Dockerfile.e2e-ssh.
ssh-alpha:
profiles: ["e2e"]
build:
context: .
dockerfile: docker/Dockerfile.e2e-ssh
image: shellius-e2e-ssh:latest
hostname: ssh-alpha
restart: "no"
volumes:
- ./data/e2e-ssh:/etc/ssh/e2e-keys:ro
ssh-bravo:
profiles: ["e2e"]
build:
context: .
dockerfile: docker/Dockerfile.e2e-ssh
image: shellius-e2e-ssh:latest
hostname: ssh-bravo
restart: "no"
volumes:
- ./data/e2e-ssh:/etc/ssh/e2e-keys:ro
ssh-charlie:
profiles: ["e2e"]
build:
context: .
dockerfile: docker/Dockerfile.e2e-ssh
image: shellius-e2e-ssh:latest
hostname: ssh-charlie
restart: "no"
volumes:
- ./data/e2e-ssh:/etc/ssh/e2e-keys:ro
volumes:
postgres_dev_data:
redis_dev_data: