From df28fa9ee57ee6bf59eef6f04a53b5ac77b1dc25 Mon Sep 17 00:00:00 2001 From: coji Date: Mon, 16 Mar 2026 15:58:17 +0900 Subject: [PATCH 1/2] improve: optimize Docker build for faster CI and smaller image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split base into build-base (build-essential, python3) and runtime-base (sqlite3, atlas, vim) so build tools are excluded from production image - Change GHA cache mode from min to max to cache all intermediate stages - Add opensrc/, .git/, .github/ to .dockerignore to reduce build context - Fix legacy ENV format warnings Image size: 1.40GB → 1.09GB (-22%) CI with cache: base stages cached, only rebuild on source changes (~30s) Co-Authored-By: Claude Opus 4.6 (1M context) --- .dockerignore | 5 +++- .github/workflows/deploy.yml | 2 +- Dockerfile | 48 ++++++++++++++++++++++-------------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/.dockerignore b/.dockerignore index 84fdbe2c..0a612399 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,7 @@ public/build build dist data -test \ No newline at end of file +test +opensrc +.git +.github \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index fad2b0dc..0cb282b3 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -169,7 +169,7 @@ jobs: COMMIT_SHA=${{ github.sha }} provenance: false cache-from: type=gha - cache-to: type=gha,mode=min + cache-to: type=gha,mode=max deploy: name: 🚀 Deploy diff --git a/Dockerfile b/Dockerfile index dbcb4617..21ffda01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,29 @@ ARG NODE_VERSION=24.12.0 ARG PNPM_VERSION=10.26.2 -# base node image -FROM node:${NODE_VERSION}-slim AS base +# --- Build base: includes native build tools for better-sqlite3 --- +FROM node:${NODE_VERSION}-slim AS build-base -# Install dependencies and Atlas RUN apt-get update \ - && apt-get install --no-install-recommends -y openssl openssh-client sqlite3 procps curl ca-certificates unzip vim build-essential python3 \ + && apt-get install --no-install-recommends -y openssl curl ca-certificates build-essential python3 \ + && apt-get clean \ + && npm i -g pnpm@${PNPM_VERSION} \ + && rm -rf /var/lib/apt/lists/* + + +# --- Runtime base: minimal packages for production --- +FROM node:${NODE_VERSION}-slim AS runtime-base + +RUN apt-get update \ + && apt-get install --no-install-recommends -y openssl openssh-client sqlite3 procps curl ca-certificates unzip vim \ && apt-get clean \ && npm i -g pnpm@${PNPM_VERSION} \ && curl -sSf https://atlasgo.sh | sh \ - && rm -rf /var/lib/apt/lists/* + && rm -rf /var/lib/apt/lists/* + -# Install all node_modules, including dev dependencies -FROM base AS deps +# --- Install all node_modules (dev + prod) --- +FROM build-base AS deps WORKDIR /upflow @@ -21,10 +31,10 @@ COPY package.json pnpm-lock.yaml ./ RUN pnpm fetch -# Setup production node_modules -FROM base AS production-deps +# --- Production node_modules only --- +FROM build-base AS production-deps -ENV NODE_ENV production +ENV NODE_ENV=production WORKDIR /upflow COPY --from=deps /upflow/node_modules /upflow/node_modules @@ -32,8 +42,8 @@ COPY package.json pnpm-lock.yaml ./ RUN pnpm install --prod --offline --frozen-lockfile -# Build the app -FROM base AS build +# --- Build the app --- +FROM build-base AS build WORKDIR /upflow @@ -45,13 +55,13 @@ COPY . . RUN pnpm run build -# Finally, build the production image with minimal footprint -FROM base +# --- Production image --- +FROM runtime-base -ENV DATABASE_URL "file:/upflow/data/data.db?connection_limit=1" -ENV UPFLOW_DATA_DIR "/upflow/data" -ENV PORT "8080" -ENV NODE_ENV "production" +ENV DATABASE_URL="file:/upflow/data/data.db?connection_limit=1" +ENV UPFLOW_DATA_DIR="/upflow/data" +ENV PORT="8080" +ENV NODE_ENV="production" # add shortcut for connecting to database CLI RUN printf '#!/bin/sh\nset -x\nsqlite3 file:/upflow/data/data.db\n' > /usr/local/bin/database-cli && chmod +x /usr/local/bin/database-cli @@ -71,4 +81,4 @@ COPY --from=build /upflow/batch /upflow/batch COPY --from=build /upflow/ops/remote /upflow/ops/remote COPY --from=build /upflow/server.mjs /upflow/server.mjs -CMD [ "sh", "./start.sh" ] \ No newline at end of file +CMD [ "sh", "./start.sh" ] From 14339c3926c20916f21dd337b0476dc8cdf4d7d5 Mon Sep 17 00:00:00 2001 From: coji Date: Mon, 16 Mar 2026 16:03:01 +0900 Subject: [PATCH 2/2] chore: establish single source of truth for Node/pnpm versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add .node-version (24.14.0) as source of truth for Node version - Add packageManager field (pnpm@10.32.1) to package.json - Bump Dockerfile ARGs to match: Node 24.12.0→24.14.0, pnpm 10.26.2→10.32.1 - Remove hardcoded version/node-version from CI workflow steps (pnpm/action-setup reads packageManager, setup-node reads .node-version) Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy.yml | 16 ---------------- .node-version | 1 + Dockerfile | 4 ++-- package.json | 1 + 4 files changed, 4 insertions(+), 18 deletions(-) create mode 100644 .node-version diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0cb282b3..7f75b4a9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -22,14 +22,10 @@ jobs: - uses: pnpm/action-setup@v4 name: Install pnpm - with: - version: 10 - run_install: false - name: ⎔ Setup node uses: actions/setup-node@v6 with: - node-version: 24 cache: 'pnpm' - name: Install dependencies @@ -47,14 +43,10 @@ jobs: - uses: pnpm/action-setup@v4 name: Install pnpm - with: - version: 10 - run_install: false - name: ⎔ Setup node uses: actions/setup-node@v6 with: - node-version: 24 cache: 'pnpm' - name: Install dependencies @@ -72,14 +64,10 @@ jobs: - uses: pnpm/action-setup@v4 name: Install pnpm - with: - version: 10 - run_install: false - name: ⎔ Setup node uses: actions/setup-node@v6 with: - node-version: 24 cache: 'pnpm' - name: Install dependencies @@ -103,14 +91,10 @@ jobs: - uses: pnpm/action-setup@v4 name: Install pnpm - with: - version: 10 - run_install: false - name: ⎔ Setup node uses: actions/setup-node@v6 with: - node-version: 24 cache: 'pnpm' - name: Install dependencies diff --git a/.node-version b/.node-version new file mode 100644 index 00000000..d845d9d8 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +24.14.0 diff --git a/Dockerfile b/Dockerfile index 21ffda01..e121393b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -ARG NODE_VERSION=24.12.0 -ARG PNPM_VERSION=10.26.2 +ARG NODE_VERSION=24.14.0 +ARG PNPM_VERSION=10.32.1 # --- Build base: includes native build tools for better-sqlite3 --- FROM node:${NODE_VERSION}-slim AS build-base diff --git a/package.json b/package.json index 9f12ae5c..4fd2b10e 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "vite-plugin-devtools-json": "1.0.0", "vitest": "4.1.0" }, + "packageManager": "pnpm@10.32.1", "pnpm": { "onlyBuiltDependencies": [ "@biomejs/biome",