Skip to content

Add Docker Compose support for frontend + backend - #7

Merged
Rikul merged 8 commits into
mainfrom
copilot/add-lightweight-docker-container
Nov 26, 2025
Merged

Add Docker Compose support for frontend + backend#7
Rikul merged 8 commits into
mainfrom
copilot/add-lightweight-docker-container

Conversation

Copilot AI commented Nov 26, 2025

Copy link
Copy Markdown
Contributor

Adds containerized deployment via docker compose up with lightweight Alpine-based images.

Changes

  • Frontend Dockerfile: Multi-stage build (node:22-alpine → nginx:alpine, ~30MB final) with build-time API key support
  • Backend Dockerfile: node:22-alpine with production dependencies, non-root user, and health check endpoint
  • docker-compose.yml: Orchestrates services with persistent volume for SQLite, health check-based startup ordering, and API key configuration via .env file
  • nginx.conf: SPA routing, API proxy to backend, 50MB upload limit, security headers
  • server/db.js: Added DATA_DIR env var support for volume-mounted database

Usage

  1. Create a .env file with your API keys:
GEMINI_API_KEY=your_key_here
AI_SERVICE=gemini
  1. Build and run:
docker compose up --build
# Frontend: http://localhost:8080
# Backend API: http://localhost:8080/api (proxied through frontend)

Data persists in billscan-data volume across restarts.

Original prompt

Can you create lightweight docker container to run frontend + backend. Users shoud be able to docker compose up


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: Rikul <1149512+Rikul@users.noreply.github.com>
Copilot AI changed the title [WIP] Add lightweight Docker container for frontend and backend Add Docker Compose support for frontend + backend Nov 26, 2025
Copilot AI requested a review from Rikul November 26, 2025 05:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Docker containerization support for BillScan, enabling users to deploy the application using docker compose up. The implementation uses lightweight Alpine-based images with a multi-stage build for the frontend and includes data persistence via Docker volumes.

Key changes:

  • Multi-stage frontend Dockerfile producing a ~30MB nginx-served static site
  • Backend Dockerfile with node:22-alpine and configurable database location
  • Docker Compose orchestration with persistent volume for SQLite data

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
Dockerfile Frontend multi-stage build (Node.js build → nginx serve)
server/Dockerfile Backend Node.js container with production dependencies
docker-compose.yml Orchestrates frontend + backend services with data volume
nginx.conf Configures SPA routing, API proxy, and upload limits
server/db.js Adds DATA_DIR environment variable for volume-mounted database
.dockerignore Excludes build artifacts and sensitive files from frontend image
server/.dockerignore Excludes build artifacts and database from backend image
README.md Documents Docker deployment workflow and architecture

Critical issue: The Docker setup is missing environment variable configuration for AI service API keys, which are required for the application to function. API keys need to be passed as build arguments to the frontend (since Vite embeds them at build time) and configured in docker-compose.yml.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment thread README.md Outdated
Comment thread docker-compose.yml
Comment on lines +2 to +12
frontend:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:80"
depends_on:
- backend
environment:
- NODE_ENV=production
restart: unless-stopped

Copilot AI Nov 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Docker setup is missing environment variable configuration for AI service API keys. According to the README, BillScan requires API keys (e.g., GEMINI_API_KEY, OPENAI_API_KEY, etc.) to function. These need to be passed as build arguments to the frontend Dockerfile and configured in the docker-compose.yml.

Suggested fix for docker-compose.yml frontend service:

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}

And in the Dockerfile, add ARG declarations before the build step and pass them as environment variables during the build.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added build args for all AI service API keys to the frontend service in docker-compose.yml. Users can now configure API keys via a .env file, and they'll be passed as build arguments during the Docker build. Commit: e6d82ea

Comment thread docker-compose.yml Outdated
Comment on lines +8 to +9
depends_on:
- backend

Copilot AI Nov 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The depends_on configuration only ensures the backend container starts before the frontend, but doesn't wait for the backend service to be ready to accept connections. This can cause issues during initial startup.

