Skip to content

Commit 4ad6347

Browse files
committed
feat(lab-02): Jitsi LAN -- coturn TURN/STUN server, config.js TURN config
1 parent 1113f20 commit 4ad6347

3 files changed

Lines changed: 273 additions & 45 deletions

File tree

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,37 @@ jobs:
103103
- name: Cleanup
104104
if: always()
105105
run: docker compose -f docker/docker-compose.standalone.yml down -v
106+
107+
lab-02-smoke:
108+
name: Lab 02 — Jitsi LAN (coturn TURN/STUN, web, TLS, config.js)
109+
runs-on: ubuntu-latest
110+
needs: validate
111+
continue-on-error: true
112+
steps:
113+
- uses: actions/checkout@v4
114+
115+
- name: Install tools
116+
run: sudo apt-get install -y curl openssl
117+
118+
- name: Validate LAN compose
119+
run: docker compose -f docker/docker-compose.lan.yml config -q && echo "LAN compose valid"
120+
121+
- name: Start LAN stack
122+
run: docker compose -f docker/docker-compose.lan.yml up -d
123+
124+
- name: Wait for coturn TURN server
125+
run: timeout 30 bash -c 'until timeout 3 bash -c "echo > /dev/tcp/localhost/3478" 2>/dev/null; do sleep 2; done'
126+
127+
- name: Wait for Jitsi web
128+
run: timeout 120 bash -c 'until curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" | grep -E "^(200|301|302)"; do sleep 5; done'
129+
130+
- name: Run Lab 08-02 test script
131+
run: bash tests/labs/test-lab-08-02.sh
132+
133+
- name: Collect logs on failure
134+
if: failure()
135+
run: docker compose -f docker/docker-compose.lan.yml logs
136+
137+
- name: Cleanup
138+
if: always()
139+
run: docker compose -f docker/docker-compose.lan.yml down -v

docker/docker-compose.lan.yml

Lines changed: 160 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,170 @@
1-
# Lab 02 — External Dependencies: jitsi with external PostgreSQL and Redis
2-
---
1+
# =============================================================================
2+
# IT-Stack — Jitsi — Lab 02: External Dependencies
3+
# =============================================================================
4+
# Adds a coturn TURN/STUN server to the 4-container Jitsi stack.
5+
# The TURN server enables NAT traversal for clients behind firewalls/NAT,
6+
# which is required in any real LAN or internet deployment.
7+
#
8+
# Services:
9+
# coturn — coturn 4.6 TURN/STUN server (:3478 TCP/UDP, :5349 TLS)
10+
# prosody — XMPP server (xmpp.meet.jitsi alias)
11+
# jicofo — conference focus
12+
# jvb — video bridge with TURN config (:10000/udp, :4443)
13+
# web — Jitsi Web (:8443 HTTPS, :8180 HTTP)
14+
#
15+
# Usage:
16+
# docker compose -f docker/docker-compose.lan.yml up -d
17+
# docker compose -f docker/docker-compose.lan.yml down -v
18+
# =============================================================================
19+
20+
networks:
21+
jitsi-net:
22+
driver: bridge
23+
turn-net:
24+
driver: bridge
25+
26+
volumes:
27+
jitsi-lan-prosody-config:
28+
jitsi-lan-prosody-plugins:
29+
jitsi-lan-jicofo-config:
30+
jitsi-lan-jvb-config:
31+
jitsi-lan-web-config:
32+
333
services:
4-
jitsi:
5-
image: jitsi/web:stable
6-
container_name: it-stack-jitsi
7-
restart: unless-stopped
34+
35+
coturn:
36+
image: coturn/coturn:4.6
37+
container_name: jitsi-lan-coturn
838
ports:
9-
- "443:$firstPort"
39+
- "3478:3478/tcp"
40+
- "3478:3478/udp"
41+
- "5349:5349/tcp"
42+
- "5349:5349/udp"
43+
command: >
44+
--listening-port=3478
45+
--tls-listening-port=5349
46+
--min-port=49152
47+
--max-port=49200
48+
--lt-cred-mech
49+
--fingerprint
50+
--realm=lab.local
51+
--user=jitsi:TurnPass1!
52+
--log-file=stdout
53+
--no-cli
54+
networks:
55+
- turn-net
56+
- jitsi-net
57+
restart: unless-stopped
58+
59+
prosody:
60+
image: jitsi/prosody:stable-9753
61+
container_name: jitsi-lan-prosody
1062
environment:
11-
- IT_STACK_ENV=lab-02-lan
12-
- DB_HOST=
13-
- DB_PORT=5432
14-
- REDIS_HOST=
63+
AUTH_TYPE: internal
64+
ENABLE_AUTH: "1"
65+
ENABLE_GUESTS: "1"
66+
JICOFO_AUTH_PASSWORD: JicofoPass1!
67+
JVB_AUTH_PASSWORD: JvbPass1!
68+
JICOFO_COMPONENT_SECRET: JicofoSecret1!
69+
XMPP_DOMAIN: meet.jitsi
70+
XMPP_AUTH_DOMAIN: auth.meet.jitsi
71+
XMPP_GUEST_DOMAIN: guest.meet.jitsi
72+
XMPP_MUC_DOMAIN: muc.meet.jitsi
73+
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
74+
TURN_HOST: coturn
75+
TURN_PORT: "3478"
76+
TURN_CREDENTIALS: TurnPass1!
77+
TZ: UTC
78+
volumes:
79+
- jitsi-lan-prosody-config:/config
80+
- jitsi-lan-prosody-plugins:/prosody-plugins-custom
1581
networks:
16-
- it-stack-net
82+
jitsi-net:
83+
aliases:
84+
- xmpp.meet.jitsi
85+
restart: unless-stopped
1786

