Skip to content

Commit c1b1734

Browse files
committed
docker optimization for issue 104 ready for testing
1 parent f5caf5c commit c1b1734

4 files changed

Lines changed: 45 additions & 15 deletions

File tree

‎.github/workflows/docker-image.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ jobs:
3131
context: ./client
3232
dockerfile: ./client/Dockerfile
3333
image: homeglow-frontend
34+
platforms: linux/amd64
3435
- name: backend
3536
context: ./server
3637
dockerfile: ./server/Dockerfile
3738
image: homeglow-backend
39+
platforms: linux/amd64,linux/arm64
3840

3941
steps:
4042
- name: Checkout
@@ -52,6 +54,9 @@ jobs:
5254
echo "git_commit=${GITHUB_SHA}" >> "$GITHUB_OUTPUT"
5355
echo "repository=${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT"
5456
57+
- name: Set up QEMU (for arm64 cross-builds)
58+
uses: docker/setup-qemu-action@v3
59+
5560
- name: Set up Docker Buildx
5661
uses: docker/setup-buildx-action@v4
5762

@@ -83,6 +88,7 @@ jobs:
8388
with:
8489
context: ${{ matrix.context }}
8590
file: ${{ matrix.dockerfile }}
91+
platforms: ${{ matrix.platforms }}
8692
push: true
8793
tags: ${{ steps.meta.outputs.tags }}
8894
labels: ${{ steps.meta.outputs.labels }}

‎docs/guides/deployment.md‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,13 @@ and [`server/Dockerfile`](../../server/Dockerfile). See
5757
`node:20-alpine` builds the Vite bundle, then `nginx:alpine` serves `dist/`. An
5858
entrypoint runs `envsubst` on [`nginx.conf`](../../client/nginx.conf) so
5959
`FRONTEND_PORT`/`BACKEND_SERVICE`/`BACKEND_PORT` are applied at container start.
60-
- **Backend** ([`server/Dockerfile`](../../server/Dockerfile)): `node:24`, installs
61-
build tooling, `npm install`, rebuilds `better-sqlite3` from source, and runs
62-
`node index.js`. `uploads/` and `widgets/` are created with open permissions.
60+
- **Backend** ([`server/Dockerfile`](../../server/Dockerfile)): multi-stage —
61+
a `node:24-slim` builder installs production dependencies (with a C++ toolchain
62+
available only in that stage as a fallback if `better-sqlite3` has no prebuilt
63+
binary), then a clean `node:24-slim` runtime copies `node_modules` + app code and
64+
runs `node index.js`. Final image is ~300MB (vs ~1.4GB before the multi-stage
65+
split). Published for `linux/amd64` and `linux/arm64` (Raspberry Pi capable).
66+
`uploads/` and `widgets/` are created with open permissions.
6367

6468
## CI/CD (GitHub Actions)
6569

‎server/.dockerignore‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ data
1212
uploads
1313
widgets/
1414

15+
# Not needed at runtime: tests run in CI, scripts are dev-time tooling.
16+
tests
17+
scripts
18+
Dockerfile
19+
.dockerignore
20+
1521
# Misc
1622
.env
1723
**/.env

‎server/Dockerfile‎

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
1-
FROM node:24
1+
# ---- Builder: install production dependencies ----
2+
# The C++ toolchain lives only in this stage. better-sqlite3 ships prebuilt
3+
# binaries for linux amd64/arm64 (glibc), so `npm ci` normally downloads a
4+
# binary and compiles nothing; the toolchain is the automatic fallback for
5+
# platforms without a prebuild.
6+
FROM node:24-slim AS builder
27
WORKDIR /app
38

9+
RUN apt-get update && \
10+
apt-get install -y --no-install-recommends python3 make g++ && \
11+
rm -rf /var/lib/apt/lists/*
12+
13+
COPY package*.json ./
14+
RUN npm ci --omit=dev --no-audit --no-fund
15+
16+
# ---- Runtime ----
17+
FROM node:24-slim
18+
WORKDIR /app
19+
20+
# tzdata: chore scheduling depends on the TZ env var. Node's bundled ICU covers
21+
# JS Date/Intl on its own, but the OS zoneinfo db is ~3MB of insurance for
22+
# anything else that reads /usr/share/zoneinfo.
23+
RUN apt-get update && \
24+
apt-get install -y --no-install-recommends tzdata && \
25+
rm -rf /var/lib/apt/lists/*
26+
427
# Accept PORT and TZ as build arguments with defaults
528
ARG PORT=5000
629
ARG TZ=America/New_York
@@ -9,24 +32,15 @@ ARG BACKEND_GIT_COMMIT=
932
ARG BACKEND_GITHUB_REPOSITORY=jherforth/HomeGlow
1033

1134
# Set as environment variables for runtime
35+
ENV NODE_ENV=production
1236
ENV PORT=$PORT
1337
ENV TZ=$TZ
1438
ENV APP_VERSION=$BACKEND_VERSION
1539
ENV BACKEND_VERSION=$BACKEND_VERSION
1640
ENV BACKEND_GIT_COMMIT=$BACKEND_GIT_COMMIT
1741
ENV BACKEND_GITHUB_REPOSITORY=$BACKEND_GITHUB_REPOSITORY
1842

19-
# Install SQLite3 dependencies with GPG error handling
20-
RUN apt-get clean && \
21-
rm -rf /var/lib/apt/lists/* && \
22-
apt-get update --allow-insecure-repositories || apt-get update && \
23-
apt-get install -y --allow-unauthenticated libsqlite3-dev python3 make g++
24-
25-
COPY package*.json ./
26-
RUN npm install -g npm@latest
27-
RUN npm install || { echo 'npm install failed'; exit 1; }
28-
RUN npm rebuild better-sqlite3 --build-from-source
29-
43+
COPY --from=builder /app/node_modules ./node_modules
3044
COPY . .
3145
RUN mkdir -p /app/uploads/users /app/widgets && chmod -R 777 /app/uploads /app/widgets
3246

0 commit comments

Comments
 (0)