1+ # DO NOT USE THIS IN PRODUCTION
2+ #
3+ # This Dockerfile builds a Docker image for a pre-configured Backstage instance
4+ # with the Stack Overflow plugins installed. It’s designed as a quick way to try
5+ # out the integration without having to set it up yourself.
6+ #
7+ # This is not intended for production use.
8+
9+ # Stage 1 - Create yarn install skeleton layer
10+ FROM node:20-bookworm-slim AS packages
11+
12+ WORKDIR /app
13+ COPY backstage.json package.json yarn.lock ./
14+ COPY .yarn ./.yarn
15+ COPY .yarnrc.yml ./
16+
17+ COPY packages packages
18+
19+ # Comment this out if you don't have any internal plugins
20+ COPY plugins plugins
21+
22+ RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+
23+
24+ # Stage 2 - Install dependencies and build packages
25+ FROM node:20-bookworm-slim AS build
26+
27+ # Set Python interpreter for `node-gyp` to use
28+ ENV PYTHON=/usr/bin/python3
29+
30+ # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend.
31+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
32+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
33+ apt-get update && \
34+ apt-get install -y --no-install-recommends python3 g++ build-essential && \
35+ rm -rf /var/lib/apt/lists/*
36+
37+ # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image,
38+ # in which case you should also move better-sqlite3 to "devDependencies" in package.json.
39+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
40+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
41+ apt-get update && \
42+ apt-get install -y --no-install-recommends libsqlite3-dev && \
43+ rm -rf /var/lib/apt/lists/*
44+
45+ USER node
46+ WORKDIR /app
47+
48+ COPY --from=packages --chown=node:node /app .
49+
50+ RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
51+ yarn install --immutable
52+
53+ COPY --chown=node:node . .
54+
55+ RUN yarn tsc
56+ RUN yarn --cwd packages/backend build
57+
58+ RUN mkdir packages/backend/dist/skeleton packages/backend/dist/bundle \
59+ && tar xzf packages/backend/dist/skeleton.tar.gz -C packages/backend/dist/skeleton \
60+ && tar xzf packages/backend/dist/bundle.tar.gz -C packages/backend/dist/bundle
61+
62+ # Stage 3 - Build the actual backend image and install production dependencies
63+ FROM node:20-bookworm-slim
64+
65+ # Set Python interpreter for `node-gyp` to use
66+ ENV PYTHON=/usr/bin/python3
67+
68+ # Install isolate-vm dependencies, these are needed by the @backstage/plugin-scaffolder-backend.
69+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
70+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
71+ apt-get update && \
72+ apt-get install -y --no-install-recommends python3 g++ build-essential && \
73+ rm -rf /var/lib/apt/lists/*
74+
75+ # Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image,
76+ # in which case you should also move better-sqlite3 to "devDependencies" in package.json.
77+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
78+ --mount=type=cache,target=/var/lib/apt,sharing=locked \
79+ apt-get update && \
80+ apt-get install -y --no-install-recommends libsqlite3-dev && \
81+ rm -rf /var/lib/apt/lists/*
82+
83+ # From here on we use the least-privileged `node` user to run the backend.
84+ USER node
85+
86+ # This should create the app dir as `node`.
87+ # If it is instead created as `root` then the `tar` command below will
88+ # fail: `can't create directory 'packages/': Permission denied`.
89+ # If this occurs, then ensure BuildKit is enabled (`DOCKER_BUILDKIT=1`)
90+ # so the app dir is correctly created as `node`.
91+ WORKDIR /app
92+
93+ # Copy the install dependencies from the build stage and context
94+ COPY --from=build --chown=node:node /app/.yarn ./.yarn
95+ COPY --from=build --chown=node:node /app/.yarnrc.yml ./
96+ COPY --from=build --chown=node:node /app/backstage.json ./
97+ COPY --from=build --chown=node:node /app/yarn.lock /app/package.json /app/packages/backend/dist/skeleton/ ./
98+
99+ # Note: The skeleton bundle only includes package.json files -- if your app has
100+ # plugins that define a `bin` export, the bin files need to be copied as well to
101+ # be linked in node_modules/.bin during yarn install.
102+
103+ RUN --mount=type=cache,target=/home/node/.cache/yarn,sharing=locked,uid=1000,gid=1000 \
104+ yarn workspaces focus --all --production && rm -rf "$(yarn cache clean)"
105+
106+ # Copy the built packages from the build stage
107+ COPY --from=build --chown=node:node /app/packages/backend/dist/bundle/ ./
108+
109+ # Copy any other files that we need at runtime
110+ COPY --chown=node:node app-config*.yaml ./
111+
112+ # This will include the examples, if you don't need these simply remove this line
113+ COPY --chown=node:node examples ./examples
114+
115+ # This switches many Node.js dependencies to production mode.
116+ ENV NODE_ENV=development
117+
118+ # This disables node snapshot for Node 20 to work with the Scaffolder
119+ ENV NODE_OPTIONS="--no-node-snapshot"
120+
121+ CMD ["node" , "packages/backend" , "--config" , "app-config.docker-local.yaml" ]
0 commit comments