# Stage 1: Build TypeScript FROM node:22-alpine AS builder RUN corepack enable && corepack prepare pnpm@9.15.0 --activate WORKDIR /app # Copy workspace config and package manifests COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json tsconfig.json ./ COPY src/shared/package.json src/shared/tsconfig.json src/shared/ COPY src/bastion/package.json src/bastion/tsconfig.json src/bastion/ COPY src/cli/package.json src/cli/tsconfig.json src/cli/ # Install all dependencies RUN pnpm install --frozen-lockfile # Copy source code COPY src/shared/src/ src/shared/src/ COPY src/bastion/src/ src/bastion/src/ COPY src/cli/src/ src/cli/src/ # Build TypeScript RUN pnpm build # Stage 2: Production runtime FROM fedora:43 # Install system dependencies RUN dnf install -y \ dnsmasq \ ipxe-bootimgs-x86 \ ipxe-bootimgs-aarch64 \ curl \ openssh-clients \ nodejs \ npm \ && dnf clean all # Install pnpm RUN npm install -g pnpm@9 # Create app directory WORKDIR /app # Copy workspace config, manifests, and lockfile COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./ COPY src/shared/package.json src/shared/ COPY src/bastion/package.json src/bastion/ COPY src/cli/package.json src/cli/ # Install production dependencies RUN pnpm install --frozen-lockfile --prod 2>/dev/null || pnpm install --prod # Copy built output from builder COPY --from=builder /app/src/shared/dist/ src/shared/dist/ COPY --from=builder /app/src/bastion/dist/ src/bastion/dist/ COPY --from=builder /app/src/cli/dist/ src/cli/dist/ # Create data directories RUN mkdir -p /data/state /data/tftp /data/http ENV BASTION_DIR=/data ENV HTTP_PORT=8080 EXPOSE 8080/tcp EXPOSE 67/udp EXPOSE 69/udp EXPOSE 4011/udp ENTRYPOINT ["node", "src/cli/dist/index.js", "init", "bastion", "standalone", "start"]