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:
@@ -18,3 +18,9 @@ yarn-error.log*
|
|||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
.opencode
|
||||||
|
data
|
||||||
|
workspaces
|
||||||
|
packages/desktop/src-tauri
|
||||||
|
packages/desktop/target
|
||||||
|
packages/intellij
|
||||||
|
|||||||
@@ -51,3 +51,8 @@ packages/intellij/
|
|||||||
|
|
||||||
# OS
|
# OS
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
# Local runtime state (docker/dev)
|
||||||
|
data/
|
||||||
|
workspaces/
|
||||||
|
*.pid
|
||||||
|
|||||||
+18
-12
@@ -1,11 +1,7 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
FROM archlinux:latest AS base
|
FROM oven/bun:1 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install build dependencies in base stage
|
|
||||||
RUN pacman -Sy --noconfirm --needed bun && \
|
|
||||||
pacman -Scc --noconfirm
|
|
||||||
|
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package.json bun.lock ./
|
COPY package.json bun.lock ./
|
||||||
@@ -20,15 +16,26 @@ WORKDIR /app
|
|||||||
COPY . .
|
COPY . .
|
||||||
RUN bun run build:web
|
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 && \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
pacman -Scc --noconfirm
|
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
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
# Create openchamber user
|
# 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
|
# Switch to openchamber user
|
||||||
USER openchamber
|
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 && \
|
mkdir -p /home/openchamber/.local /home/openchamber/.config /home/openchamber/.ssh && \
|
||||||
npm install -g opencode-ai
|
npm install -g opencode-ai
|
||||||
|
|
||||||
WORKDIR /home/openchamber
|
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY --from=deps /app/packages/web/node_modules ./packages/web/node_modules
|
COPY --from=deps /app/packages/web/node_modules ./packages/web/node_modules
|
||||||
COPY --from=builder /app/package.json ./package.json
|
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/bin ./packages/web/bin
|
||||||
COPY --from=builder /app/packages/web/server ./packages/web/server
|
COPY --from=builder /app/packages/web/server ./packages/web/server
|
||||||
COPY --from=builder /app/packages/web/dist ./packages/web/dist
|
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
|
EXPOSE 3000
|
||||||
|
|
||||||
ENTRYPOINT ["/app/openchamber-entrypoint.sh"]
|
ENTRYPOINT ["sh", "/home/openchamber/openchamber-entrypoint.sh"]
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ _requires Node.js 20+_
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/btriapitsyn/openchamber/main/scripts/install.sh | 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>
|
<details>
|
||||||
@@ -153,27 +153,31 @@ environment:
|
|||||||
UI_PASSWORD: your_secure_password
|
UI_PASSWORD: your_secure_password
|
||||||
```
|
```
|
||||||
|
|
||||||
**Cloudflare Tunnel:**
|
**Cloudflare Tunnel (optional):**
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
CF_TUNNEL: "true" # Options: true, qr, password
|
OPENCHAMBER_TUNNEL_MODE: quick # quick | managed-remote | managed-local
|
||||||
|
OPENCHAMBER_TUNNEL_PROVIDER: cloudflare
|
||||||
```
|
```
|
||||||
|
|
||||||
| Value | Description |
|
For `managed-remote` mode, provide:
|
||||||
| ---------- | ------------------------------- |
|
|
||||||
| `true` | Enable tunnel only |
|
|
||||||
| `qr` | Enable tunnel + QR code |
|
|
||||||
| `password` | Enable tunnel + password in URL |
|
|
||||||
|
|
||||||
### 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**.
|
```yaml
|
||||||
- Managed-remote tunnels require a domain in your Cloudflare account.
|
environment:
|
||||||
- Cloudflare setup guide: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/create-remote-tunnel/
|
OPENCHAMBER_TUNNEL_MODE: managed-local
|
||||||
- Managed-local mode uses your local cloudflared config, for example:
|
OPENCHAMBER_TUNNEL_CONFIG: /home/openchamber/.cloudflared/config.yml
|
||||||
- `openchamber tunnel start --provider cloudflare --mode managed-local --config ~/.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
|
### Tunnel behavior notes
|
||||||
|
|
||||||
@@ -237,7 +241,7 @@ chown -R 1000:1000 data/
|
|||||||
<details>
|
<details>
|
||||||
<summary><strong>Web / PWA</strong></summary>
|
<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
|
- Mobile-first: optimized chat controls, keyboard-safe layouts, drag-to-reorder projects
|
||||||
- Background notifications and cross-tab session tracking
|
- Background notifications and cross-tab session tracking
|
||||||
- Self-update + restart flow that keeps your server settings intact
|
- Self-update + restart flow that keeps your server settings intact
|
||||||
|
|||||||
+5
-1
@@ -17,7 +17,11 @@ services:
|
|||||||
- ./workspaces:/home/openchamber/workspaces
|
- ./workspaces:/home/openchamber/workspaces
|
||||||
#environment:
|
#environment:
|
||||||
# UI_PASSWORD: your_secure_password_here # Uncomment to set UI password
|
# 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
|
# OH_MY_OPENCODE: true # enable oh-my-opencode
|
||||||
# OPENCODE_HOST: http://172.17.0.1:4096 # Connect to external OpenCode server
|
# OPENCODE_HOST: http://172.17.0.1:4096 # Connect to external OpenCode server
|
||||||
# OPENCODE_SKIP_START: true # skip start opencode
|
# OPENCODE_SKIP_START: true # skip start opencode
|
||||||
|
|||||||
+23
-3
@@ -50,9 +50,29 @@ openchamber update # Update to latest version
|
|||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
UI_PASSWORD: your_secure_password
|
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:
|
**Data directory:** mount `data/` for persistent storage. Ensure permissions:
|
||||||
```bash
|
```bash
|
||||||
mkdir -p data/openchamber data/opencode/share data/opencode/config data/ssh
|
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>
|
<summary>Background & daemon mode</summary>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
openchamber --daemon # Run in background
|
openchamber # Runs in background by default
|
||||||
openchamber stop # Stop background server
|
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
|
- **Self-update** - update and restart from the UI, server settings stay intact
|
||||||
- **Cross-tab tracking** - session activity stays in sync across browser tabs
|
- **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
|
- One-scan onboarding with tunnel QR + password URL helpers
|
||||||
- Mobile-first experience: optimized chat controls, keyboard-safe layouts, and attachment-friendly UI
|
- Mobile-first experience: optimized chat controls, keyboard-safe layouts, and attachment-friendly UI
|
||||||
- Background notifications plus reliable cross-tab session activity tracking
|
- Background notifications plus reliable cross-tab session activity tracking
|
||||||
|
|||||||
@@ -36,30 +36,9 @@ fi
|
|||||||
echo "[entrypoint] SSH public key:"
|
echo "[entrypoint] SSH public key:"
|
||||||
cat "${SSH_PUBLIC_KEY_PATH}"
|
cat "${SSH_PUBLIC_KEY_PATH}"
|
||||||
|
|
||||||
# Handle UI_PASSWORD environment variable
|
# Handle UI password environment variable
|
||||||
OPENCHAMBER_ARGS=""
|
|
||||||
|
|
||||||
if [ -n "${UI_PASSWORD:-}" ]; then
|
if [ -n "${UI_PASSWORD:-}" ]; then
|
||||||
echo "[entrypoint] UI password set, enabling authentication"
|
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
|
fi
|
||||||
|
|
||||||
if [ "${OH_MY_OPENCODE:-false}" = "true" ]; then
|
if [ "${OH_MY_OPENCODE:-false}" = "true" ]; then
|
||||||
@@ -82,5 +61,10 @@ if [ "$#" -gt 0 ]; then
|
|||||||
exec "$@"
|
exec "$@"
|
||||||
fi
|
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
|
bun packages/web/bin/cli.js logs
|
||||||
|
|||||||
Reference in New Issue
Block a user