48 lines
2.1 KiB
Docker
48 lines
2.1 KiB
Docker
# syntax=docker/dockerfile:1.7
|
|
|
|
# ---- Build stage: compile TypeScript ----
|
|
FROM node:20-alpine AS builder
|
|
ENV COREPACK_DEFAULT_TO_LATEST=0
|
|
RUN corepack enable && corepack prepare pnpm@10.15.1 --activate
|
|
RUN apk add --no-cache python3 make g++
|
|
WORKDIR /build
|
|
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml tsconfig.base.json ./
|
|
COPY apps/server/package.json ./apps/server/
|
|
COPY apps/web/package.json ./apps/web/
|
|
COPY apps/booterm/package.json ./apps/booterm/
|
|
RUN pnpm install --frozen-lockfile
|
|
COPY apps/booterm ./apps/booterm
|
|
RUN pnpm --filter=@boocode/booterm build
|
|
|
|
# ---- Prod-deps stage: hoisted, native built via npm rebuild ----
|
|
FROM node:20-alpine AS proddeps
|
|
ENV COREPACK_DEFAULT_TO_LATEST=0
|
|
RUN corepack enable && corepack prepare pnpm@10.15.1 --activate
|
|
RUN apk add --no-cache python3 make g++
|
|
WORKDIR /prod
|
|
COPY apps/booterm/package.json ./package.json
|
|
RUN pnpm install --prod --config.node-linker=hoisted --config.strict-peer-dependencies=false
|
|
# pnpm 10 ignores build scripts; force compile with npm directly.
|
|
# node-gyp is bundled with npm in the node:20-alpine image.
|
|
RUN cd node_modules/node-pty && npm run install
|
|
# Sanity check — fail the build if the artifact still isn't there
|
|
RUN test -f node_modules/node-pty/build/Release/pty.node && echo "pty.node OK" || (echo "pty.node MISSING" && exit 1)
|
|
|
|
# ---- Runtime ----
|
|
FROM node:20-alpine AS runtime
|
|
RUN apk add --no-cache tmux libstdc++ bash su-exec shadow
|
|
# v1.10.1: terminal shells inside tmux drop privs to samkintop via su-exec.
|
|
# Mirror uid/gid 1000:1000 from the host so the bind-mounted /home/samkintop
|
|
# (added in docker-compose) is owned by the user from the container's view.
|
|
RUN deluser --remove-home node 2>/dev/null; delgroup node 2>/dev/null; \
|
|
addgroup -g 1000 samkintop && \
|
|
adduser -D -u 1000 -G samkintop -s /bin/bash samkintop
|
|
WORKDIR /app
|
|
COPY --from=builder /build/apps/booterm/dist ./dist
|
|
COPY --from=proddeps /prod/package.json ./package.json
|
|
COPY --from=proddeps /prod/node_modules ./node_modules
|
|
COPY apps/booterm/tmux.conf /etc/booterm/tmux.conf
|
|
ENV NODE_ENV=production
|
|
EXPOSE 3000
|
|
CMD ["node", "dist/index.js"]
|