Skip to content
Closed
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
44 changes: 44 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Git
.git
.gitignore

# Python
__pycache__
*.py[cod]
*$py.class
*.so
.Python
.env
.venv
env/
venv/
ENV/

# IDE
.idea/
.vscode/
*.swp
*.swo

# Build
*.egg-info/
dist/
build/
.eggs/

# Logs (will be mounted as volume)
logs/

# OAuth credentials (will be mounted as volume)
oauth_creds/

# Documentation
*.md
!README.md

# GitHub
.github/

# Misc
.DS_Store
*.log
46 changes: 46 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Build stage
FROM python:3.11-slim as builder

WORKDIR /app

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider pinning the gcc version or using build-essential for more complete build dependencies. While gcc alone works for most Python packages, some might need additional build tools. For example: build-essential or gcc g++ for C++ extensions.

Suggested change
gcc \
build-essential \

Copilot uses AI. Check for mistakes.
&& rm -rf /var/lib/apt/lists/*

# Copy requirements first for better caching
COPY requirements.txt .

# Copy the local rotator_library for editable install
COPY src/rotator_library ./src/rotator_library

# Install dependencies
RUN pip install --no-cache-dir --user -r requirements.txt
Comment on lines +14 to +18
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

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

The editable install (-e src/rotator_library in requirements.txt) in a multi-stage build can be problematic. The builder stage creates path references to /app/src/rotator_library, and while the production stage copies both the installed packages (line 26) and source (line 32) at the same paths, this adds complexity. Consider using a regular (non-editable) install for Docker builds by creating a separate requirements-docker.txt that lists src/rotator_library instead of -e src/rotator_library, or by running pip install --no-cache-dir --user src/rotator_library directly.

Suggested change
# Copy the local rotator_library for editable install
COPY src/rotator_library ./src/rotator_library
# Install dependencies
RUN pip install --no-cache-dir --user -r requirements.txt
# Copy the local rotator_library for installation
COPY src/rotator_library ./src/rotator_library
# Install dependencies (requirements.txt should NOT include -e src/rotator_library)
RUN pip install --no-cache-dir --user -r requirements.txt && pip install --no-cache-dir --user ./src/rotator_library

Copilot uses AI. Check for mistakes.

# Production stage
FROM python:3.11-slim

WORKDIR /app

# Copy installed packages from builder
COPY --from=builder /root/.local /root/.local

# Make sure scripts in .local are usable
ENV PATH=/root/.local/bin:$PATH
Comment on lines +21 to +29
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

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

The container is configured to run as the default root user (FROM python:3.11-slim with dependencies installed under /root/.local and no USER directive), which means any remote code execution in proxy_app would immediately yield root-level access inside the container and to any mounted volumes (e.g., OAuth credentials). To reduce impact from a compromise, create a dedicated non-root user, install dependencies into that user’s home, set ownership on /app, logs, and oauth_creds, and add a USER directive so the app runs with least privilege. For example:

RUN useradd -m appuser \
  && chown -R appuser:appuser /app
USER appuser

and adjust install paths accordingly.

Copilot uses AI. Check for mistakes.

# Copy application code
COPY src/ ./src/

# Create directories for logs and oauth credentials
RUN mkdir -p logs oauth_creds
EXPOSE 8000
# Expose the default port
EXPOSE 8000
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

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

Port mismatch: The EXPOSE instruction specifies port 8317, but the CMD at line 46 uses port 8000. This should be 8000 to match the application's default port and the docker-compose.yml configuration.

Copilot uses AI. Check for mistakes.

# Set environment variables
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONPATH=/app/src

# Default command - runs proxy with the correct PYTHONPATH
CMD ["python", "src/proxy_app/main.py", "--port", "8317"]
31 changes: 31 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
services:
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider adding a comment at the top of the file documenting: 1) Prerequisites (e.g., "Create .env from .env.example before running"), 2) How to start the service (docker-compose up -d), and 3) How to view logs (docker-compose logs -f). This would improve the developer experience for first-time users.

Copilot uses AI. Check for mistakes.
llm-proxy:
build:
context: .
dockerfile: Dockerfile
container_name: llm-api-proxy
restart: unless-stopped
ports:
- "8317:8317"
volumes:
# Mount .env files for configuration
Copy link

Copilot AI Dec 4, 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 in .dockerignore (line 11), which means it won't be present in the Docker image build context. This volume mount will fail if .env doesn't exist on the host. Consider adding a note in comments or documentation that users need to create .env from .env.example before running docker-compose.

Suggested change
# Mount .env files for configuration
# Mount .env files for configuration
# NOTE: You must create a .env file on the host before running docker-compose.
# Copy or rename .env.example to .env and update values as needed.

Copilot uses AI. Check for mistakes.
- ./.env:/app/.env:ro
# Mount oauth_creds directory for OAuth credentials persistence
- ./oauth_creds:/app/oauth_creds
# Mount logs directory for persistent logging
- ./logs:/app/logs
# Mount key_usage.json for usage statistics persistence
- ./key_usage.json:/app/key_usage.json
# Optionally mount additional .env files (e.g., combined credential files)
# - ./antigravity_all_combined.env:/app/antigravity_all_combined.env:ro
environment:
# Skip OAuth interactive initialization in container (non-interactive)
- SKIP_OAUTH_INIT_CHECK=true
# Ensure Python output is not buffered
- PYTHONUNBUFFERED=1
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8317/')"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
Loading