You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: surfsense_web/content/docs/docker-installation/dev-compose.mdx
+8-1Lines changed: 8 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,11 @@ cd SurfSense/docker
10
10
docker compose -f docker-compose.dev.yml up --build
11
11
```
12
12
13
-
This file builds the backend and frontend from your local source code (instead of pulling prebuilt images) and includes pgAdmin for database inspection at [http://localhost:5050](http://localhost:5050). Use the production `docker-compose.yml` for all other cases.
13
+
This file builds the backend and frontend from your local source code (instead
14
+
of pulling prebuilt images) and includes pgAdmin for database inspection at
15
+
[http://localhost:5050](http://localhost:5050). It intentionally keeps raw
16
+
frontend, backend, and zero-cache ports published for debugging. Use the
17
+
production `docker-compose.yml` for the default Caddy single-origin setup.
14
18
15
19
## Dev-Only Environment Variables
16
20
@@ -28,3 +32,6 @@ The following `.env` variables are **only used by the dev compose file** (they h
28
32
|`NEXT_PUBLIC_DEPLOYMENT_MODE`| Frontend build arg for deployment mode |`self-hosted`|
29
33
30
34
In the production compose file, the `NEXT_PUBLIC_*` frontend variables are automatically derived from `AUTH_TYPE`, `ETL_SERVICE`, and the port settings. In the dev compose file, they are passed as build args since the frontend is built from source.
35
+
Production Docker exposes only the bundled Caddy proxy by default; dev compose
36
+
keeps direct service ports so contributors can inspect and restart individual
@@ -99,24 +99,59 @@ docker run -d --name watchtower \
99
99
100
100
SurfSense containers are labeled for Watchtower, so `--label-enable` limits updates to the SurfSense services.
101
101
102
-
### Ports
102
+
### Public URL and Ports
103
103
104
104
| Variable | Description | Default |
105
105
|----------|-------------|---------|
106
-
|`FRONTEND_PORT`| Frontend service port |`3929`|
107
-
|`BACKEND_PORT`| Backend API service port |`8929`|
108
-
|`ZERO_CACHE_PORT`| Zero-cache real-time sync port |`5929`|
106
+
|`SURFSENSE_PUBLIC_URL`| Public origin used by the frontend, backend OAuth callbacks, and Zero browser URL |`http://localhost:3929`|
107
+
|`SURFSENSE_SITE_ADDRESS`| Caddy site address. `:80` means local plain HTTP; a hostname enables automatic HTTPS |`:80`|
108
+
|`LISTEN_HTTP_PORT`| Host port mapped to Caddy's HTTP listener |`3929`|
109
+
|`LISTEN_HTTPS_PORT`| Host port mapped to Caddy's HTTPS listener for domain mode |`443`|
109
110
110
-
### Custom Domain / Reverse Proxy
111
+
SurfSense includes Caddy by default. The `frontend`, `backend`, and
112
+
`zero-cache` containers are internal-only in the production compose file; the
113
+
browser reaches them through Caddy path routing.
111
114
112
-
Only set these if serving SurfSense on a real domain via a reverse proxy (Caddy, Nginx, Cloudflare Tunnel, etc.). Leave commented out for standard localhost deployments.
115
+
### Custom Domain / Automatic HTTPS
116
+
117
+
For a real domain, point DNS at the Docker host and set:
118
+
119
+
```dotenv
120
+
SURFSENSE_SITE_ADDRESS=surf.example.com
121
+
LISTEN_HTTP_PORT=80
122
+
LISTEN_HTTPS_PORT=443
123
+
CERT_EMAIL=you@example.com
124
+
SURFSENSE_PUBLIC_URL=https://surf.example.com
125
+
```
126
+
127
+
Caddy will issue and renew Let's Encrypt certificates automatically. Ports 80
128
+
and 443 must be reachable from the internet for the default HTTP-01 challenge.
113
129
114
130
| Variable | Description |
115
131
|----------|-------------|
116
-
|`NEXT_FRONTEND_URL`| Public frontend URL (e.g. `https://app.yourdomain.com`) |
117
-
|`BACKEND_URL`| Public backend URL for OAuth callbacks (e.g. `https://api.yourdomain.com`) |
118
-
|`NEXT_PUBLIC_FASTAPI_BACKEND_URL`| Backend URL used by the frontend (e.g. `https://api.yourdomain.com`) |
119
-
|`NEXT_PUBLIC_ZERO_CACHE_URL`| Zero-cache URL used by the frontend (e.g. `https://zero.yourdomain.com`) |
132
+
|`CERT_EMAIL`| Optional ACME contact email |
133
+
|`CERT_ACME_CA`| ACME directory URL; use Let's Encrypt staging when testing cert issuance |
134
+
|`CERT_ACME_DNS`| DNS-01 challenge config; requires the custom Caddy build |
135
+
|`TRUSTED_PROXIES`| CIDR ranges trusted for forwarded client IP headers |
136
+
|`SURFSENSE_MAX_BODY_SIZE`| Upload limit enforced at the proxy |
137
+
138
+
### Bring Your Own Proxy
139
+
140
+
If you already run nginx, Traefik, Cloudflare Tunnel, or another ingress, you
141
+
can comment out the `proxy` service and route traffic to the internal services
142
+
with the same path contract:
143
+
144
+
| Public path | Upstream |
145
+
|-------------|----------|
146
+
|`/auth/*`|`backend:8000`|
147
+
|`/api/v1/*`|`backend:8000`|
148
+
|`/zero/*`|`zero-cache:4848`|
149
+
|`/*`|`frontend:3000`|
150
+
151
+
Alternative proxies must preserve WebSocket upgrades for `/zero`, avoid
152
+
buffering streaming responses, allow long-running requests, and support large
153
+
uploads. For DNS-01 or wildcard certificates with Caddy, build
154
+
`docker/proxy/Dockerfile` and set `CERT_ACME_DNS` for your DNS provider.
120
155
121
156
### Zero-cache (Real-Time Sync)
122
157
@@ -165,7 +200,10 @@ Create credentials at the [Google Cloud Console](https://console.cloud.google.co
165
200
166
201
### Connector OAuth Keys
167
202
168
-
Uncomment the connectors you want to use. Redirect URIs follow the pattern `http://localhost:8000/api/v1/auth/<connector>/connector/callback`.
203
+
Uncomment the connectors you want to use. Redirect URIs follow the single-origin
|`zero-cache`| Rocicorp Zero real-time sync (replicates Postgres to clients) |
229
-
|`frontend`| Next.js web application |
268
+
|`frontend`| Next.js web application, internal behind Caddy|
230
269
231
270
All services start automatically with `docker compose up -d`.
232
271
@@ -292,9 +331,9 @@ docker compose down -v
292
331
293
332
## Troubleshooting
294
333
295
-
-**Ports already in use**: Change the relevant `*_PORT` variable in `.env` and restart.
334
+
-**Port already in use**: Change `LISTEN_HTTP_PORT`in `.env` and restart. In domain mode, use ports `80` and `443` so Caddy can complete certificate issuance.
296
335
-**Permission errors on Linux**: You may need to prefix `docker` commands with `sudo`.
297
-
-**Real-time updates not working**: Open DevTools → Console and check for WebSocket errors. Verify `NEXT_PUBLIC_ZERO_CACHE_URL` matches the running zero-cache address.
336
+
-**Real-time updates not working**: Open DevTools → Console and check for WebSocket errors. In production Docker the expected URL is `${SURFSENSE_PUBLIC_URL}/zero`.
298
337
-**Line ending issues on Windows**: Run `git config --global core.autocrlf true` before cloning.
Copy file name to clipboardExpand all lines: surfsense_web/content/docs/how-to/zero-sync.mdx
+8-4Lines changed: 8 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,10 +32,10 @@ zero-cache is included in the Docker Compose setup. The key environment variable
32
32
33
33
| Variable | Description | Default |
34
34
|----------|-------------|---------|
35
-
|`ZERO_CACHE_PORT`|Port for the zero-cache service |`5929` (prod) / `4848` (dev)|
35
+
|`SURFSENSE_PUBLIC_URL`|Public SurfSense origin used by the browser |`http://localhost:3929`|
36
36
|`ZERO_ADMIN_PASSWORD`| Password for the zero-cache admin UI and `/statz` endpoint |`surfsense-zero-admin`|
37
37
|`ZERO_UPSTREAM_DB`| PostgreSQL connection URL for replication | Built from `DB_*` vars |
38
-
|`NEXT_PUBLIC_ZERO_CACHE_URL`| URL the frontend uses to connect to zero-cache |`http://localhost:<ZERO_CACHE_PORT>`|
38
+
|`NEXT_PUBLIC_ZERO_CACHE_URL`| URL the frontend uses to connect to zero-cache |`${SURFSENSE_PUBLIC_URL}/zero`|
39
39
|`ZERO_APP_PUBLICATIONS`| PostgreSQL publication restricting which tables are replicated |`zero_publication`|
40
40
|`ZERO_NUM_SYNC_WORKERS`| Number of view-sync worker processes. Must be ≤ `ZERO_UPSTREAM_MAX_CONNS` and ≤ `ZERO_CVR_MAX_CONNS`|`4`|
41
41
|`ZERO_UPSTREAM_MAX_CONNS`| Max connections to upstream PostgreSQL for mutations |`20`|
@@ -71,7 +71,11 @@ For the full manual setup walkthrough, see the [Manual Installation guide](/docs
71
71
72
72
### Custom Domain / Reverse Proxy
73
73
74
-
When deploying behind a reverse proxy, set `NEXT_PUBLIC_ZERO_CACHE_URL` to your public zero-cache URL (e.g., `https://zero.yourdomain.com`). The zero-cache service must be accessible via WebSocket from the browser.
74
+
The production Docker stack includes Caddy by default. Zero is exposed under the
75
+
same public origin as the app at `${SURFSENSE_PUBLIC_URL}/zero`, for example
76
+
`https://surf.example.com/zero`. Zero accepts this single path-component base
77
+
URL, so Caddy forwards `/zero/*` to the internal `zero-cache:4848` service
78
+
without stripping the prefix.
75
79
76
80
### Database Requirements
77
81
@@ -110,7 +114,7 @@ Zero syncs the following tables for real-time features:
110
114
111
115
-**zero-cache not starting**: Check `docker compose logs zero-cache`. Ensure PostgreSQL has `wal_level=logical` (configured in `postgresql.conf`).
112
116
-**"Insufficient upstream connections" error**: zero-cache defaults `ZERO_NUM_SYNC_WORKERS` to the number of CPU cores, which can exceed connection pool limits on high-core machines. Lower `ZERO_NUM_SYNC_WORKERS` or raise `ZERO_UPSTREAM_MAX_CONNS` / `ZERO_CVR_MAX_CONNS` in your `.env`.
113
-
-**Frontend not syncing**: Open DevTools → Console and check for WebSocket connection errors. Verify `NEXT_PUBLIC_ZERO_CACHE_URL`matches the running zero-cache address.
117
+
-**Frontend not syncing**: Open DevTools → Console and check for WebSocket connection errors. In production Docker, verify `NEXT_PUBLIC_ZERO_CACHE_URL`resolves to `${SURFSENSE_PUBLIC_URL}/zero`.
114
118
-**Stale data after restart**: zero-cache rebuilds its SQLite replica from PostgreSQL on startup. This may take a moment for large databases.
0 commit comments