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
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.git
.github
.next
.data
node_modules
.env*
*.md
tests
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: ci

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
build:
name: install, typecheck, test, build (Bun)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# The version comes from packageManager in package.json, the same Bun the
# image (.nixpacks/Dockerfile) pins.
- uses: oven-sh/setup-bun@v2
with:
bun-version-file: package.json
- run: bun install --frozen-lockfile
- run: bun run typecheck
- run: bun test
- run: bun run build
# The production server must boot under Bun and answer.
- name: Standalone server answers under Bun
run: |
cp -r public .next/standalone/
cp -r .next/static .next/standalone/.next/
(cd .next/standalone && PORT=3000 HOSTNAME=127.0.0.1 bun server.js > /tmp/server.log 2>&1 &)
for i in $(seq 1 30); do
code=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/ || true)
[ "$code" = 200 ] && { echo "/ -> $code"; exit 0; }
sleep 1
done
cat /tmp/server.log; exit 1
82 changes: 47 additions & 35 deletions .nixpacks/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
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=Vkv8k5qQY1A-/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=Vkv8k5qQY1A-/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=Vkv8k5qQY1A-next/cache,target=/app/.next/cache --mount=type=cache,id=Vkv8k5qQY1A-node_modules/cache,target=/app/node_modules/.cache pnpm run build


RUN printf '\nPATH=/app/node_modules/.bin:$PATH' >> /root/.profile


# start
COPY . /app

CMD ["pnpm run start"]

# syntax=docker/dockerfile:1
#
# recipepdfs.com, run on Bun.
#
# This file lives at .nixpacks/Dockerfile because that is the path dev2's compose
# stack builds (cli-tools dev2/dev2-site provision records it per site, and
# re-provisioning keeps it). It used to be nixpacks output (Node + pnpm); it is now
# a hand-written Bun image, so do not regenerate it with nixpacks.
#
# Contract with /home/anthony/www/recipepdfs.com on dev2, unchanged from the Node
# image: listens on 8080 inside the container (compose maps 127.0.0.1:APP_PORT),
# answers / for the deploy health check, reads its secrets from app.env at run time.

FROM oven/bun:1.4.0-slim AS deps
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile

FROM deps AS build
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
# `bun --bun next build` (the build script): Next runs on Bun, not Node.
RUN bun run build

FROM oven/bun:1.4.0-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=8080
# Docker sets HOSTNAME to the container id and Next's standalone server binds to it
# literally; it must listen on every interface for the published port to reach it.
ENV HOSTNAME=0.0.0.0
# Standalone output: server.js plus only the dependencies it imports.
COPY --from=build --chown=bun:bun /app/.next/standalone ./
COPY --from=build --chown=bun:bun /app/.next/static ./.next/static
COPY --from=build --chown=bun:bun /app/public ./public
# lib/store.ts keeps its JSON store in ./.data (process.cwd()), so /app itself must
# be writable by the non-root user. There is no volume: the store starts from the
# seed on every container start, exactly as it did on the Node image.
RUN mkdir -p /app/.data && chown bun:bun /app /app/.data
# The oven/bun image ships a non-root `bun` user.
USER bun
EXPOSE 8080
# 127.0.0.1, not localhost: localhost resolves ::1 first and Next binds IPv4 only.
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD bun -e "fetch('http://127.0.0.1:'+(process.env.PORT||8080)+'/').then(r=>process.exit(r.status<500?0:1)).catch(()=>process.exit(1))"
CMD ["bun", "server.js"]
1 change: 0 additions & 1 deletion .nixpacks/build.sh

This file was deleted.

21 changes: 0 additions & 21 deletions .nixpacks/nixpkgs-ffeebf0acf3ae8b29f8c7049cd911b9636efd7e7.nix

This file was deleted.

8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ Coinpay-authenticated marketplace for free and paid recipe PDF cookbooks.
## Local setup

```bash
pnpm install
bun install
cp .env.example .env.local
pnpm dev
bun dev
```

Bun is the package manager, the runtime (`bun --bun next ...`) and the test runner
(`bun test`). Production runs the Next standalone server under Bun, built from
`.nixpacks/Dockerfile`.

Register the OAuth callback in Coinpay as:

```text
Expand Down
Loading
Loading