From e25518123527a1a6d9f20965c4ffebdcbb76104e Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 09:52:39 +0000 Subject: [PATCH 1/2] ops: deploy sh1pt.com to dev2 on merge Railway deployed this on push; dev2 does not by itself. The workflow ssh's to the box and runs /home/anthony/www/sh1pt.com/deploy-app.sh, which builds the image from this checkout and restarts the compose stack. Generated by cli-tools dev2/dev2-site scaffold. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/deploy-dev2.yml | 60 +++++++++++++++++++ .nixpacks/Dockerfile | 35 +++++++++++ .nixpacks/build.sh | 1 + ...eebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix | 21 +++++++ 4 files changed, 117 insertions(+) create mode 100644 .github/workflows/deploy-dev2.yml create mode 100644 .nixpacks/Dockerfile create mode 100644 .nixpacks/build.sh create mode 100644 .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix diff --git a/.github/workflows/deploy-dev2.yml b/.github/workflows/deploy-dev2.yml new file mode 100644 index 00000000..de6feb6f --- /dev/null +++ b/.github/workflows/deploy-dev2.yml @@ -0,0 +1,60 @@ +# Ship every merge to dev2, where sh1pt.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/sh1pt.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/sh1pt.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://sh1pt.com/" || true) + case "$code" in 2*|3*|401|403) echo "sh1pt.com $code"; exit 0;; esac + echo "attempt $i: $code"; sleep 10 + done + echo "sh1pt.com never answered"; exit 1 diff --git a/.nixpacks/Dockerfile b/.nixpacks/Dockerfile new file mode 100644 index 00000000..61bdd33f --- /dev/null +++ b/.nixpacks/Dockerfile @@ -0,0 +1,35 @@ +FROM ghcr.io/railwayapp/nixpacks:ubuntu-1745885067 + +ENTRYPOINT ["/bin/bash", "-l", "-c"] +WORKDIR /app/ + + +COPY .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix +RUN nix-env -if .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix && nix-collect-garbage -d + + +ARG CI NIXPACKS_METADATA NODE_ENV NPM_CONFIG_PRODUCTION +ENV CI=$CI NIXPACKS_METADATA=$NIXPACKS_METADATA NODE_ENV=$NODE_ENV NPM_CONFIG_PRODUCTION=$NPM_CONFIG_PRODUCTION + +# setup phase +# noop + +# install phase +ENV NIXPACKS_PATH=/app/node_modules/.bin:$NIXPACKS_PATH +COPY . /app/. +RUN --mount=type=cache,id=xrMbq0WIzsA-/root/local/share/pnpm/store/v3,target=/root/.local/share/pnpm/store/v3 npm install -g corepack@0.24.1 && corepack enable +RUN --mount=type=cache,id=xrMbq0WIzsA-/root/local/share/pnpm/store/v3,target=/root/.local/share/pnpm/store/v3 pnpm i --frozen-lockfile + +# build phase +COPY . /app/. +RUN --mount=type=cache,id=xrMbq0WIzsA-boilerplates/next-plugin-store/next/cache,target=/app/boilerplates/next-plugin-store/.next/cache --mount=type=cache,id=xrMbq0WIzsA-boilerplates/next-supabase/next/cache,target=/app/boilerplates/next-supabase/.next/cache --mount=type=cache,id=xrMbq0WIzsA-boilerplates/perry-hono-supabase/apps/web/next/cache,target=/app/boilerplates/perry-hono-supabase/apps/web/.next/cache --mount=type=cache,id=xrMbq0WIzsA-node_modules/cache,target=/app/node_modules/.cache --mount=type=cache,id=xrMbq0WIzsA-sites/sh1ptcom/next/cache,target=/app/sites/sh1pt.com/.next/cache pnpm run build + + +RUN printf '\nPATH=/app/node_modules/.bin:$PATH' >> /root/.profile + + +# start +COPY . /app + +CMD ["pnpm run start"] + diff --git a/.nixpacks/build.sh b/.nixpacks/build.sh new file mode 100644 index 00000000..ab1e90e2 --- /dev/null +++ b/.nixpacks/build.sh @@ -0,0 +1 @@ +docker build /home/anthony/src/profullstack/sh1pt/.claude/worktrees/dev2-sh1pt.com-pohvos28 -f /home/anthony/src/profullstack/sh1pt/.claude/worktrees/dev2-sh1pt.com-pohvos28/.nixpacks/Dockerfile -t 6e86fa36-3d05-42cd-8e44-5b78b757adfe --build-arg CI=true --build-arg NIXPACKS_METADATA=node --build-arg NODE_ENV=production --build-arg NPM_CONFIG_PRODUCTION=false \ No newline at end of file diff --git a/.nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix b/.nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix new file mode 100644 index 00000000..478c3c15 --- /dev/null +++ b/.nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix @@ -0,0 +1,21 @@ +{ }: + +let pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.tar.gz") { overlays = [ (import (builtins.fetchTarball "https://github.com/railwayapp/nix-npm-overlay/archive/main.tar.gz")) ]; }; +in with pkgs; + let + APPEND_LIBRARY_PATH = "${lib.makeLibraryPath [ gcc-unwrapped ] }"; + myLibraries = writeText "libraries" '' + export LD_LIBRARY_PATH="${APPEND_LIBRARY_PATH}:$LD_LIBRARY_PATH" + + ''; + in + buildEnv { + name = "ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7-env"; + paths = [ + (runCommand "ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7-env" { } '' + mkdir -p $out/etc/profile.d + cp ${myLibraries} $out/etc/profile.d/ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7-env.sh + '') + nodejs_18 pnpm-9_x + ]; + } From ffaa774aabec730d163a5b453d45331fece475cd Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Fri, 25 Sep 2026 09:54:34 +0000 Subject: [PATCH 2/2] ops: build sh1pt.com on dev2 with the site's own Dockerfile The nixpacks-generated Dockerfile installs the whole workspace on node 18 and never builds the packages sites/sh1pt.com depends on, so next build fails with "Can't resolve '@profullstack/sh1pt-action-packs'". .nixpacks/Dockerfile now mirrors sites/sh1pt.com/Dockerfile (root context, pruned workspace, node 20), which is what Railway built. Co-Authored-By: Claude Fable 5.1 --- .nixpacks/Dockerfile | 58 ++++++++++++------- .nixpacks/build.sh | 1 - ...eebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix | 21 ------- 3 files changed, 36 insertions(+), 44 deletions(-) delete mode 100644 .nixpacks/build.sh delete mode 100644 .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix diff --git a/.nixpacks/Dockerfile b/.nixpacks/Dockerfile index 61bdd33f..d995722b 100644 --- a/.nixpacks/Dockerfile +++ b/.nixpacks/Dockerfile @@ -1,35 +1,49 @@ -FROM ghcr.io/railwayapp/nixpacks:ubuntu-1745885067 +# dev2 builds this file (cli-tools dev2/dev2-site: compose builds .nixpacks/Dockerfile from the +# repo root). nixpacks' generated Dockerfile cannot build sh1pt.com: it installs the whole +# 555-package workspace on node 18 and never builds the workspace packages the site +# depends on (@profullstack/sh1pt-action-packs, ...). This is sites/sh1pt.com/Dockerfile, +# the one Railway built; keep the two in sync. -ENTRYPOINT ["/bin/bash", "-l", "-c"] -WORKDIR /app/ +# syntax=docker/dockerfile:1.6 +# Dockerfile for sh1pt.com — built from the monorepo root. +# Reason for existing: Railpack's auto-generated COPY-per-workspace-package +# exceeds BuildKit's mount-options length limit (~344 workspace packages). +# A single bulk COPY sidesteps that. +FROM node:20-bookworm-slim AS build -COPY .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix -RUN nix-env -if .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix && nix-collect-garbage -d +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH +RUN npm install -g pnpm@9.12.0 +WORKDIR /app -ARG CI NIXPACKS_METADATA NODE_ENV NPM_CONFIG_PRODUCTION -ENV CI=$CI NIXPACKS_METADATA=$NIXPACKS_METADATA NODE_ENV=$NODE_ENV NPM_CONFIG_PRODUCTION=$NPM_CONFIG_PRODUCTION +COPY . . -# setup phase -# noop +# Replace the workspace file with a minimal one covering only sh1pt-dot-com's +# transitive closure. Otherwise pnpm scans all 555 workspace packages, which +# OOMs the build container. +RUN printf 'packages:\n - sites/sh1pt.com\n - packages/core\n - packages/cli\n - packages/policy\n - packages/openapi\n - packages/actions-fleet-core\n - packages/actions\n - packages/automation/browser\n - packages/secrets/env-updater\n' > pnpm-workspace.yaml -# install phase -ENV NIXPACKS_PATH=/app/node_modules/.bin:$NIXPACKS_PATH -COPY . /app/. -RUN --mount=type=cache,id=xrMbq0WIzsA-/root/local/share/pnpm/store/v3,target=/root/.local/share/pnpm/store/v3 npm install -g corepack@0.24.1 && corepack enable -RUN --mount=type=cache,id=xrMbq0WIzsA-/root/local/share/pnpm/store/v3,target=/root/.local/share/pnpm/store/v3 pnpm i --frozen-lockfile +# Next probes the app env file during build. Railway injects real values at +# runtime, so an empty file keeps container builds deterministic. +RUN touch sites/sh1pt.com/.env -# build phase -COPY . /app/. -RUN --mount=type=cache,id=xrMbq0WIzsA-boilerplates/next-plugin-store/next/cache,target=/app/boilerplates/next-plugin-store/.next/cache --mount=type=cache,id=xrMbq0WIzsA-boilerplates/next-supabase/next/cache,target=/app/boilerplates/next-supabase/.next/cache --mount=type=cache,id=xrMbq0WIzsA-boilerplates/perry-hono-supabase/apps/web/next/cache,target=/app/boilerplates/perry-hono-supabase/apps/web/.next/cache --mount=type=cache,id=xrMbq0WIzsA-node_modules/cache,target=/app/node_modules/.cache --mount=type=cache,id=xrMbq0WIzsA-sites/sh1ptcom/next/cache,target=/app/sites/sh1pt.com/.next/cache pnpm run build +RUN pnpm --filter sh1pt-dot-com... install --frozen-lockfile=false +RUN pnpm --filter sh1pt-dot-com^... --if-present build +RUN pnpm --filter sh1pt-dot-com build +FROM node:20-bookworm-slim AS runner -RUN printf '\nPATH=/app/node_modules/.bin:$PATH' >> /root/.profile +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH +ENV NODE_ENV=production +RUN npm install -g pnpm@9.12.0 +WORKDIR /app -# start -COPY . /app - -CMD ["pnpm run start"] +COPY --from=build --chown=node:node /app /app +EXPOSE 8080 +USER node +CMD ["sh", "-c", "cd sites/sh1pt.com && exec node node_modules/next/dist/bin/next start -p ${PORT:-8080} -H 0.0.0.0"] diff --git a/.nixpacks/build.sh b/.nixpacks/build.sh deleted file mode 100644 index ab1e90e2..00000000 --- a/.nixpacks/build.sh +++ /dev/null @@ -1 +0,0 @@ -docker build /home/anthony/src/profullstack/sh1pt/.claude/worktrees/dev2-sh1pt.com-pohvos28 -f /home/anthony/src/profullstack/sh1pt/.claude/worktrees/dev2-sh1pt.com-pohvos28/.nixpacks/Dockerfile -t 6e86fa36-3d05-42cd-8e44-5b78b757adfe --build-arg CI=true --build-arg NIXPACKS_METADATA=node --build-arg NODE_ENV=production --build-arg NPM_CONFIG_PRODUCTION=false \ No newline at end of file diff --git a/.nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix b/.nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix deleted file mode 100644 index 478c3c15..00000000 --- a/.nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ }: - -let pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.tar.gz") { overlays = [ (import (builtins.fetchTarball "https://github.com/railwayapp/nix-npm-overlay/archive/main.tar.gz")) ]; }; -in with pkgs; - let - APPEND_LIBRARY_PATH = "${lib.makeLibraryPath [ gcc-unwrapped ] }"; - myLibraries = writeText "libraries" '' - export LD_LIBRARY_PATH="${APPEND_LIBRARY_PATH}:$LD_LIBRARY_PATH" - - ''; - in - buildEnv { - name = "ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7-env"; - paths = [ - (runCommand "ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7-env" { } '' - mkdir -p $out/etc/profile.d - cp ${myLibraries} $out/etc/profile.d/ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7-env.sh - '') - nodejs_18 pnpm-9_x - ]; - }