18-
# Lightweight local DB for lab (replace with lab-db1 in real env)
19-
postgres:
20-
image: postgres:16
21-
container_name: it-stack-jitsi-db
87+
jicofo:
88+
image: jitsi/jicofo:stable-9753
89+
container_name: jitsi-lan-jicofo
2290
environment:
23-
POSTGRES_DB: jitsi_db
24-
POSTGRES_USER: jitsi_user
25-
POSTGRES_PASSWORD: jitsi_pass
91+
AUTH_TYPE: internal
92+
JICOFO_AUTH_PASSWORD: JicofoPass1!
93+
JICOFO_COMPONENT_SECRET: JicofoSecret1!
94+
XMPP_SERVER: xmpp.meet.jitsi
95+
XMPP_DOMAIN: meet.jitsi
96+
XMPP_AUTH_DOMAIN: auth.meet.jitsi
97+
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
98+
TZ: UTC
2699
volumes:
27-
- jitsi_pg_data:/var/lib/postgresql/data
100+
- jitsi-lan-jicofo-config:/config
28101
networks:
29-
- it-stack-net
102+
- jitsi-net
103+
depends_on:
104+
- prosody
105+
restart: unless-stopped
30106

31-
networks:
32-
it-stack-net:
33-
driver: bridge
107+
jvb:
108+
image: jitsi/jvb:stable-9753
109+
container_name: jitsi-lan-jvb
110+
ports:
111+
- "10000:10000/udp"
112+
- "4443:4443"
113+
environment:
114+
JVB_AUTH_PASSWORD: JvbPass1!
115+
XMPP_SERVER: xmpp.meet.jitsi
116+
XMPP_DOMAIN: meet.jitsi
117+
XMPP_AUTH_DOMAIN: auth.meet.jitsi
118+
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
119+
DOCKER_HOST_ADDRESS: 127.0.0.1
120+
# TURN configuration
121+
JVB_STUN_SERVERS: coturn:3478
122+
TURN_HOST: coturn
123+
TURN_PORT: "3478"
124+
TURN_CREDENTIALS: TurnPass1!
125+
TZ: UTC
126+
volumes:
127+
- jitsi-lan-jvb-config:/config
128+
networks:
129+
- jitsi-net
130+
depends_on:
131+
- prosody
132+
restart: unless-stopped
34133

