diff --git a/api/.env.development b/api/.env.development new file mode 100644 index 0000000..e797c94 --- /dev/null +++ b/api/.env.development @@ -0,0 +1,12 @@ +SUPABASE_URL=https://mhcafqvzbrrwvahpvvzd.supabase.co +SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1oY2FmcXZ6YnJyd3ZhaHB2dnpkIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0MTI0MTMyMSwiZXhwIjoyMDU2ODE3MzIxfQ.9r33CUsu6ZR4vyv4ed-UY6cLE1FZzSSxTNE8pFUKjN4 + +STREAM_CHAT_API_KEY=t5vvvddteapa +STREAM_CHAT_API_SECRET=zrr32sqenw3atpv9rnz2nhhyyncf7bunr7fmfqy9r7e69fcw978dhzevmhpxa2jj + +FRONTEND_URL=http://localhost:5173 + +EMAIL_USER="baptiste@xtablo.com" +EMAIL_KEY="jayf pzpj nrsv vtim" + +XTABLO_URL="https://xtablo-ui-dev.arbelleville.workers.dev" diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..9cc6338 --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,105 @@ +# ============================================================================== +# Base stage - Common dependencies and setup +# ============================================================================== +FROM node:18-alpine AS base + +# Build argument for NODE_ENV +ARG NODE_ENV=production + +# Install security updates +RUN apk --no-cache upgrade + +# Create app directory and set up non-root user +WORKDIR /app +RUN addgroup -g 1001 -S nodejs +RUN adduser -S nodejs -u 1001 + +# Copy package files +COPY package*.json ./ + +# ============================================================================== +# Dependencies stage - Install all dependencies +# ============================================================================== +FROM base AS deps + +# Install all dependencies (including devDependencies for build) +RUN npm ci + +# ============================================================================== +# Build stage - Compile TypeScript +# ============================================================================== +FROM deps AS build + +# Copy source code +COPY . . + +# Build the application +RUN npm run build + +# ============================================================================== +# Production dependencies stage - Install only production dependencies +# ============================================================================== +FROM base AS prod-deps + +# Install only production dependencies +RUN npm ci --only=production && npm cache clean --force + +# ============================================================================== +# Staging stage - For staging environment +# ============================================================================== +FROM base AS staging + +# Copy production dependencies +COPY --from=prod-deps /app/node_modules ./node_modules + +# Copy built application +COPY --from=build /app/dist ./dist +COPY --from=build /app/package*.json ./ + +# Copy environment files +COPY --from=build /app/.env* ./ + +# Change ownership to nodejs user +RUN chown -R nodejs:nodejs /app + +# Switch to non-root user +USER nodejs + +# Expose port +EXPOSE 8080 + +# Set staging environment. TODO: Change to staging when it's ready. +ENV NODE_ENV=development + +# Start the application +CMD ["npm", "start"] + +# ============================================================================== +# Production stage - For production environment (default) +# ============================================================================== +FROM base AS production + +# Copy production dependencies +COPY --from=prod-deps /app/node_modules ./node_modules + +# Copy built application +COPY --from=build /app/dist ./dist +COPY --from=build /app/package*.json ./ + +# Copy environment files +COPY --from=build /app/.env* ./ + +# Change ownership to nodejs user +RUN chown -R nodejs:nodejs /app + +# Switch to non-root user +USER nodejs + +# Expose port +EXPOSE 8080 + +# Set production environment +ENV NODE_ENV=production + +# Start the application +CMD ["npm", "start"] \ No newline at end of file diff --git a/api/cloudbuild.yaml b/api/cloudbuild.yaml new file mode 100644 index 0000000..69925be --- /dev/null +++ b/api/cloudbuild.yaml @@ -0,0 +1,6 @@ +steps: +- name: 'gcr.io/cloud-builders/docker' + args: [ 'build', '--target', '$_NODE_ENV', '-t', 'europe-west1-docker.pkg.dev/$_AR_PROJECT_ID/$_AR_REPOSITORY/xtablo-source/xtablo-api', '.' ] + +# substitutions: +# _AR_ENV: 'production' \ No newline at end of file diff --git a/api/package.json b/api/package.json index b3f4bb6..a7da68b 100644 --- a/api/package.json +++ b/api/package.json @@ -4,7 +4,7 @@ "scripts": { "dev": "NODE_ENV=development tsx watch src/index.ts", "build": "tsc", - "start": "NODE_ENV=production node dist/index.js" + "start": "node dist/index.js" }, "dependencies": { "@hono/node-server": "^1.14.4", diff --git a/api/src/config.ts b/api/src/config.ts index cd4df4b..9ae4334 100644 --- a/api/src/config.ts +++ b/api/src/config.ts @@ -1,3 +1,5 @@ +import dotenv from "dotenv"; + export interface AppConfig { NODE_ENV: "development" | "production" | "test"; PORT: number; @@ -21,6 +23,8 @@ function validateEnvVar(name: string, value: string | undefined): string { } function createConfig(): AppConfig { + dotenv.config({ path: `.env.${process.env.NODE_ENV}` }); + const NODE_ENV = (process.env.NODE_ENV || "development") as | "development" | "production" diff --git a/api/src/index.ts b/api/src/index.ts index d54d482..4f2b310 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -1,5 +1,3 @@ -import "dotenv/config"; - import { Hono } from "hono"; import { serve } from "@hono/node-server"; import { logger } from "hono/logger"; diff --git a/ui/.env.production b/ui/.env.production index 134e2e8..6adb937 100644 --- a/ui/.env.production +++ b/ui/.env.production @@ -4,6 +4,6 @@ VITE_SUPABASE_URL=https://mhcafqvzbrrwvahpvvzd.supabase.co VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1oY2FmcXZ6YnJyd3ZhaHB2dnpkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDEyNDEzMjEsImV4cCI6MjA1NjgxNzMyMX0.Otxn5BWCPD2ABlMM59hCgeur9Tf_Q7PndAbTkqXDPtM VITE_SUPABASE_ID=mhcafqvzbrrwvahpvvzd -VITE_STREAM_CHAT_API_KEY="t5vvvddteapa" +VITE_STREAM_CHAT_API_KEY="v4yf8rs94aa8" VITE_API_URL=https://xablo-api-636270553187.europe-west1.run.app \ No newline at end of file