Skip to content

Commit 7d785de

Browse files
MohsinHashmi-DataInnmohsin-wiserclaude
authored
feat: add https with let's encrypt for devcontainer proxy (#391)
* feat: add https with let's encrypt for devcontainer proxy - Add Let's Encrypt certificate resolver to Traefik configuration - Add HTTP to HTTPS redirect for all services - Update devcontainer routers to use websecure entrypoint with TLS - Add persistent volume for Let's Encrypt certificates - Fix code-server startup by unsetting VSCODE_IPC_HOOK_CLI - Update post-start.sh to show HTTPS URLs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: use per-router https redirect to preserve local domain http access - Remove blanket HTTP→HTTPS redirect from Traefik entrypoint - Add redirect middleware per-router for nip.io domains only - Local domain routes (*.dev.simpleaccounts.local) remain HTTP-only - Fixes issue where local domain routes became unreachable 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Mohsin Hashmi <mhashmi@wiser.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 99d7faf commit 7d785de

3 files changed

Lines changed: 51 additions & 12 deletions

File tree

.devcontainer/docker-compose.yml

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,46 @@ services:
7070
labels:
7171
- 'traefik.enable=true'
7272
- 'traefik.docker.network=dev-proxy-network'
73-
# Frontend routing (port 3000)
73+
# ============= HTTPS redirect middleware (for nip.io domains only) =============
74+
- 'traefik.http.middlewares.${USER:-devuser}-https-redirect.redirectscheme.scheme=https'
75+
- 'traefik.http.middlewares.${USER:-devuser}-https-redirect.redirectscheme.permanent=true'
76+
# ============= Frontend routing (port 3000) =============
77+
# HTTP router (redirects to HTTPS)
78+
- 'traefik.http.routers.${USER:-devuser}-frontend-http.rule=HostRegexp(`${USER:-devuser}.{ip:[0-9-]+}.nip.io`)'
79+
- 'traefik.http.routers.${USER:-devuser}-frontend-http.entrypoints=web'
80+
- 'traefik.http.routers.${USER:-devuser}-frontend-http.middlewares=${USER:-devuser}-https-redirect'
81+
# HTTPS router with Let's Encrypt
7482
- 'traefik.http.routers.${USER:-devuser}-frontend.rule=HostRegexp(`${USER:-devuser}.{ip:[0-9-]+}.nip.io`)'
75-
- 'traefik.http.routers.${USER:-devuser}-frontend.entrypoints=web'
83+
- 'traefik.http.routers.${USER:-devuser}-frontend.entrypoints=websecure'
84+
- 'traefik.http.routers.${USER:-devuser}-frontend.tls=true'
85+
- 'traefik.http.routers.${USER:-devuser}-frontend.tls.certresolver=letsencrypt'
7686
- 'traefik.http.routers.${USER:-devuser}-frontend.service=${USER:-devuser}-frontend'
7787
- 'traefik.http.services.${USER:-devuser}-frontend.loadbalancer.server.port=3000'
78-
# Backend API routing (port 8080)
88+
# ============= Backend API routing (port 8080) =============
89+
# HTTP router (redirects to HTTPS)
90+
- 'traefik.http.routers.${USER:-devuser}-api-http.rule=HostRegexp(`${USER:-devuser}-api.{ip:[0-9-]+}.nip.io`)'
91+
- 'traefik.http.routers.${USER:-devuser}-api-http.entrypoints=web'
92+
- 'traefik.http.routers.${USER:-devuser}-api-http.middlewares=${USER:-devuser}-https-redirect'
93+
# HTTPS router with Let's Encrypt
7994
- 'traefik.http.routers.${USER:-devuser}-api.rule=HostRegexp(`${USER:-devuser}-api.{ip:[0-9-]+}.nip.io`)'
80-
- 'traefik.http.routers.${USER:-devuser}-api.entrypoints=web'
95+
- 'traefik.http.routers.${USER:-devuser}-api.entrypoints=websecure'
96+
- 'traefik.http.routers.${USER:-devuser}-api.tls=true'
97+
- 'traefik.http.routers.${USER:-devuser}-api.tls.certresolver=letsencrypt'
8198
- 'traefik.http.routers.${USER:-devuser}-api.service=${USER:-devuser}-api'
8299
- 'traefik.http.services.${USER:-devuser}-api.loadbalancer.server.port=8080'
83-
# Code-server / Web IDE routing (port 8443)
100+
# ============= Code-server / Web IDE routing (port 8443) =============
101+
# HTTP router (redirects to HTTPS)
102+
- 'traefik.http.routers.${USER:-devuser}-ide-http.rule=HostRegexp(`${USER:-devuser}-ide.{ip:[0-9-]+}.nip.io`)'
103+
- 'traefik.http.routers.${USER:-devuser}-ide-http.entrypoints=web'
104+
- 'traefik.http.routers.${USER:-devuser}-ide-http.middlewares=${USER:-devuser}-https-redirect'
105+
# HTTPS router with Let's Encrypt
84106
- 'traefik.http.routers.${USER:-devuser}-ide.rule=HostRegexp(`${USER:-devuser}-ide.{ip:[0-9-]+}.nip.io`)'
85-
- 'traefik.http.routers.${USER:-devuser}-ide.entrypoints=web'
107+
- 'traefik.http.routers.${USER:-devuser}-ide.entrypoints=websecure'
108+
- 'traefik.http.routers.${USER:-devuser}-ide.tls=true'
109+
- 'traefik.http.routers.${USER:-devuser}-ide.tls.certresolver=letsencrypt'
86110
- 'traefik.http.routers.${USER:-devuser}-ide.service=${USER:-devuser}-ide'
87111
- 'traefik.http.services.${USER:-devuser}-ide.loadbalancer.server.port=8443'
88-
# Local domain routing
112+
# ============= Local domain routing (HTTP only, no redirect) =============
89113
- 'traefik.http.routers.${USER:-devuser}-frontend-local.rule=Host(`${USER:-devuser}.dev.simpleaccounts.local`)'
90114
- 'traefik.http.routers.${USER:-devuser}-frontend-local.entrypoints=web'
91115
- 'traefik.http.routers.${USER:-devuser}-frontend-local.service=${USER:-devuser}-frontend'

.devcontainer/post-start.sh

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ CONFIGEOF
7171

7272
if ! pgrep -x "code-server" > /dev/null; then
7373
echo "🌐 Starting code-server (Web IDE)..."
74-
nohup code-server /workspaces/SimpleAccounts-UAE > /tmp/code-server.log 2>&1 &
74+
# Unset VSCODE_IPC_HOOK_CLI to prevent code-server from connecting to existing VS Code/Cursor instance
75+
(unset VSCODE_IPC_HOOK_CLI; nohup code-server /workspaces/SimpleAccounts-UAE > /tmp/code-server.log 2>&1 &)
7576
echo "✅ Code-server started on port 8443 (password protected)"
7677
else
7778
echo "✅ Code-server already running"
@@ -170,13 +171,15 @@ echo "━━━━━━━━━━━━━━━━━━━━━━━━
170171

171172
if [ "$TRAEFIK_ENABLED" = true ]; then
172173
echo ""
173-
echo "🌐 Shareable URLs (via Traefik):"
174+
echo "🌐 Shareable URLs (via Traefik with HTTPS):"
174175
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
175-
echo " Frontend: http://${DEV_USER}.${NIP_IP}.nip.io"
176-
echo " Backend: http://${DEV_USER}-api.${NIP_IP}.nip.io"
177-
echo " Web IDE: http://${DEV_USER}-ide.${NIP_IP}.nip.io"
176+
echo " Frontend: https://${DEV_USER}.${NIP_IP}.nip.io"
177+
echo " Backend: https://${DEV_USER}-api.${NIP_IP}.nip.io"
178+
echo " Web IDE: https://${DEV_USER}-ide.${NIP_IP}.nip.io"
178179
echo " Dashboard: http://proxy.${NIP_IP}.nip.io:8090"
179180
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
181+
echo ""
182+
echo "🔒 SSL certificates are automatically provisioned by Let's Encrypt"
180183
else
181184
echo ""
182185
echo "📡 Local Development (use port forwarding):"

.devcontainer/proxy/docker-compose.proxy.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ services:
4040
# Entrypoints
4141
- '--entrypoints.web.address=:80'
4242
- '--entrypoints.websecure.address=:443'
43+
# NOTE: No blanket HTTP→HTTPS redirect here to preserve local domain HTTP access
44+
# HTTPS redirect is handled per-router via middleware for nip.io domains only
45+
# Let's Encrypt Certificate Resolver
46+
- '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
47+
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web'
48+
- '--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL:-admin@simpleaccounts.io}'
49+
- '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json'
4350
# Logs
4451
- '--log.level=INFO'
4552
- '--accesslog=true'
@@ -49,6 +56,7 @@ services:
4956
- '8090:8080' # Traefik dashboard
5057
volumes:
5158
- /var/run/docker.sock:/var/run/docker.sock:ro
59+
- letsencrypt:/letsencrypt
5260
networks:
5361
- dev-proxy-network
5462
labels:
@@ -66,3 +74,7 @@ networks:
6674
dev-proxy-network:
6775
name: dev-proxy-network
6876
driver: bridge
77+
78+
volumes:
79+
letsencrypt:
80+
name: traefik-letsencrypt

0 commit comments

Comments
 (0)