-
-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
157 lines (141 loc) · 6.97 KB
/
Copy pathdocker-compose.yml
File metadata and controls
157 lines (141 loc) · 6.97 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
##############################################
# Web SSH Terminal - Homelab Docker Compose
#
# No .env file needed - edit values directly below
#
# BEFORE RUNNING:
# 1. SECRET_KEY is optional — auto-generated & persisted on first run.
# 2. Set CORS_ORIGINS to your domain (e.g. https://ssh.example.com)
# For homelab without TLS: http://your-server-ip:5000
# For wildcard (insecure): CORS_ORIGINS=* and ALLOW_CORS_WILDCARD=true
##############################################
services:
webssh:
image: ghcr.io/bifrost0x/webssh:latest
container_name: webssh
restart: unless-stopped
# Longer than the 30 s maximum in RUNTIME_SHUTDOWN_GRACE_SECONDS, so the
# lifecycle signal gate can cancel bounded work before Docker sends KILL.
stop_grace_period: 40s
ports:
- "5000:5000"
environment:
# This default file intentionally preserves HTTP-friendly homelab
# compatibility. For an Internet-facing deployment, layer
# docker-compose.production.yml on top.
- DEPLOYMENT_PROFILE=homelab
# === SECRET_KEY: OPTIONAL ===
# Left unset, a strong key is auto-generated on first run and persisted to
# the data volume below (/app/data/secret_key). Set it explicitly only if
# an external secret-management policy requires it or you are restoring
# data on another host. Multiple app replicas are not supported because
# live SSH state remains process-local:
# - SECRET_KEY=<paste output of: openssl rand -hex 32>
# === CORS: Wildcard default for homelab use ===
# For production: replace * with your domain (e.g. https://ssh.example.com)
# and remove ALLOW_CORS_WILDCARD
- CORS_ORIGINS=*
- ALLOW_CORS_WILDCARD=true
# === Set to 1 if behind reverse proxy (Traefik, nginx, etc.) ===
- TRUSTED_PROXIES=0
# === Subfolder deployment (optional) ===
# Set when serving the app under a URL subpath, e.g. https://server.local/webssh
# Requires: TRUSTED_PROXIES=1 above AND a reverse proxy that strips the
# prefix and forwards it via the X-Forwarded-Prefix header.
# Leave commented to run at the root — behavior is unchanged when unset.
# See README "Subfolder Deployment" section for nginx/Traefik/Caddy examples.
# - APPLICATION_ROOT=/webssh
# === Homelab HTTP compatibility ===
- SESSION_COOKIE_SECURE=false
# === First account and registration ===
# A fresh homelab install automatically opens /register. Exactly the
# first browser-created account becomes administrator; the one-time
# bootstrap closes as soon as that account exists.
# Uncomment to require the create-admin CLI even on a fresh homelab:
# - BOOTSTRAP_REGISTRATION_ENABLED=false
# Uncomment to keep normal self-registration open for additional users.
# It can also be toggled later from the Admin Panel.
# - REGISTRATION_ENABLED=true
# === Persistent remote sessions via tmux ===
# tmux must be installed on the remote SSH host. If it is unavailable,
# WebSSH automatically falls back to a regular shell.
- TMUX_ENABLED=true
- TMUX_DEFAULT=true
- TMUX_SESSION_PREFIX=webssh
# === Tailscale SSH (optional, shared node identity) ===
# Disabled by default. See docs/tailscale-ssh.md for the required
# authorization controls and a persistent Tailscale sidecar example.
# Before enabling, configure narrow target and remote-user allowlists.
# - TAILSCALE_SSH_ENABLED=true
# - TAILSCALE_SSH_ALLOWED_WEBSSH_USERS=operator
# - TAILSCALE_SSH_ALLOWED_TARGETS=tiny-server,100.64.0.10
# - TAILSCALE_SSH_ALLOWED_REMOTE_USERS=root,ubuntu
# === Built-in security features ===
# Host-key management, recovery codes, and audit export/retention are
# enabled by default. Uncomment only when intentionally disabling one.
# - HOST_KEY_MANAGEMENT_ENABLED=false
# - RECOVERY_CODES_ENABLED=false
# - AUDIT_EXPORT_ENABLED=false
# Internal-target blocking is useful for exposed multi-user deployments,
# but remains off here because homelabs commonly connect to private IPs.
# - BLOCK_INTERNAL_SSH=true
# === Native web backup and restore ===
# Always available to administrators. Restore always requires two
# confirmations plus the current administrator password. Temporary
# snapshots and uploaded archives use an instance-specific namespace
# outside /app/data and expire.
# Override operational limits only when the defaults do not fit.
# - BACKUP_UPLOAD_MAX_SIZE=1073741824
# - BACKUP_OPERATION_TIMEOUT=1800
# - BACKUP_DOWNLOAD_TTL=600
# - BACKUP_TEMP_DIR=/tmp/webssh-backup-operations
# === Passkeys and OIDC (optional, disabled by default) ===
# Passkeys require the exact public browser domain and origin.
# - WEBAUTHN_ENABLED=true
# - WEBAUTHN_RP_ID=ssh.example.com
# - WEBAUTHN_RP_NAME=WebSSH
# - WEBAUTHN_ORIGIN=https://ssh.example.com
# OIDC additionally requires a read-only client-secret file mounted into
# the container. Accounts are linked by issuer + subject in Admin.
# - OIDC_ENABLED=true
# - OIDC_ISSUER=https://idp.example.com
# - OIDC_CLIENT_ID=webssh
# - OIDC_CLIENT_SECRET_FILE=/run/secrets/webssh_oidc_client_secret
# - OIDC_REDIRECT_URI=https://ssh.example.com/oidc/callback
# - OIDC_ALLOWED_SUBJECTS=
# - OIDC_ALLOWED_DOMAINS=example.com
# - OIDC_LOGIN_RATE_LIMIT=10 per minute
# === Optional: Usually no changes needed ===
# The image already supplies DEBUG=false, HOST=0.0.0.0, PORT=5000, and
# DATA_DIR=/app/data. Leave those defaults untouched for normal use.
# Native gthread runtime: keep one worker. Socket admission leaves
# request threads available for HTTP routes and file transfers.
# - GUNICORN_THREADS=64
# - MAX_SOCKET_CONNECTIONS=48
# - MAX_SOCKET_CONNECTIONS_PER_USER=8
# === Redis-backed rate limiting (optional) ===
# Uncomment the two lines below AND the redis service section at the
# bottom of this file to preserve counters across app restarts while
# Redis keeps running. The app must still use exactly one worker because
# live SSH state remains in-process.
# - RATELIMIT_STORAGE_URL=redis://redis:6379/0
# depends_on:
# - redis
volumes:
- webssh_data:/app/data
healthcheck:
test: ["CMD", "python", "-c", "import os, urllib.request; urllib.request.urlopen('http://127.0.0.1:' + os.getenv('PORT', '5000') + '/ready', timeout=2).read(1)"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
# Redis (optional - uncomment for external rate-limit counters)
# redis:
# image: redis:7-alpine
# container_name: webssh-redis
# restart: unless-stopped
# # Only expose to the internal Docker network; no host port needed.
# command: ["redis-server", "--save", "", "--appendonly", "no"]
volumes:
webssh_data:
driver: local