-
Notifications
You must be signed in to change notification settings - Fork 0
Add Docker Compose support for frontend + backend #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0b5f1b1
b07a40f
365e59e
282fc5f
2cf6e74
f50bbf5
1c05138
e6d82ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| node_modules | ||
| dist | ||
| dist-ssr | ||
| *.local | ||
| .git | ||
| .gitignore | ||
| *.md | ||
| .env | ||
| .env.local | ||
| .vscode | ||
| .idea | ||
| *.log | ||
| npm-debug.log* | ||
| bills.db | ||
| tmp |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # Frontend Dockerfile - Multi-stage build for lightweight image | ||
| FROM node:22-alpine AS builder | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy package files | ||
| COPY package*.json ./ | ||
|
|
||
| # Install dependencies | ||
| RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi | ||
|
|
||
| # Accept build arguments for API keys | ||
| ARG GEMINI_API_KEY | ||
| ARG OPENAI_API_KEY | ||
| ARG ANTHROPIC_API_KEY | ||
| ARG OLLAMA_HOST | ||
| ARG OLLAMA_MODEL | ||
| ARG OPENAI_MODEL | ||
| ARG ANTHROPIC_MODEL | ||
| ARG AI_SERVICE | ||
|
|
||
| # Set as environment variables for the build | ||
| ENV GEMINI_API_KEY=$GEMINI_API_KEY | ||
| ENV OPENAI_API_KEY=$OPENAI_API_KEY | ||
| ENV ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY | ||
| ENV OLLAMA_HOST=$OLLAMA_HOST | ||
| ENV OLLAMA_MODEL=$OLLAMA_MODEL | ||
| ENV OPENAI_MODEL=$OPENAI_MODEL | ||
| ENV ANTHROPIC_MODEL=$ANTHROPIC_MODEL | ||
| ENV AI_SERVICE=$AI_SERVICE | ||
| # Copy source files | ||
| COPY . . | ||
|
|
||
| # Build the application | ||
| RUN npm run build | ||
|
|
||
| # Production stage - serve with lightweight nginx | ||
| FROM nginx:alpine | ||
|
|
||
| # Copy built assets from builder stage | ||
| COPY --from=builder /app/dist /usr/share/nginx/html | ||
|
|
||
| # Copy custom nginx configuration | ||
| COPY nginx.conf /etc/nginx/conf.d/default.conf | ||
|
|
||
| # Expose port 80 | ||
| EXPOSE 80 | ||
|
|
||
| CMD ["nginx", "-g", "daemon off;"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| services: | ||
| frontend: | ||
| build: | ||
| context: . | ||
| dockerfile: Dockerfile | ||
| args: | ||
| - GEMINI_API_KEY=${GEMINI_API_KEY} | ||
| - OPENAI_API_KEY=${OPENAI_API_KEY} | ||
| - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} | ||
| - OLLAMA_HOST=${OLLAMA_HOST} | ||
| - OLLAMA_MODEL=${OLLAMA_MODEL} | ||
| - OPENAI_MODEL=${OPENAI_MODEL} | ||
| - ANTHROPIC_MODEL=${ANTHROPIC_MODEL} | ||
| - AI_SERVICE=${AI_SERVICE} | ||
| ports: | ||
| - "8080:80" | ||
| depends_on: | ||
| backend: | ||
| condition: service_healthy | ||
| environment: | ||
| - NODE_ENV=production | ||
| restart: unless-stopped | ||
|
Comment on lines
+2
to
+22
|
||
|
|
||
| backend: | ||
| build: | ||
| context: ./server | ||
| dockerfile: Dockerfile | ||
| volumes: | ||
| - billscan-data:/data | ||
| environment: | ||
| - NODE_ENV=production | ||
| - DATA_DIR=/data | ||
| healthcheck: | ||
| test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/bills"] | ||
|
Comment on lines
+33
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The backend healthcheck is defined as Useful? React with 👍 / 👎. |
||
| interval: 10s | ||
| timeout: 5s | ||
| retries: 3 | ||
| start_period: 10s | ||
| restart: unless-stopped | ||
|
|
||
| volumes: | ||
| billscan-data: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| server { | ||
| listen 80; | ||
| server_name localhost; | ||
| root /usr/share/nginx/html; | ||
| index index.html; | ||
|
|
||
|
Rikul marked this conversation as resolved.
|
||
| # Security headers | ||
| add_header X-Frame-Options "SAMEORIGIN" always; | ||
| add_header X-Content-Type-Options "nosniff" always; | ||
| add_header X-XSS-Protection "1; mode=block" always; | ||
| add_header Referrer-Policy "strict-origin-when-cross-origin" always; | ||
| # Enable gzip compression | ||
| gzip on; | ||
| gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; | ||
|
|
||
| # Handle SPA routing - redirect all requests to index.html | ||
| location / { | ||
| try_files $uri $uri/ /index.html; | ||
| } | ||
|
|
||
| # Proxy API requests to backend | ||
| location /api { | ||
| proxy_pass http://backend:3000; | ||
| proxy_http_version 1.1; | ||
| proxy_set_header Upgrade $http_upgrade; | ||
| proxy_set_header Connection 'upgrade'; | ||
| proxy_set_header Host $host; | ||
| proxy_set_header X-Real-IP $remote_addr; | ||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
| proxy_set_header X-Forwarded-Proto $scheme; | ||
| proxy_cache_bypass $http_upgrade; | ||
| # Increase body size limit for image uploads | ||
| client_max_body_size 50M; | ||
| } | ||
|
|
||
| # Cache static assets | ||
| location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { | ||
| expires 1y; | ||
| add_header Cache-Control "public, immutable"; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| node_modules | ||
| *.log | ||
| npm-debug.log* | ||
| bills.db | ||
| .git | ||
| .gitignore | ||
| *.md | ||
| tmp |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # Backend Dockerfile - Lightweight Node.js image | ||
| FROM node:22-alpine | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy package files | ||
| COPY package*.json ./ | ||
|
|
||
| # Install dependencies | ||
| RUN if [ -f package-lock.json ]; then npm ci --production; else npm install --production; fi | ||
|
|
||
| # Copy source files | ||
| COPY . . | ||
|
|
||
| # Create data directory for SQLite database persistence | ||
| RUN mkdir -p /data | ||
|
|
||
|
Rikul marked this conversation as resolved.
|
||
| # Create non-root user | ||
| RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001 | ||
| RUN chown -R nodejs:nodejs /app /data | ||
|
|
||
| # Switch to non-root user | ||
| USER nodejs | ||
| # Expose port 3000 | ||
| EXPOSE 3000 | ||
|
|
||
| # Start the server | ||
| CMD ["node", "index.js"] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Docker Quick Start section does not explain how to configure required API keys. Without API key configuration, the application will not function.
Add a note after line 59 explaining how to pass environment variables:
Then Docker Compose will automatically load these variables.
Then Docker Compose will automatically load these variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added step 1 to the Docker Quick Start section explaining how to create a
.envfile with API keys before runningdocker compose up. Commit: e6d82eaThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was already addressed in commit e6d82ea. The README now includes step 1 in the Docker Quick Start section that explains how to create a
.envfile with API keys before runningdocker compose up. See lines 57-63 in README.md.