fix(docker): align container runtime with core tunnel flow (#661)

* fix(docker): align runtime with core startup flow

* docs: update tunnel and daemon usage examples

* docs: clarify managed-local tunnel config paths in Docker
This commit is contained in:
Iuliia Ivashko
2026-03-15 00:12:11 +02:00
committed by GitHub
parent e57f17996f
commit 1f8e875357
7 changed files with 84 additions and 55 deletions
+6
View File
@@ -18,3 +18,9 @@ yarn-error.log*
pnpm-debug.log*
.env
.env.*
.opencode
data
workspaces
packages/desktop/src-tauri
packages/desktop/target
packages/intellij
+5
View File
@@ -51,3 +51,8 @@ packages/intellij/
# OS
Thumbs.db
# Local runtime state (docker/dev)
data/
workspaces/
*.pid
+18 -12
View File
@@ -1,11 +1,7 @@
# syntax=docker/dockerfile:1
FROM archlinux:latest AS base
FROM oven/bun:1 AS base
WORKDIR /app
# Install build dependencies in base stage
RUN pacman -Sy --noconfirm --needed bun && \
pacman -Scc --noconfirm
FROM base AS deps
WORKDIR /app
COPY package.json bun.lock ./
@@ -20,15 +16,26 @@ WORKDIR /app
COPY . .
RUN bun run build:web
FROM base AS runtime
FROM oven/bun:1 AS runtime
WORKDIR /home/openchamber
RUN pacman -Sy --noconfirm --needed base-devel python openssh cloudflared git nodejs npm less && \
pacman -Scc --noconfirm
RUN apt-get update && apt-get install -y --no-install-recommends \
bash \
ca-certificates \
git \
less \
nodejs \
npm \
openssh-client \
python3 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=cloudflare/cloudflared:latest /usr/local/bin/cloudflared /usr/local/bin/cloudflared
ENV NODE_ENV=production
# Create openchamber user
RUN useradd -m -s /bin/bash openchamber
RUN useradd -m -s /bin/bash openchamber && mkdir -p /home/openchamber && chown -R openchamber:openchamber /home/openchamber
# Switch to openchamber user
USER openchamber
@@ -40,7 +47,6 @@ RUN npm config set prefix /home/openchamber/.npm-global && mkdir -p /home/opench
mkdir -p /home/openchamber/.local /home/openchamber/.config /home/openchamber/.ssh && \
npm install -g opencode-ai
WORKDIR /home/openchamber
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/packages/web/node_modules ./packages/web/node_modules
COPY --from=builder /app/package.json ./package.json
@@ -48,8 +54,8 @@ COPY --from=builder /app/packages/web/package.json ./packages/web/package.json
COPY --from=builder /app/packages/web/bin ./packages/web/bin
COPY --from=builder /app/packages/web/server ./packages/web/server
COPY --from=builder /app/packages/web/dist ./packages/web/dist
COPY --chmod=755 scripts/docker-entrypoint.sh /app/openchamber-entrypoint.sh
COPY scripts/docker-entrypoint.sh /home/openchamber/openchamber-entrypoint.sh
EXPOSE 3000
ENTRYPOINT ["/app/openchamber-entrypoint.sh"]
ENTRYPOINT ["sh", "/home/openchamber/openchamber-entrypoint.sh"]
+20 -16
View File
@@ -106,7 +106,7 @@ _requires Node.js 20+_
```bash
curl -fsSL https://raw.githubusercontent.com/btriapitsyn/openchamber/main/scripts/install.sh | bash
openchamber --ui-password be-creative-here --daemon
openchamber --ui-password be-creative-here
```
<details>
@@ -153,27 +153,31 @@ environment:
UI_PASSWORD: your_secure_password
```
**Cloudflare Tunnel:**
**Cloudflare Tunnel (optional):**
```yaml
environment:
CF_TUNNEL: "true" # Options: true, qr, password
OPENCHAMBER_TUNNEL_MODE: quick # quick | managed-remote | managed-local
OPENCHAMBER_TUNNEL_PROVIDER: cloudflare
```
| Value | Description |
| ---------- | ------------------------------- |
| `true` | Enable tunnel only |
| `qr` | Enable tunnel + QR code |
| `password` | Enable tunnel + password in URL |
For `managed-remote` mode, provide:
### Managed Cloudflare Tunnel (persistent hostname)
```yaml
environment:
OPENCHAMBER_TUNNEL_MODE: managed-remote
OPENCHAMBER_TUNNEL_HOSTNAME: app.example.com
OPENCHAMBER_TUNNEL_TOKEN: <token>
```
OpenChamber also supports managed-remote mode for more reliable long-lived access with your Cloudflare account and custom hostname.
For `managed-local` mode, optionally provide:
- Configure it in-app at **Settings -> OpenChamber -> Tunnel** and switch mode to **Managed Remote Tunnel**.
- Managed-remote tunnels require a domain in your Cloudflare account.
- Cloudflare setup guide: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/create-remote-tunnel/
- Managed-local mode uses your local cloudflared config, for example:
- `openchamber tunnel start --provider cloudflare --mode managed-local --config ~/.cloudflared/config.yml`
```yaml
environment:
OPENCHAMBER_TUNNEL_MODE: managed-local
OPENCHAMBER_TUNNEL_CONFIG: /home/openchamber/.cloudflared/config.yml
```
Managed-local path note: `OPENCHAMBER_TUNNEL_CONFIG` must point to a path inside the container user home (`/home/openchamber/...`). If your Cloudflare config references a credentials JSON file, that file path must also be accessible inside the container (mount with `volumes`).
### Tunnel behavior notes
@@ -237,7 +241,7 @@ chown -R 1000:1000 data/
<details>
<summary><strong>Web / PWA</strong></summary>
- Cloudflare tunnel with Quick and Named modes, secure one-time connect links, and QR onboarding
- Cloudflare tunnel with quick, managed-remote, and managed-local modes, secure one-time connect links, and QR onboarding
- Mobile-first: optimized chat controls, keyboard-safe layouts, drag-to-reorder projects
- Background notifications and cross-tab session tracking
- Self-update + restart flow that keeps your server settings intact
+5 -1
View File
@@ -17,7 +17,11 @@ services:
- ./workspaces:/home/openchamber/workspaces
#environment:
# UI_PASSWORD: your_secure_password_here # Uncomment to set UI password
# CF_TUNNEL: true # Enable Cloudflare Tunnel (true/qr/password)
# OPENCHAMBER_TUNNEL_PROVIDER: cloudflare
# OPENCHAMBER_TUNNEL_MODE: quick # quick | managed-remote | managed-local
# OPENCHAMBER_TUNNEL_HOSTNAME: app.example.com # required for managed-remote
# OPENCHAMBER_TUNNEL_TOKEN: your_cloudflare_token # required for managed-remote
# OPENCHAMBER_TUNNEL_CONFIG: /home/openchamber/.cloudflared/config.yml # optional for managed-local
# OH_MY_OPENCODE: true # enable oh-my-opencode
# OPENCODE_HOST: http://172.17.0.1:4096 # Connect to external OpenCode server
# OPENCODE_SKIP_START: true # skip start opencode
+23 -3
View File
@@ -50,9 +50,29 @@ openchamber update # Update to latest version
```yaml
environment:
UI_PASSWORD: your_secure_password
CF_TUNNEL: "true" # Options: true, qr, password
OPENCHAMBER_TUNNEL_MODE: quick # quick | managed-remote | managed-local
OPENCHAMBER_TUNNEL_PROVIDER: cloudflare
```
For `managed-remote` mode, also set:
```yaml
environment:
OPENCHAMBER_TUNNEL_MODE: managed-remote
OPENCHAMBER_TUNNEL_HOSTNAME: app.example.com
OPENCHAMBER_TUNNEL_TOKEN: <token>
```
For `managed-local` mode, you can set:
```yaml
environment:
OPENCHAMBER_TUNNEL_MODE: managed-local
OPENCHAMBER_TUNNEL_CONFIG: /home/openchamber/.cloudflared/config.yml
```
Managed-local path note: `OPENCHAMBER_TUNNEL_CONFIG` must use a container path under `/home/openchamber/...`. If the config file references `credentials-file`, ensure that JSON path is also mounted and reachable inside the container.
**Data directory:** mount `data/` for persistent storage. Ensure permissions:
```bash
mkdir -p data/openchamber data/opencode/share data/opencode/config data/ssh
@@ -65,7 +85,7 @@ chown -R 1000:1000 data/
<summary>Background & daemon mode</summary>
```bash
openchamber --daemon # Run in background
openchamber # Runs in background by default
openchamber stop # Stop background server
```
@@ -79,7 +99,7 @@ openchamber stop # Stop background server
- **Self-update** - update and restart from the UI, server settings stay intact
- **Cross-tab tracking** - session activity stays in sync across browser tabs
- Cloudflare tunnel access with Quick, managed-remote, and managed-local modes
- Cloudflare tunnel access with quick, managed-remote, and managed-local modes
- One-scan onboarding with tunnel QR + password URL helpers
- Mobile-first experience: optimized chat controls, keyboard-safe layouts, and attachment-friendly UI
- Background notifications plus reliable cross-tab session activity tracking
+7 -23
View File
@@ -36,30 +36,9 @@ fi
echo "[entrypoint] SSH public key:"
cat "${SSH_PUBLIC_KEY_PATH}"
# Handle UI_PASSWORD environment variable
OPENCHAMBER_ARGS=""
# Handle UI password environment variable
if [ -n "${UI_PASSWORD:-}" ]; then
echo "[entrypoint] UI password set, enabling authentication"
OPENCHAMBER_ARGS="${OPENCHAMBER_ARGS} --ui-password ${UI_PASSWORD}"
fi
# Handle Cloudflare Tunnel (CF_TUNNEL: true/qr/password/full)
if [ -n "${CF_TUNNEL:-}" ] && [ "${CF_TUNNEL:-false}" != "false" ]; then
echo "[entrypoint] Cloudflare Tunnel enabled (${CF_TUNNEL})"
OPENCHAMBER_ARGS="${OPENCHAMBER_ARGS} --try-cf-tunnel"
case "${CF_TUNNEL}" in
"qr")
OPENCHAMBER_ARGS="${OPENCHAMBER_ARGS} --tunnel-qr"
;;
esac
case "${CF_TUNNEL}" in
"password")
OPENCHAMBER_ARGS="${OPENCHAMBER_ARGS} --tunnel-password-url"
;;
esac
fi
if [ "${OH_MY_OPENCODE:-false}" = "true" ]; then
@@ -82,5 +61,10 @@ if [ "$#" -gt 0 ]; then
exec "$@"
fi
bun packages/web/bin/cli.js ${OPENCHAMBER_ARGS}
set -- bun packages/web/bin/cli.js
if [ -n "${UI_PASSWORD:-}" ]; then
set -- "$@" --ui-password "$UI_PASSWORD"
fi
"$@"
bun packages/web/bin/cli.js logs