ARG NODE_VERSION=26.12.1
FROM node:${NODE_VERSION}-alpine AS builder
RUN apk --no-cache add python3 py3-setuptools build-base
WORKDIR /directus
COPY package.json .
RUN npm install --global "$(node -p "require('./package.json').packageManager")"
RUN chown node:node .
USER node
ENV NODE_OPTIONS=--max-old-space-size=8192
COPY --chown=node:node pnpm-lock.yaml pnpm-workspace.yaml ./
RUN pnpm fetch
COPY --chown=node:node . .
RUN <<EOF
set -ex
pnpm install --recursive --offline --frozen-lockfile
pnpm_config_workspace_concurrency=2 pnpm --recursive --filter '!e2e' run build
pnpm --filter directus deploy --legacy --prod dist
cd dist
node -e '
const f = "package.json", {name, version, type, exports, bin} = require(`./${f}`), {packageManager} = require(`../${f}`);
fs.writeFileSync(f, JSON.stringify({name, version, type, exports, bin, packageManager}, null, 2));
'
mkdir -p database extensions uploads
EOF
FROM node:${NODE_VERSION}-alpine AS runtime
RUN apk --no-cache upgrade \
&& rm -rf \
/usr/local/lib/node_modules/npm \
/usr/local/lib/node_modules/corepack \
/usr/local/bin/npm \
/usr/local/bin/npx \
/usr/local/bin/corepack \
/root/.npm
USER node
WORKDIR /directus
ENV \
DB_CLIENT="sqlite3" \
DB_FILENAME="/directus/database/database.sqlite" \
NODE_ENV="production" \
NPM_CONFIG_UPDATE_NOTIFIER="false"
COPY --from=builder --chown=node:node /directus/ecosystem.config.cjs .
COPY --from=builder --chown=node:node /directus/dist .
COPY --chown=node:node docker-entrypoint.cjs .
USER root
RUN ln -s /directus/node_modules/.pnpm/pm2@*/node_modules/pm2/bin/pm2 /usr/local/bin/pm2
USER node
EXPOSE 8055
CMD ["node", "docker-entrypoint.cjs"]