Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Docker Build and Test

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build Backend
run: |
cd Backend
docker build -t inpactai-backend:test .

- name: Build Frontend
run: |
cd Frontend
docker build -t inpactai-frontend:test .

Comment on lines +20 to +29
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The workflow builds Backend and Frontend images separately with custom tags, but then runs 'docker compose up' which will rebuild the images again according to docker-compose.yml, ignoring the previously built images. Either use the pre-built images or remove the separate build steps to avoid redundant builds.

Suggested change
- name: Build Backend
run: |
cd Backend
docker build -t inpactai-backend:test .
- name: Build Frontend
run: |
cd Frontend
docker build -t inpactai-frontend:test .

Copilot uses AI. Check for mistakes.
- name: Start services
run: |
docker compose up -d
sleep 30
Comment on lines +30 to +33
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The CI workflow attempts to start services with docker compose but doesn't provide the required .env files. The compose configuration depends on Backend/.env and Frontend/.env, which won't exist in the CI environment, causing the services to fail to start. Consider creating example .env files or using environment variables in the workflow.

Copilot uses AI. Check for mistakes.

- name: Check backend health
run: |
curl -f http://localhost:8000/ || exit 1

- name: Check frontend health
run: |
curl -f http://localhost:5173/ || exit 1
Comment on lines +30 to +41
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

CI will fail without environment setup and uses fragile health checks.

The workflow starts services without creating required .env files, which will likely cause startup failures. Additionally, the arbitrary sleep 30 is fragile and doesn't guarantee services are ready.

Apply this diff to fix the issues:

+    - name: Setup environment files
+      run: |
+        cp Backend/.env.example Backend/.env
+        cp Frontend/.env.example Frontend/.env
+        # Set minimal test credentials
+        echo "REDIS_HOST=redis" >> Backend/.env
+        echo "REDIS_PORT=6379" >> Backend/.env
+        
     - name: Start services
       run: |
         docker compose up -d
-        sleep 30
+        
+    - name: Wait for services to be healthy
+      run: |
+        timeout 120 bash -c 'until docker compose ps | grep -q "healthy"; do sleep 2; done' || true
+        docker compose ps
         
     - name: Check backend health
       run: |
-        curl -f http://localhost:8000/ || exit 1
+        timeout 30 bash -c 'until curl -f http://localhost:8000/; do sleep 2; done'
         
     - name: Check frontend health
       run: |
-        curl -f http://localhost:5173/ || exit 1
+        timeout 30 bash -c 'until curl -f http://localhost:5173/; do sleep 2; done'

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/docker-build.yml around lines 30-41: the job currently calls
"docker compose up -d" then uses a brittle "sleep 30" and single curl checks,
and it doesn't create required .env files; change this to first create/populate
required environment files (e.g., copy .env.example to .env or write secrets
from GitHub Secrets) before bringing services up, run "docker compose up --build
-d" and then replace the fixed sleep with a robust waiting loop that polls the
backend and frontend health endpoints with curl retries and a timeout (e.g.,
loop until curl -f succeeds or a timeout is reached, with short sleeps between
attempts), and ensure the step fails if services don't become healthy within the
timeout so CI fails fast.


- name: Show logs on failure
if: failure()
run: |
docker compose logs

- name: Cleanup
if: always()
run: |
docker compose down -v
21 changes: 21 additions & 0 deletions Backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
__pycache__
*.pyc
*.pyo
*.pyd
.Python
*.so
.env
.venv
Comment on lines +7 to +8
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The .env file is excluded from Docker context, which is correct. However, the configuration depends on the .env file being present on the host, and there's no validation that it exists before the build. Consider adding a check in the Dockerfile or documenting this requirement more clearly in the error messages.

Suggested change
.env
.venv

Copilot uses AI. Check for mistakes.
env/
venv/
ENV/
.git
.gitignore
.pytest_cache
.coverage
htmlcov/
dist/
build/
*.egg-info/
.DS_Store
*.log
12 changes: 12 additions & 0 deletions Backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
user=postgres
password=your_postgres_password
host=your_postgres_host
port=5432
dbname=postgres
GROQ_API_KEY=your_groq_api_key
SUPABASE_URL=your_supabase_url
SUPABASE_KEY=your_supabase_key
GEMINI_API_KEY=your_gemini_api_key
YOUTUBE_API_KEY=your_youtube_api_key
REDIS_HOST=redis
REDIS_PORT=6379
18 changes: 18 additions & 0 deletions Backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.10-slim

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
curl \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
Comment on lines +1 to +18
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add non-root user for security.