35-
volumes:
36-
jitsi_pg_data:
134+
web:
135+
image: jitsi/web:stable-9753
136+
container_name: jitsi-lan-web
137+
ports:
138+
- "8443:443"
139+
- "8180:80"
140+
environment:
141+
ENABLE_AUTH: "1"
142+
ENABLE_GUESTS: "1"
143+
PUBLIC_URL: https://localhost:8443
144+
XMPP_SERVER: xmpp.meet.jitsi
145+
XMPP_BOSH_URL_BASE: http://xmpp.meet.jitsi:5280
146+
XMPP_DOMAIN: meet.jitsi
147+
XMPP_AUTH_DOMAIN: auth.meet.jitsi
148+
XMPP_GUEST_DOMAIN: guest.meet.jitsi
149+
XMPP_MUC_DOMAIN: muc.meet.jitsi
150+
JVB_TCP_HARVESTER_DISABLED: "true"
151+
# TURN configuration for web clients
152+
TURN_HOST: coturn
153+
TURN_PORT: "3478"
154+
TURN_CREDENTIALS: TurnPass1!
155+
TZ: UTC
156+
volumes:
157+
- jitsi-lan-web-config:/config
158+
networks:
159+
- jitsi-net
160+
depends_on:
161+
- prosody
162+
- jicofo
163+
- jvb
164+
healthcheck:
165+
test: ["CMD-SHELL", "curl -sk https://localhost/ -o /dev/null -w '%{http_code}' | grep -E '^(200|301|302)$'"]
166+
interval: 30s
167+
timeout: 10s
168+
retries: 10
169+
start_period: 60s
170+
restart: unless-stopped

tests/labs/test-lab-08-02.sh

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
#!/usr/bin/env bash
1+
#!/usr/bin/env bash
22
# test-lab-08-02.sh — Lab 08-02: External Dependencies
3-
# Module 08: Jitsi video conferencing
4-
# jitsi with external PostgreSQL, Redis, and network integration
3+
# Module 08: Jitsi — coturn TURN/STUN server, separate jitsi-net + turn-net
54
set -euo pipefail
65

76
LAB_ID="08-02"
@@ -11,7 +10,6 @@ COMPOSE_FILE="docker/docker-compose.lan.yml"
1110
PASS=0
1211
FAIL=0
1312

14-
# ── Colors ────────────────────────────────────────────────────────────────────
1513
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
1614
CYAN='\033[0;36m'; NC='\033[0m'
1715

@@ -29,30 +27,92 @@ echo ""
2927
# ── PHASE 1: Setup ────────────────────────────────────────────────────────────
3028
info "Phase 1: Setup"
3129
docker compose -f "${COMPOSE_FILE}" up -d
32-
info "Waiting 30s for ${MODULE} to initialize..."
33-
sleep 30
30+
info "Waiting for coturn TURN server..."
31+
timeout 30 bash -c 'until docker ps --filter name=jitsi-lan-coturn --filter status=running --format "{{.Names}}" | grep -q coturn; do sleep 2; done'
32+
info "Waiting for Jitsi web (HTTPS :8443)..."
33+
timeout 120 bash -c 'until curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" | grep -E "^(200|301|302)$"; do sleep 5; done'
3434

3535
# ── PHASE 2: Health Checks ────────────────────────────────────────────────────
3636
info "Phase 2: Health Checks"
3737

