Skip to content

Commit e3afb83

Browse files
committed
Fix Railway volume permissions at runtime
1 parent 1a0b091 commit e3afb83

3 files changed

Lines changed: 90 additions & 6 deletions

File tree

docker-compose.railway.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# opencode-cloud Railway Compose Template
2+
#
3+
# Use this file for Railway template import workflows.
4+
# The canonical docker-compose.yml remains local/quick-deploy focused and
5+
# includes six volumes that Railway template import does not support.
6+
7+
services:
8+
opencode:
9+
image: prizz/opencode-cloud-sandbox:latest
10+
pull_policy: ${OPENCODE_PULL_POLICY:-missing}
11+
restart: unless-stopped
12+
init: true
13+
stop_grace_period: ${OPENCODE_STOP_GRACE_PERIOD:-30s}
14+
environment:
15+
OPENCODE_HOST: ${OPENCODE_HOST:-0.0.0.0}
16+
logging:
17+
driver: ${OPENCODE_LOG_DRIVER:-json-file}
18+
options:
19+
max-size: ${OPENCODE_LOG_MAX_SIZE:-10m}
20+
max-file: "${OPENCODE_LOG_MAX_FILE:-3}"
21+
volumes:
22+
- opencode-data:/home/opencoder/.local/share/opencode
23+
24+
volumes:
25+
opencode-data:

docs/deploy/railway.md

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@ Steps:
2121
> **Important:** After deploying, verify that a Railway Volume is attached.
2222
> Without a volume, all data is lost on every redeploy.
2323
24+
## Template from Compose File (Manual Upload)
25+
26+
If you are creating a Railway template by importing a Compose file, use
27+
`docker-compose.railway.yml` from this repository.
28+
29+
Do **not** import the root `docker-compose.yml` for Railway templates. That
30+
file is local/quick-deploy oriented and declares six volumes.
31+
32+
```bash
33+
curl -O https://raw.githubusercontent.com/pRizz/opencode-cloud/main/docker-compose.railway.yml
34+
```
35+
36+
Railway template import supports one volume per service. The Railway-specific
37+
compose file keeps a single persisted mount at
38+
`/home/opencoder/.local/share/opencode` for compatibility.
39+
It keeps variable-driven runtime/logging knobs where Railway supports them and
40+
uses a fixed image reference to avoid Railway parser issues.
2441
## Manual Deployment
2542

2643
### Prerequisites
@@ -155,13 +172,31 @@ the build logs.
155172
- Verify the image tag exists on Docker Hub
156173
- Check Railway deployment logs for errors
157174

158-
### Volume permissions
175+
### `EACCES` creating `/home/opencoder/.local/share/opencode/bin`
176+
177+
**Symptom:** Deploy logs repeatedly show:
178+
179+
```text
180+
EACCES: permission denied, mkdir '/home/opencoder/.local/share/opencode/bin'
181+
```
182+
183+
**Cause:** The Railway volume is mounted with root ownership, but the app runs
184+
as `opencoder`. If the mounted path is not writable by `opencoder`, startup
185+
fails.
186+
187+
**Immediate workaround (Railway service settings):**
188+
1. Ensure `RAILWAY_RUN_UID=0` (or remove a conflicting non-root value).
189+
2. Set the service **Start Command** to:
190+
191+
```bash
192+
/bin/sh -c 'install -d -m 0755 /home/opencoder/.local/share/opencode && chown -R opencoder:opencoder /home/opencoder/.local/share/opencode && exec /usr/local/bin/entrypoint.sh'
193+
```
194+
195+
After redeploy, the `EACCES` lines should stop.
159196

160-
Railway volumes require the container to run as root. The opencode-cloud
161-
image runs its entrypoint as root (which then drops privileges for the
162-
application), so this should work without additional configuration. If you
163-
encounter permission errors, ensure `RAILWAY_RUN_UID=0` is not explicitly
164-
set to a non-root value.
197+
**Long-term behavior:** Recent images auto-check this mount on startup and
198+
attempt to fix ownership before launching opencode. Keep the volume mounted at
199+
`/home/opencoder/.local/share/opencode`.
165200

166201
## Limitations
167202

packages/core/src/docker/files/entrypoint.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,29 @@ EOF
579579
maybe_initialize_bootstrap_mode
580580
}
581581

582+
ensure_opencode_data_dir_writable() {
583+
local data_dir="/home/opencoder/.local/share/opencode"
584+
585+
install -d -m 0755 "${data_dir}"
586+
587+
if runuser -u opencoder -- test -w "${data_dir}"; then
588+
return
589+
fi
590+
591+
log "Detected non-writable opencode data directory; attempting ownership fix: ${data_dir}"
592+
if ! chown -R opencoder:opencoder "${data_dir}" 2>/dev/null; then
593+
log "WARNING: Failed to change ownership for ${data_dir}; continuing with writability re-check."
594+
fi
595+
596+
if runuser -u opencoder -- test -w "${data_dir}"; then
597+
return
598+
fi
599+
600+
log "ERROR: ${data_dir} is not writable by user 'opencoder'."
601+
log "If running on Railway, set RAILWAY_RUN_UID=0 and attach a volume mounted at ${data_dir}."
602+
exit 1
603+
}
604+
582605
load_builtin_home_users
583606
if ! ensure_jsonc_parser; then
584607
log "ERROR: JSONC parser is required for auth config checks."
@@ -589,6 +612,7 @@ EOF
589612
migrate_unmanaged_home_users_to_records
590613
sync_bootstrap_state
591614
warn_security_posture
615+
ensure_opencode_data_dir_writable
592616

593617
log "Starting opencode on ${OPENCODE_HOST}:${OPENCODE_PORT}"
594618
/usr/local/bin/opencode-broker &

0 commit comments

Comments
 (0)