Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ RUN python -m pip install --no-cache-dir --upgrade pip \
&& chmod +x /app/scripts/railway_start.sh \
&& chown -R zero:zero /app

USER zero

EXPOSE 8765

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
Expand Down
2 changes: 2 additions & 0 deletions contracts/distribution/railway-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"partner_docs_name_template_url": true,
"partner_docs_present": true,
"railway_healthcheck_configured": true,
"railway_start_drops_root_after_volume_chown": true,
"railway_start_names_runtime_version": true,
"railway_start_preserves_argv_after_su": true,
"railway_start_uses_durable_journal": true,
"railway_start_uses_foundation_state_dir": true,
"railway_start_uses_port": true,
Expand Down
5 changes: 5 additions & 0 deletions docs/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2320,6 +2320,9 @@ captured.
- Public HTTP networking enabled for the runtime service.
- Persistent Railway volume mounted at `/data`.
- Railway-provided `PORT`; do not hardcode a port.
- The container starts as root only long enough for
`/app/scripts/railway_start.sh` to create and chown Railway's mounted
`/data` volume, then the paper API process runs as the `zero` user.

### Deployment Dependencies

Expand Down Expand Up @@ -2389,6 +2392,8 @@ before any live authority ceremony.
- Public HTTP networking enabled for the runtime service.
- Persistent Railway volume mounted at `/data`.
- Railway-provided `PORT`.
- Startup repairs mounted volume ownership, then drops to the `zero` user
before launching the API.

### Why Deploy ZERO on Railway?

Expand Down
5 changes: 5 additions & 0 deletions docs/railway-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ captured.
- Public HTTP networking enabled for the runtime service.
- Persistent Railway volume mounted at `/data`.
- Railway-provided `PORT`; do not hardcode a port.
- The container starts as root only long enough for
`/app/scripts/railway_start.sh` to create and chown Railway's mounted
`/data` volume, then the paper API process runs as the `zero` user.

### Deployment Dependencies

Expand Down Expand Up @@ -122,6 +125,8 @@ before any live authority ceremony.
- Public HTTP networking enabled for the runtime service.
- Persistent Railway volume mounted at `/data`.
- Railway-provided `PORT`.
- Startup repairs mounted volume ownership, then drops to the `zero` user
before launching the API.

### Why Deploy ZERO on Railway?

Expand Down
1 change: 1 addition & 0 deletions scripts/hardening_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ contains "zero.registry_launch_packet.v1" docs/registry-launch.md
contains "zero.railway_template_packet.v1" contracts/distribution/railway-template.json
contains "pending_marketplace_republish_after_runtime_package_update" contracts/distribution/railway-template.json
contains "zero-engine==0.1.6" contracts/distribution/railway-template.json
contains "railway_start_drops_root_after_volume_chown" contracts/distribution/railway-template.json
contains "pending_after_marketplace_republish" contracts/distribution/railway-template.json
contains "template_published_partner_pending" contracts/distribution/railway-template.json
contains "docs/assets/zero-template-icon.svg" contracts/distribution/railway-template.json
Expand Down
1 change: 1 addition & 0 deletions scripts/public_readiness_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ file_contains "https://railway.com/deploy/zero-paper-runtime" README.md
file_contains "zero.railway_template_packet.v1" contracts/distribution/railway-template.json
file_contains "pending_marketplace_republish_after_runtime_package_update" contracts/distribution/railway-template.json
file_contains "zero-engine==0.1.6" contracts/distribution/railway-template.json
file_contains "railway_start_drops_root_after_volume_chown" contracts/distribution/railway-template.json
file_contains "pending_after_marketplace_republish" contracts/distribution/railway-template.json
file_contains "template_published_partner_pending" contracts/distribution/railway-template.json
file_contains "ZERO Paper Runtime" contracts/distribution/railway-template.json
Expand Down
16 changes: 15 additions & 1 deletion scripts/railway_smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,21 @@ cleanup() {
docker logs "${CONTAINER_NAME}" >&2 || true
fi
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true
rm -rf "${STATE_DIR}"
if [[ -d "${STATE_DIR}" ]]; then
docker run --rm \
-v "${STATE_DIR}:/data" \
--entrypoint /bin/sh \
"${IMAGE}" \
-c "chown -R $(id -u):$(id -g) /data" >/dev/null 2>&1 || true
rm -rf "${STATE_DIR}" || {
if command -v sudo >/dev/null 2>&1; then
sudo rm -rf "${STATE_DIR}"
else
chmod -R u+w "${STATE_DIR}" 2>/dev/null || true
rm -rf "${STATE_DIR}"
fi
}
fi
}
trap cleanup EXIT

Expand Down
5 changes: 5 additions & 0 deletions scripts/railway_start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ case "${ZERO_HYPERLIQUID_LIVE_PRICES}" in
;;
esac

if [ "$(id -u)" = "0" ]; then
chown -R zero:zero "$(dirname "${ZERO_JOURNAL_PATH}")" "${ZERO_FOUNDATION_STATE_DIR}"
exec su zero -s /bin/sh -c 'exec "$@"' -- zero-runtime "${args[@]}"
fi

exec "${args[@]}"
9 changes: 9 additions & 0 deletions scripts/railway_template_packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ def build_packet() -> dict[str, Any]:
'ZERO_FOUNDATION_STATE_DIR="${ZERO_FOUNDATION_STATE_DIR:-/data/.zero}"'
in start_script
),
"railway_start_drops_root_after_volume_chown": (
'chown -R zero:zero "$(dirname "${ZERO_JOURNAL_PATH}")" "${ZERO_FOUNDATION_STATE_DIR}"'
in start_script
and "exec su zero -s /bin/sh" in start_script
),
"railway_start_preserves_argv_after_su": (
'exec su zero -s /bin/sh -c \'exec "$@"\' -- zero-runtime "${args[@]}"'
in start_script
),
}

return {
Expand Down