38-
if docker compose -f "${COMPOSE_FILE}" ps | grep -q "running\|Up"; then
39-
pass "Container is running"
38+
for c in jitsi-lan-coturn jitsi-lan-prosody jitsi-lan-jicofo jitsi-lan-jvb jitsi-lan-web; do
39+
if docker ps --filter "name=^/${c}$" --filter "status=running" --format '{{.Names}}' | grep -q "${c}"; then
40+
pass "Container ${c} is running"
41+
else
42+
fail "Container ${c} is not running"
43+
fi
44+
done
45+
46+
if timeout 5 bash -c 'echo > /dev/tcp/localhost/3478' 2>/dev/null; then
47+
pass "TURN server: TCP port 3478 reachable"
48+
else
49+
fail "TURN server: TCP port 3478 not reachable"
50+
fi
51+
52+
HTTP_CODE=$(curl -sk http://localhost:8180/ -o /dev/null -w "%{http_code}" 2>/dev/null || echo "000")
53+
if echo "${HTTP_CODE}" | grep -qE '^(200|301|302)$'; then
54+
pass "Jitsi web HTTP :8180 → ${HTTP_CODE}"
55+
else
56+
fail "Jitsi web HTTP :8180 → ${HTTP_CODE}"
57+
fi
58+
59+
HTTPS_CODE=$(curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" 2>/dev/null || echo "000")
60+
if echo "${HTTPS_CODE}" | grep -qE '^(200|301|302)$'; then
61+
pass "Jitsi web HTTPS :8443 → ${HTTPS_CODE}"
4062
else
41-
fail "Container is not running"
63+
fail "Jitsi web HTTPS :8443 → ${HTTPS_CODE}"
4264
fi
4365

4466
# ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
4567
info "Phase 3: Functional Tests (Lab 02 — External Dependencies)"
4668

47-
# TODO: Add module-specific functional tests here
48-
# Example:
49-
# if curl -sf http://localhost:443/health > /dev/null 2>&1; then
50-
# pass "Health endpoint responds"
51-
# else
52-
# fail "Health endpoint not reachable"
53-
# fi
69+
COTURN_LOG=$(docker logs jitsi-lan-coturn 2>&1 | tail -10 || echo "")
70+
if echo "${COTURN_LOG}" | grep -qi "turnserver\|Coturn\|listening"; then
71+
pass "coturn: TURN server started and logging"
72+
else
73+
warn "coturn: check logs manually"
74+
fi
5475

55-
warn "Functional tests for Lab 08-02 pending implementation"
76+
CERT_SUBJECT=$(echo | openssl s_client -connect localhost:8443 -servername localhost \
77+
2>/dev/null | openssl x509 -noout -subject 2>/dev/null | head -1 || echo "")
78+
if [ -n "${CERT_SUBJECT}" ]; then
79+
pass "TLS cert: present (${CERT_SUBJECT})"
80+
else
81+
warn "TLS cert: could not retrieve"
82+
fi
83+
84+
CONFIG_JS=$(curl -sk https://localhost:8443/config.js 2>/dev/null || echo "")
85+
if [ -n "${CONFIG_JS}" ]; then
86+
pass "config.js: served by Jitsi web"
87+
else
88+
fail "config.js: not reachable"
89+
fi
90+
91+
if echo "${CONFIG_JS}" | grep -q 'stunServers\|iceServers\|p2p'; then
92+
pass "config.js: STUN/ICE server config present"
93+
else
94+
warn "config.js: STUN/ICE config not detected"
95+
fi
96+
97+
# Key Lab 02 test: TURN config in config.js
98+
if echo "${CONFIG_JS}" | grep -qiE 'turn|coturn|TurnCredentials'; then
99+
pass "config.js: TURN configuration present"
100+
else
101+
warn "config.js: TURN config not found in config.js (may be injected at runtime)"
102+
fi
103+
104+
if curl -sk https://localhost:8443/external_api.js | grep -q 'JitsiMeetExternalAPI\|external_api'; then
105+
pass "external_api.js: Jitsi Meet External API available"
106+
else
107+
fail "external_api.js: not available"
108+
fi
109+
110+
JVB_LOG=$(docker logs jitsi-lan-jvb 2>&1 | tail -20 || echo "")
111+
if echo "${JVB_LOG}" | grep -qi "started\|running\|bridge"; then
112+
pass "JVB: started (log evidence)"
113+
else
114+
warn "JVB: could not confirm start from log"
115+
fi
56116

57117
# ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58118
info "Phase 4: Cleanup"
@@ -67,5 +127,5 @@ echo -e " ${GREEN}PASS: ${PASS}${NC} | ${RED}FAIL: ${FAIL}${NC}"
67127
echo -e "${CYAN}======================================${NC}"
68128

69129
if [ "${FAIL}" -gt 0 ]; then
70-
exit 1
71-
fi
130+
exit 1
131+
fi

0 commit comments

Comments
 (0)