diff --git a/packages/sync-server/.dockerignore b/.dockerignore similarity index 66% rename from packages/sync-server/.dockerignore rename to .dockerignore index 9a3b7d6774..137eb17307 100644 --- a/packages/sync-server/.dockerignore +++ b/.dockerignore @@ -1,8 +1,6 @@ -node_modules -user-files -server-files - -# Yarn +**/node_modules +.git +.lage .pnp.* .yarn/* !.yarn/patches diff --git a/packages/sync-server/docker/alpine.Dockerfile b/packages/sync-server/docker/alpine.Dockerfile index a0a1607656..0c8fa8e560 100644 --- a/packages/sync-server/docker/alpine.Dockerfile +++ b/packages/sync-server/docker/alpine.Dockerfile @@ -1,4 +1,4 @@ -FROM node:22-alpine AS deps +FROM node:22-alpine AS builder # Install required packages RUN apk add --no-cache python3 openssl build-base @@ -6,18 +6,9 @@ RUN corepack enable WORKDIR /app -# Copy only the files needed for installing dependencies COPY .yarn ./.yarn COPY yarn.lock package.json .yarnrc.yml ./ -COPY packages/api/package.json packages/api/package.json -COPY packages/component-library/package.json packages/component-library/package.json -COPY packages/crdt/package.json packages/crdt/package.json -COPY packages/desktop-client/package.json packages/desktop-client/package.json -COPY packages/desktop-electron/package.json packages/desktop-electron/package.json -COPY packages/eslint-plugin-actual/package.json packages/eslint-plugin-actual/package.json -COPY packages/loot-core/package.json packages/loot-core/package.json -COPY packages/sync-server/package.json packages/sync-server/package.json -COPY packages/plugins-service/package.json packages/plugins-service/package.json +COPY packages ./packages # Avoiding memory issues with ARMv7 RUN if [ "$(uname -m)" = "armv7l" ]; then yarn config set taskPoolConcurrency 2; yarn config set networkConcurrency 5; fi @@ -25,18 +16,15 @@ RUN if [ "$(uname -m)" = "armv7l" ]; then yarn config set taskPoolConcurrency 2; # Focus the workspaces in production mode RUN if [ "$(uname -m)" = "armv7l" ]; then npm_config_build_from_source=true yarn workspaces focus @actual-app/sync-server --production; else yarn workspaces focus @actual-app/sync-server --production; fi -FROM deps AS builder +# Dereference yarn's workspace:* symlinks so the prod stage can copy just node_modules. +RUN cp -RL node_modules node_modules.real \ + && rm -rf node_modules \ + && mv node_modules.real node_modules -WORKDIR /app - -COPY packages/sync-server ./packages/sync-server - -# Remove symbolic links for @actual-app/web and @actual-app/sync-server -RUN rm -rf ./node_modules/@actual-app/web ./node_modules/@actual-app/sync-server - -# Copy in the @actual-app/web artifacts manually, so we don't need the entire packages folder -COPY packages/desktop-client/package.json ./node_modules/@actual-app/web/package.json -COPY packages/desktop-client/build ./node_modules/@actual-app/web/build +# Strip dev-only content from dereferenced workspace packages to keep the final image lean. +RUN find node_modules/@actual-app -maxdepth 2 -type d \ + \( -name src -o -name e2e -o -name __tests__ -o -name __mocks__ -o -name tests -o -name test -o -name build-stats \) \ + -exec rm -rf {} + FROM alpine:3.22 AS prod @@ -53,8 +41,8 @@ RUN mkdir /data && chown -R ${USERNAME}:${USERNAME} /data WORKDIR /app ENV NODE_ENV=production -# Pull in only the necessary artifacts (built node_modules, server files, etc.) -COPY --from=builder /app/node_modules /app/node_modules +# sync-server entry flattened at /app so CMD stays `node app.js`. +COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/packages/sync-server/package.json ./ COPY --from=builder /app/packages/sync-server/build ./ diff --git a/packages/sync-server/docker/ubuntu.Dockerfile b/packages/sync-server/docker/ubuntu.Dockerfile index 74395ecc02..3bf9789230 100644 --- a/packages/sync-server/docker/ubuntu.Dockerfile +++ b/packages/sync-server/docker/ubuntu.Dockerfile @@ -1,22 +1,13 @@ -FROM node:22-bookworm AS deps +FROM node:22-bookworm AS builder # Install required packages RUN apt-get update && apt-get install -y openssl WORKDIR /app -# Copy only the files needed for installing dependencies COPY .yarn ./.yarn COPY yarn.lock package.json .yarnrc.yml ./ -COPY packages/api/package.json packages/api/package.json -COPY packages/component-library/package.json packages/component-library/package.json -COPY packages/crdt/package.json packages/crdt/package.json -COPY packages/desktop-client/package.json packages/desktop-client/package.json -COPY packages/desktop-electron/package.json packages/desktop-electron/package.json -COPY packages/eslint-plugin-actual/package.json packages/eslint-plugin-actual/package.json -COPY packages/loot-core/package.json packages/loot-core/package.json -COPY packages/sync-server/package.json packages/sync-server/package.json -COPY packages/plugins-service/package.json packages/plugins-service/package.json +COPY packages ./packages # Avoiding memory issues with ARMv7 RUN if [ "$(uname -m)" = "armv7l" ]; then yarn config set taskPoolConcurrency 2; yarn config set networkConcurrency 5; fi @@ -24,18 +15,15 @@ RUN if [ "$(uname -m)" = "armv7l" ]; then yarn config set taskPoolConcurrency 2; # Focus the workspaces in production mode RUN yarn workspaces focus @actual-app/sync-server --production -FROM deps AS builder +# Dereference yarn's workspace:* symlinks so the prod stage can copy just node_modules. +RUN cp -RL node_modules node_modules.real \ + && rm -rf node_modules \ + && mv node_modules.real node_modules -WORKDIR /app - -COPY packages/sync-server ./packages/sync-server - -# Remove symbolic links for @actual-app/web and @actual-app/sync-server -RUN rm -rf ./node_modules/@actual-app/web ./node_modules/@actual-app/sync-server - -# Copy in the @actual-app/web artifacts manually, so we don't need the entire packages folder -COPY packages/desktop-client/package.json ./node_modules/@actual-app/web/package.json -COPY packages/desktop-client/build ./node_modules/@actual-app/web/build +# Strip dev-only content from dereferenced workspace packages to keep the final image lean. +RUN find node_modules/@actual-app -maxdepth 2 -type d \ + \( -name src -o -name e2e -o -name __tests__ -o -name __mocks__ -o -name tests -o -name test -o -name build-stats \) \ + -exec rm -rf {} + FROM node:22-bookworm-slim AS prod @@ -53,8 +41,8 @@ RUN groupadd --gid $USER_GID $USERNAME \ WORKDIR /app ENV NODE_ENV=production -# Pull in only the necessary artifacts (built node_modules, server files, etc.) -COPY --from=builder /app/node_modules /app/node_modules +# sync-server entry flattened at /app so CMD stays `node app.js`. +COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/packages/sync-server/package.json ./ COPY --from=builder /app/packages/sync-server/build ./ diff --git a/upcoming-release-notes/7564.md b/upcoming-release-notes/7564.md new file mode 100644 index 0000000000..9120018642 --- /dev/null +++ b/upcoming-release-notes/7564.md @@ -0,0 +1,6 @@ +--- +category: Bugfixes +authors: [MatissJanis] +--- + +Fix Docker container failing to start due to unresolved workspace dependencies.