diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3c24b9d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +node_modules +npm-debug.log +logs +./logs +.git +.gitignore +.github +.idea +.vscode +.env +./config/.env +Dockerfile* +.dockerignore +README.md diff --git a/Dockerfile b/Dockerfile index bf2e7e7..298a66f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,35 @@ -# Use the official Node.js image as a base -FROM node:18 +# Stage 1: Build & install production dependencies +FROM node:20-alpine AS dependencies -# Set the working directory in the container WORKDIR /app -# Copy package.json and package-lock.json to the container COPY package*.json ./ -# Install dependencies -RUN npm install +RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force -# Copy the rest of the application code -COPY . . +# Stage 2: Production runner +FROM node:20-alpine AS runner -# Expose the application port +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 + +# Install dumb-init for robust signal handling (PID 1) +RUN apk add --no-cache dumb-init && mkdir -p /app/uploads && chown -R node:node /app + +# Switch to non-root user +USER node + +# Copy production node_modules with ownership +COPY --chown=node:node --from=dependencies /app/node_modules ./node_modules + +# Copy application source code with ownership +COPY --chown=node:node . . + +# Expose backend port EXPOSE 3000 -# Start the application -CMD ["npm", "start"] +# Run container with dumb-init +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD ["node", "app.js"]