# Stage 1: Build
FROM node:24-alpine AS build
# Install build dependencies
RUN apk add --no-cache git python3 make g++ \
&& ln -sf /usr/bin/python3 /usr/bin/python
# Set working directory
WORKDIR /app
# Copy manifest files first to leverage cache
COPY package.json package-lock.json ./
# Fail early if lockfile or manifest is missing
RUN test -f package.json && test -f package-lock.json
# Copy the rest of the repository
COPY . .
# Install dependencies (including dev) to build the project
RUN npm ci
# Build GUI assets
RUN cd src/gui && npm run build && cd -
# Stage 2: Production
FROM node:24-alpine
# Install runtime dependencies
RUN apk add --no-cache curl
# Environment
ENV APP_PORT=4100
ENV NO_VAR_RUNTIME=1
# Working directory for the production image
WORKDIR /opt/puter/app
# Copy built artifacts and necessary source from the build stage
COPY --from=build /app/src/gui/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/tools ./tools
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/package-lock.json ./package-lock.json
# Copy additional runtime requirements from the build stage if needed
# (we rely on the node_modules installed in the build stage for runtime)
# Ensure proper permissions for the node user
# Use the existing 'node' user from the base image to avoid conflicts
USER node
EXPOSE 4100
# Robust healthcheck: try /health, then /test as a fallback
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s \
CMD sh -lc 'if curl -fsS http://127.0.0.1:4100/health; then exit 0; fi; if curl -fsS http://127.0.0.1:4100/test; then exit 0; fi; exit 1'
CMD ["node", "./tools/run-selfhosted.js"]