diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2b2a06e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,82 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build output +dist/ +build/ + +# Git +.git/ +.gitignore + +# Environment files +.env +.env.* +!.env.example + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +logs/ +*.log + +# Runtime data +pids/ +*.pid +*.seed +*.pid.lock + +# Coverage directory +coverage/ +*.lcov + +# Temporary folders +tmp/ +temp/ + +# Documentation +docs/ +ai_context/ +README.md +CONTRIBUTING.md +CODE_OF_CONDUCT.md +LICENSE +SECURITY.md + +# Package manager files +package-lock.json +.yarn-integrity +.yarn/ + +# TypeScript +*.tsbuildinfo + +# Cache +.cache/ +.parcel-cache/ +.eslintcache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Testing +test/ +tests/ +__tests__/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7be3254 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# Multi-stage build for Unthread Webhook Server + +# Build stage +FROM node:20-alpine AS builder + +# Set working directory +WORKDIR /app + +# Copy package manager files +COPY package.json yarn.lock .yarnrc ./ + +# Install all dependencies (including devDependencies for building) +RUN yarn install --frozen-lockfile --ignore-scripts + +# Copy source code and build configuration +COPY src/ ./src/ +COPY tsconfig.json ./ + +# Build the TypeScript application +RUN yarn build + +# Production stage +FROM node:20-alpine AS production + +# Set working directory +WORKDIR /app + +# Copy package manager files +COPY package.json yarn.lock .yarnrc ./ + +# Set environment to production +ENV NODE_ENV=production +# Install only production dependencies +RUN yarn config set strict-ssl false && \ + yarn install --frozen-lockfile --production --ignore-scripts && \ + yarn cache clean + +# Copy built application from builder stage +COPY --from=builder /app/dist ./dist + +# Copy environment example (for reference) +COPY .env.example ./ + +# Create non-root user for security +RUN addgroup -g 1001 -S nodejs && \ + adduser -S nodejs -u 1001 + +# Change ownership of the app directory to nodejs user +RUN chown -R nodejs:nodejs /app +USER nodejs + +# Expose the port the app runs on +EXPOSE 3000 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) }).on('error', () => process.exit(1))" + +# Start the application +CMD ["node", "dist/app.js"] \ No newline at end of file