The container currently runs as root, which is a security risk even in development environments. Running as a non-privileged user follows the principle of least privilege.

Apply this diff to add a non-root user:

 FROM python:3.10-slim
 
 WORKDIR /app
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
     gcc \
     libpq-dev \
     curl \
     && rm -rf /var/lib/apt/lists/*
 
 COPY requirements.txt .
 RUN pip install --no-cache-dir -r requirements.txt
 
+RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
+USER appuser
+
 COPY . .
 
 EXPOSE 8000
 
 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM python:3.10-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
FROM python:3.10-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
🤖 Prompt for AI Agents
In Backend/Dockerfile around lines 1 to 18, the image runs as root which is a
security risk; update the Dockerfile to create a non-root user and switch to it:
add steps to create a user and group (e.g., appuser), ensure /app ownership is
set to that user (chown -R), and use USER to switch to the non-privileged
account before CMD; keep installation steps that require root before
creating/switching, and do not run the final CMD as root.

33 changes: 33 additions & 0 deletions Backend/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
FROM python:3.10-slim AS builder

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.10-slim

WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd -r appuser && useradd -r -g appuser appuser

COPY --from=builder /root/.local /root/.local
COPY . .

RUN chown -R appuser:appuser /app

USER appuser

ENV PATH=/root/.local/bin:$PATH
Comment on lines +22 to +29
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Non-root user cannot access packages in /root/.local.

The builder installs packages to /root/.local, but the runtime container switches to appuser at Line 27. The non-root user cannot read /root/.local, causing the application to fail at startup when attempting to import packages or execute uvicorn.

Apply this diff to install packages to a location accessible by appuser:

-COPY --from=builder /root/.local /root/.local
+COPY --from=builder --chown=appuser:appuser /root/.local /home/appuser/.local
 COPY . .
 
 RUN chown -R appuser:appuser /app
 
 USER appuser
 
-ENV PATH=/root/.local/bin:$PATH
+ENV PATH=/home/appuser/.local/bin:$PATH
🤖 Prompt for AI Agents
In Backend/Dockerfile.prod around lines 22 to 29, the runtime switches to USER
appuser but the builder-installed packages were copied to /root/.local which
appuser cannot access; fix by copying the builder .local into a location owned
by appuser (e.g. /home/appuser/.local), chown that directory to appuser, and
update PATH to include that bin directory. Concretely: copy --from=builder
/root/.local /home/appuser/.local (or move install target during build), run
chown -R appuser:appuser /home/appuser/.local (and keep chown -R appuser:appuser
/app), keep USER appuser, and set ENV PATH=/home/appuser/.local/bin:$PATH so
uvicorn and other packages are executable by the non-root user.

Comment on lines +22 to +29
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The production Dockerfile sets USER to 'appuser' but then tries to use the root user's local Python packages with PATH=/root/.local/bin. This will cause permission issues since appuser won't have access to /root/.local. The COPY command should use the builder's packages and the PATH should reference the appuser's home directory instead.

Copilot uses AI. Check for mistakes.

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
6 changes: 5 additions & 1 deletion Backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ async def lifespan(app: FastAPI):
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_origins=[
"http://localhost:5173",
"http://frontend:5173",
"http://127.0.0.1:5173"
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
Expand Down
175 changes: 175 additions & 0 deletions DOCKER-ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Docker Architecture Diagram

```
┌─────────────────────────────────────────────────────────────────────┐
│ Docker Host Machine │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Docker Network: inpactai-network │ │
│ │ │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ ┌────────┐│ │
│ │ │ Frontend │ │ Backend │ │ Redis ││ │
│ │ │ Container │ │ Container │ │ Container │
│ │ │ │ │ │ │ ││ │
│ │ │ Node 18-alpine │ │ Python 3.10-slim │ │ Redis 7││ │
│ │ │ Vite Dev Server │◄───┤ FastAPI + uvicorn │ Alpine ││ │
│ │ │ Port: 5173 │ │ Port: 8000 │◄───┤ Port: ││ │
│ │ │ │ │ │ │ 6379 ││ │
│ │ └──────────────────┘ └──────────────────┘ └────────┘│ │
│ │ │ │ │ │ │
│ │ │ Volume Mount │ Volume Mount │ │ │
│ │ │ (Hot Reload) │ (Hot Reload) │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌──────────────┐ ┌─────────────┐ ┌──────────┐│ │
│ │ │ ./Frontend │ │ ./Backend │ │redis_data││ │
│ │ │ /app │ │ /app │ │ Volume ││ │
│ │ └──────────────┘ └─────────────┘ └──────────┘│ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Port Mappings: │
│ ┌─────────────┬──────────────┬────────────────────────────────┐ │
│ │ Host:5173 │ ──────────► │ frontend:5173 (React + Vite) │ │
│ │ Host:8000 │ ──────────► │ backend:8000 (FastAPI) │ │
│ │ Host:6379 │ ──────────► │ redis:6379 (Cache) │ │
│ └─────────────┴──────────────┴────────────────────────────────┘ │
│ │
│ Environment Files: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Backend/.env → Backend Container │ │
│ │ Frontend/.env → Frontend Container │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────┘

User Browser
http://localhost:5173 ──► Frontend Container ──► React UI
│ API Calls
http://backend:8000 ──► Backend Container ──► FastAPI
│ Cache/PubSub
redis:6379 ──► Redis Container


Communication Flow:
──────────────────────

1. User accesses http://localhost:5173
└─► Docker routes to Frontend Container

2. Frontend makes API call to /api/*
└─► Vite proxy forwards to http://backend:8000
└─► Docker network resolves 'backend' to Backend Container

3. Backend connects to Redis
└─► Uses REDIS_HOST=redis environment variable
└─► Docker network resolves 'redis' to Redis Container

4. Backend connects to Supabase
└─► Uses credentials from Backend/.env
└─► External connection via internet


Service Dependencies:
─────────────────────

redis (no dependencies)
└─► backend (depends on redis)
└─► frontend (depends on backend)


Health Checks:
──────────────

Redis: redis-cli ping
Backend: curl http://localhost:8000/
Frontend: No health check (depends on backend health)


Volume Mounts:
──────────────

Development:
./Backend:/app (Hot reload for Python)
./Frontend:/app (Hot reload for Vite)
/app/__pycache__ (Excluded)
/app/node_modules (Excluded)

Production:
redis_data:/data (Persistent Redis storage only)


Build Process:
──────────────

Development:
1. Copy package files
2. Install dependencies
3. Copy source code
4. Start dev server with hot reload

Production:
Stage 1: Build
1. Copy package files
2. Install dependencies
3. Copy source code
4. Build optimized bundle

Stage 2: Serve
1. Copy built artifacts
2. Use minimal runtime (nginx for frontend)
3. Serve optimized files


Network Isolation:
──────────────────

Internal Network (inpactai-network):
- frontend ←→ backend (HTTP)
- backend ←→ redis (TCP)

External Access:
- Host machine → All containers (via port mapping)
- Backend → Supabase (via internet)
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The architecture diagram uses "InPactAI/" as the root directory path but the actual repository is named "InPact". Update the diagram to reflect the correct project structure.

Copilot uses AI. Check for mistakes.
- Backend → External APIs (via internet)


Security Model:
───────────────

Development:
- Root user in containers (for hot reload)
- Source code mounted as volumes
- Debug logging enabled

Production:
- Non-root user in containers
- No volume mounts (except data)
- Production logging
- Resource limits enforced
- Optimized images
```

## Quick Command Reference

```bash
Start: docker compose up --build
Stop: docker compose down
Logs: docker compose logs -f
Rebuild: docker compose up --build
Clean: docker compose down -v
```

## Service URLs

| Service | Internal | External |
|---------|----------|----------|
| Frontend | frontend:5173 | http://localhost:5173 |
| Backend | backend:8000 | http://localhost:8000 |
| Redis | redis:6379 | localhost:6379 |
Loading