Consider adding a health check to the backend service and using condition: service_healthy:

backend:
  # ... existing config ...
  healthcheck:
    test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/bills"]
    interval: 10s
    timeout: 5s
    retries: 3
    start_period: 10s

frontend:
  # ... existing config ...
  depends_on:
    backend:
      condition: service_healthy

This ensures the frontend only starts after the backend is accepting requests.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added health check to the backend service with condition: service_healthy for the frontend's depends_on. The backend now waits for /api/bills to respond before the frontend starts. Commit: e6d82ea

Comment thread nginx.conf
Comment thread server/Dockerfile Outdated
Comment on lines +7 to +10
COPY package.json ./

# Install dependencies
RUN npm install --production

Copilot AI Nov 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider copying package-lock.json if it exists and using npm ci instead of npm install for more reproducible builds. While package-lock.json is currently in .gitignore, using npm ci when the lock file exists provides better build consistency.

Change line 7 to:

COPY package*.json ./

And line 10 to:

RUN if [ -f package-lock.json ]; then npm ci --production; else npm install --production; fi
Suggested change
COPY package.json ./
# Install dependencies
RUN npm install --production
COPY package*.json ./
# Install dependencies
RUN if [ -f package-lock.json ]; then npm ci --production; else npm install --production; fi

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use COPY package*.json ./ and conditional npm ci --production when a lock file exists. Commit: e6d82ea

Comment thread Dockerfile
Comment thread docker-compose.yml Outdated
Comment thread README.md
```bash
docker compose up --build
```

Copilot AI Nov 26, 2025

Copy link

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:

**Important:** Before running, create a `.env` file in the project root with your API keys:
```bash
# .env file
GEMINI_API_KEY=your_key_here
AI_SERVICE=gemini
# Add other keys as needed (see AI Service Configuration)

Then Docker Compose will automatically load these variables.

```suggestion

   **Important:** Before running, create a `.env` file in the project root with your API keys:
   ```bash
   # .env file
   GEMINI_API_KEY=your_key_here
   AI_SERVICE=gemini
   # Add other keys as needed (see AI Service Configuration)

Then Docker Compose will automatically load these variables.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

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 .env file with API keys before running docker compose up. Commit: e6d82ea

Copy link
Copy Markdown
Owner

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

Copy link
Copy Markdown
Contributor Author

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 .env file with API keys before running docker compose up. See lines 57-63 in README.md.

Comment thread server/Dockerfile
Comment thread Dockerfile Outdated
Comment on lines +7 to +10
COPY package.json ./

# Install dependencies
RUN npm install

Copilot AI Nov 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider copying package-lock.json if it exists and using npm ci instead of npm install for more reproducible builds. While package-lock.json is currently in .gitignore, using npm ci when the lock file exists provides better build consistency.

Change line 7 to:

COPY package*.json ./

And line 10 to:

RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
Suggested change
COPY package.json ./
# Install dependencies
RUN npm install
COPY package*.json ./
# Install dependencies
RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use COPY package*.json ./ and conditional npm ci when a lock file exists. Commit: e6d82ea

Rikul and others added 5 commits November 26, 2025 12:02
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… npm ci support

Co-authored-by: Rikul <1149512+Rikul@users.noreply.github.com>
@Rikul
Rikul marked this pull request as ready for review November 26, 2025 21:49
@Rikul
Rikul merged commit 3ea9e7a into main Nov 26, 2025
1 check passed
@Rikul
Rikul deleted the copilot/add-lightweight-docker-container branch November 26, 2025 21:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docker-compose.yml
Comment on lines +33 to +34
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/bills"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fix backend healthcheck command for alpine base

The backend healthcheck is defined as wget --no-verbose --tries=1 --spider http://localhost:3000/api/bills, but the backend image is built on node:22-alpine (see server/Dockerfile line 2), which ships BusyBox wget that lacks the --no-verbose flag. BusyBox exits with an error on that option, so the healthcheck fails even when the API is healthy, keeping the backend in an unhealthy state and preventing the frontend from starting because depends_on waits for a healthy backend.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants