11# Stage 1 - Create yarn install skeleton layer
22FROM node:20-bookworm-slim AS packages
33
4+ # Enable Corepack (for Yarn management) and install the required Yarn version
5+ RUN corepack enable
6+
47WORKDIR /app
5- COPY package.json yarn.lock ./
8+ COPY backstage.json package.json yarn.lock ./
9+ COPY .yarn ./.yarn
10+ COPY .yarnrc.yml ./
11+
612
713COPY packages packages
814
915# Comment this out if you don't have any internal plugins
10- # COPY plugins plugins
16+ COPY plugins plugins
1117
1218RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+
1319
1420# Stage 2 - Install dependencies and build packages
1521FROM node:20-bookworm-slim AS build
1622
23+ # Set Python interpreter for `node-gyp` to use
24+ ENV PYTHON=/usr/bin/python3
25+
1726# Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend.
1827RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
1928 --mount=type=cache,target=/var/lib/apt,sharing=locked \
2029 apt-get update && \
2130 apt-get install -y --no-install-recommends python3 g++ build-essential && \
22- yarn config set python /usr/bin/python3
31+ rm -rf /var/lib/apt/lists/*
32+
33+ # Enable Corepack (for Yarn management) and install the required Yarn version
34+ RUN corepack enable
2335
2436USER node
37+
38+ ENV DOCKER_BUILDKIT=1
39+
2540WORKDIR /app
2641
2742COPY --from=packages --chown=node:node /app .
43+ COPY --from=packages --chown=node:node /app/.yarn ./.yarn
44+ COPY --from=packages --chown=node:node /app/.yarnrc.yml ./
45+ COPY --from=packages --chown=node:node /app/backstage.json ./
2846
47+ # Pre-create and fix ownership for cache directory
48+ RUN mkdir -p /home/node/.cache/node/corepack/v1 && \
49+ chown -R node:node /home/node/.cache
50+
51+ # ENV CYPRESS_INSTALL_BINARY=0
52+ # RUN yarn install --immutable --network-timeout 600000
2953RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
30- yarn install --frozen-lockfile --network-timeout 600000
54+ yarn install --immutable
3155
3256COPY --chown=node:node . .
3357
34- RUN ls
58+ # RUN ls
3559
36- RUN ls /app
60+ # RUN ls /app
3761
3862RUN yarn tsc
3963RUN yarn --cwd packages/backend build
@@ -47,16 +71,25 @@ RUN mkdir packages/backend/dist/skeleton packages/backend/dist/bundle \
4771# Stage 3 - Build the actual backend image and install production dependencies
4872FROM node:20-bookworm-slim
4973
74+ # Enable Corepack (for Yarn management) and install the required Yarn version
75+ RUN corepack enable
76+
77+ # Set Python interpreter for `node-gyp` to use
78+ ENV PYTHON=/usr/bin/python3
79+
5080# Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend.
5181RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
5282 --mount=type=cache,target=/var/lib/apt,sharing=locked \
5383 apt-get update && \
5484 apt-get install -y --no-install-recommends python3 g++ build-essential && \
55- yarn config set python /usr/bin/python3
85+ rm -rf /var/lib/apt/lists/*
86+
5687
5788# From here on we use the least-privileged `node` user to run the backend.
5889USER node
5990
91+ ENV DOCKER_BUILDKIT=1
92+
6093# This should create the app dir as `node`.
6194# If it is instead created as `root` then the `tar` command below will
6295# fail: `can't create directory 'packages/': Permission denied`.
@@ -65,22 +98,36 @@ USER node
6598WORKDIR /app
6699
67100# Copy the install dependencies from the build stage and context
101+ COPY --from=build --chown=node:node /app/.yarn ./.yarn
102+ COPY --from=build --chown=node:node /app/.yarnrc.yml ./
103+ COPY --from=build --chown=node:node /app/backstage.json ./
68104COPY --from=build --chown=node:node /app/yarn.lock /app/package.json /app/packages/backend/dist/skeleton/ ./
69105
106+ # Pre-create and fix ownership for cache directory
107+ RUN mkdir -p /home/node/.cache/node/corepack/v1 && \
108+ chown -R node:node /home/node/.cache
109+
70110RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
71- yarn install --frozen-lockfile --production --network-timeout 600000
111+ yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)"
72112
73113# Copy the built packages from the build stage
74114COPY --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./
75115
76116ARG APP_ENV
77117
118+
78119# Copy any other files that we need at runtime, to understand how the configs work refer to the README.md
79- COPY --chown=node:node app-config.yaml ./
80- COPY --chown=node:node app-config.docker.yaml ./app-config.docker.yaml
81- COPY --chown=node:node app-config.${APP_ENV}.yaml ./app-config.env.yaml
120+ COPY --chown=node:node app-config*.yaml ./
121+ # COPY --chown=node:node app-config.docker.yaml ./app-config.docker.yaml
122+ # COPY --chown=node:node app-config.${APP_ENV}.yaml ./app-config.env.yaml
123+
124+ # This will include the examples, if you don't need these simply remove this line
125+ COPY --chown=node:node examples ./examples
82126
83127# This switches many Node.js dependencies to production mode. Important APP_ENV and NODE_ENV serve two different purposes
84128ENV NODE_ENV production
85129
130+ # This disables node snapshot for Node 20 to work with the Scaffolder
131+ ENV NODE_OPTIONS="--no-node-snapshot"
132+
86133CMD ["node" , "packages/backend" , "--config" , "app-config.yaml" , "--config" , "app-config.docker.yaml" , "--config" , "app-config.env.yaml" ]
0 commit comments