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
60 changes: 60 additions & 0 deletions .github/workflows/deploy-dev2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Ship every merge to dev2, where c0mpute.com runs since it left Railway (which
# deployed on merge by itself). The box pulls the merged commit, rebuilds the
# image(s) from this repo and restarts the compose stack under
# /home/anthony/www/c0mpute.com. Generated by cli-tools/dev2/dev2-site scaffold.
name: Deploy to dev2

on:
push:
branches: [master]
workflow_dispatch:
inputs:
ref:
description: Git ref to deploy (defaults to the pushed commit)
required: false
type: string

concurrency:
group: deploy-dev2
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
# ${{ }} values go through env, never straight into a run: body.
- name: Resolve target revision
id: rev
env:
REF: ${{ inputs.ref || github.sha }}
run: echo "sha=$REF" >> "$GITHUB_OUTPUT"

- name: Set up ssh
env:
SSH_KEY: ${{ secrets.DEV2_SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.DEV2_KNOWN_HOSTS }}
run: |
install -d -m 700 ~/.ssh
printf '%s\n' "$SSH_KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts

- name: Deploy
env:
DEV2_USER: ${{ secrets.DEV2_USER }}
DEV2_HOST: ${{ secrets.DEV2_HOST }}
SHA: ${{ steps.rev.outputs.sha }}
run: |
ssh -o BatchMode=yes "$DEV2_USER@$DEV2_HOST" \
/home/anthony/www/c0mpute.com/deploy-app.sh "$SHA"

- name: Verify the site answers
run: |
for i in $(seq 1 10); do
code=$(curl -s -o /dev/null -w '%{http_code}' "https://c0mpute.com/" || true)
case "$code" in 2*|3*|401|403) echo "c0mpute.com $code"; exit 0;; esac
echo "attempt $i: $code"; sleep 10
done
echo "c0mpute.com never answered"; exit 1
60 changes: 60 additions & 0 deletions .nixpacks/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# c0mpute.com on dev2: the compose stack builds this file (cli-tools dev2/dev2-site
# looks for .nixpacks/Dockerfile). It is a copy of ../Dockerfile.web, the image
# Railway built with RAILWAY_DOCKERFILE_PATH=Dockerfile.web: the Next.js site plus
# the co-located Rust status aggregator. Keep the two in step.

# c0mpute.com — single Railway deploy (DIP-0014).
#
# One service, two co-located processes: the Next.js site (foreground) and the
# status aggregator (Rust libp2p observer, background). The site proxies
# /status + /api/status to the aggregator over loopback. This replaces the
# earlier separate `c0mpute-status-aggregator` Railway service — the whole
# monorepo ships as one deploy.
#
# Point the c0mpute.com service at this file with the RAILWAY_DOCKERFILE_PATH
# variable (= Dockerfile.web). Build context is the repo root.

# ── stage 1: build the aggregator (Rust) ─────────────────────────────────
# Copy only the Rust workspace so edits under apps/web/ don't bust this layer.
FROM rust:1.92-bookworm AS rustbuild
WORKDIR /src
COPY Cargo.toml Cargo.lock ./
COPY node ./node
RUN cargo build --release --bin c0mpute

# ── stage 2: build the Next.js site (Bun) ────────────────────────────────
FROM oven/bun:1.3-debian AS webbuild
WORKDIR /app
# Native deps (better-sqlite3 is an optional native module) need a toolchain.
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3 make g++ ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY . .
RUN bun install --frozen-lockfile
RUN bun run --cwd packages/shared build && bun run --filter=c0mpute build

# ── stage 3: runtime ─────────────────────────────────────────────────────
FROM oven/bun:1.3-debian AS runtime
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# Full built app: `next start` (non-standalone) serves from .next, and several
# route handlers read repo files at request time (scripts/install.sh, etc.),
# so the whole tree + node_modules must be present.
COPY --from=webbuild /app /app
# Co-located aggregator binary.
COPY --from=rustbuild /src/target/release/c0mpute /usr/local/bin/c0mpute
COPY scripts/railway-web-start.sh /usr/local/bin/railway-web-start.sh
RUN chmod +x /usr/local/bin/railway-web-start.sh

# The aggregator serves its JSON on loopback; the site reads it there.
ENV C0MPUTE_STATUS_BIND=127.0.0.1:8090
ENV STATUS_AGGREGATOR_URL=http://127.0.0.1:8090

# Runs as root, exactly as the Railway image built from Dockerfile.web does (semgrep
# never scanned that file: its name is not a Dockerfile pattern). Moving to a
# non-root user is a runtime change for both files, not for the hosting move.
# nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint
ENTRYPOINT ["/usr/local/bin/railway-web-start.sh"]
Loading