Skip to content

Commit 14b7cfe

Browse files
authored
docker compose is back (#432)
Signed-off-by: Trevor Grant <[email protected]>
1 parent e89c465 commit 14b7cfe

File tree

9 files changed

+237
-2
lines changed

9 files changed

+237
-2
lines changed

webapp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ This monorepo contains the complete scaffolding for the Gofannon web application
2828
pnpm install
2929
```
3030

31-
### Running Locally
31+
### Running Locally (Docker Compose)
3232

3333
1. Start all services using Docker Compose:
3434
```bash

webapp/infra/docker/Dockerfile.api

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM python:3.10-slim
2+
3+
WORKDIR /app
4+
5+
COPY requirements.txt .
6+
RUN pip install --no-cache-dir -r requirements.txt
7+
8+
COPY . .
9+
10+
EXPOSE 8000
11+
12+
# The command will be provided by docker-compose for local dev
13+
# For production, you would use: CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# webapp/infra/docker/Dockerfile.couchdb-setup
2+
FROM alpine:latest
3+
4+
# Install curl and bash for the initialization script
5+
RUN apk add --no-cache curl bash
6+
7+
WORKDIR /app
8+
9+
# Copy and make the init script executable
10+
COPY couchdb-init.sh .
11+
RUN chmod +x couchdb-init.sh
12+
13+
# The command to run the script will be provided by docker-compose
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Stage 1: Build the React application
2+
FROM node:22-alpine AS builder
3+
WORKDIR /app
4+
COPY ./packages/webui/package.json ./packages/config/package.json ./package.json ./pnpm-workspace.yaml ./
5+
COPY ./pnpm-lock.yaml ./
6+
RUN npm install -g pnpm && pnpm install
7+
COPY ./packages/webui ./packages/webui
8+
COPY ./packages/config ./packages/config
9+
WORKDIR /app/packages/webui
10+
RUN pnpm install
11+
RUN pnpm build
12+
13+
# Stage 2: Serve the static files with Nginx
14+
FROM nginx:1.23-alpine
15+
COPY --from=builder /app/packages/webui/dist /usr/share/nginx/html
16+
17+
COPY ./infra/docker/nginx.conf /etc/nginx/conf.d/default.conf
18+
EXPOSE 80
19+
CMD ["nginx", "-g", "daemon off;"]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
# webapp/infra/docker/couchdb-init.sh
3+
4+
# Wait for CouchDB to be available
5+
echo "Waiting for CouchDB to start..."
6+
until curl -s http://couchdb:5984/_utils/ > /dev/null; do
7+
echo "CouchDB not yet available, waiting..."
8+
sleep 5
9+
done
10+
echo "CouchDB is up!"
11+
12+
# Create _users database if it doesn't exist
13+
# This database is crucial for CouchDB's internal user management and authentication
14+
echo "Creating _users database if it does not exist..."
15+
response=$(curl -s -X PUT "http://couchdb:5984/_users" \
16+
-u "${COUCHDB_USER}:${COUCHDB_PASSWORD}" \
17+
-H "Content-Type: application/json")
18+
19+
if echo "$response" | grep -q "error"; then
20+
# If the error is 'file_exists', it's fine, otherwise something is wrong
21+
if ! echo "$response" | grep -q "file_exists"; then
22+
echo "Error creating _users database: $response"
23+
exit 1
24+
else
25+
echo "_users database already exists."
26+
fi
27+
else
28+
echo "_users database created: $response"
29+
fi
30+
31+
# You can add commands to create other essential databases here if needed, e.g.:
32+
# echo "Creating sessions database if it does not exist..."
33+
# curl -s -X PUT "http://couchdb:5984/sessions" -u "${COUCHDB_USER}:${COUCHDB_PASSWORD}" -H "Content-Type: application/json"
34+
# echo "Creating agents database if it does not exist..."
35+
# curl -s -X PUT "http://couchdb:5984/agents" -u "${COUCHDB_USER}:${COUCHDB_PASSWORD}" -H "Content-Type: application/json"
36+
37+
# Disable logging of non-essential info to reduce noise
38+
echo "Setting CouchDB logging level to 'warning'..."
39+
curl -X PUT "http://couchdb:5984/_node/nonode@nohost/_config/log/level" \
40+
-u "${COUCHDB_USER}:${COUCHDB_PASSWORD}" \
41+
-d '"warning"'
42+
43+
44+
echo "CouchDB initialization complete."
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# webapp/infra/docker/docker-compose.yml
2+
services:
3+
webui:
4+
build:
5+
context: ../../
6+
dockerfile: infra/docker/Dockerfile.webui
7+
ports:
8+
- "3000:80"
9+
environment:
10+
- VITE_APP_ENV=local
11+
depends_on:
12+
api:
13+
condition: service_started # webui depends on api for data, but api needs couchdb first
14+
networks:
15+
- gofannon-net
16+
17+
api:
18+
build:
19+
context: ../../packages/api/user-service
20+
dockerfile: ../../../infra/docker/Dockerfile.api
21+
volumes:
22+
- ../../packages/api/user-service:/app # Mount for hot-reloading
23+
ports:
24+
- "8000:8000"
25+
environment:
26+
- APP_ENV=local
27+
- STORAGE_PROVIDER=s3
28+
- S3_ENDPOINT_URL=http://minio:9000
29+
- AWS_ACCESS_KEY_ID=minioadmin
30+
- AWS_SECRET_ACCESS_KEY=minioadmin
31+
- AWS_DEFAULT_REGION=us-east-1
32+
- DATABASE_PROVIDER=couchdb
33+
- COUCHDB_URL=http://couchdb:5984/
34+
env_file:
35+
- ./.env
36+
depends_on:
37+
minio:
38+
condition: service_started
39+
couchdb-setup:
40+
condition: service_completed_successfully
41+
networks:
42+
- gofannon-net
43+
command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
44+
45+
minio:
46+
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
47+
ports:
48+
- "9000:9000" # API port
49+
- "9001:9001" # Console port
50+
environment:
51+
- MINIO_ROOT_USER=minioadmin
52+
- MINIO_ROOT_PASSWORD=minioadmin
53+
volumes:
54+
- minio-data:/data
55+
networks:
56+
- gofannon-net
57+
command: server /data --console-address ":9001"
58+
59+
couchdb:
60+
image: couchdb:3.3
61+
ports:
62+
- "5984:5984"
63+
environment:
64+
- COUCHDB_USER=${COUCHDB_USER:-admin}
65+
- COUCHDB_PASSWORD=${COUCHDB_PASSWORD:-password}
66+
volumes:
67+
- couchdb-data:/opt/couchdb/data
68+
networks:
69+
- gofannon-net
70+
healthcheck: # <--- ADD THIS HEALTHCHECK
71+
test: ["CMD-SHELL", "curl -f http://localhost:5984/ || exit 1"]
72+
interval: 5s
73+
timeout: 5s
74+
retries: 5
75+
start_period: 10s # Give CouchDB some time to warm up before checks begin
76+
77+
couchdb-setup: # <--- NEW SERVICE FOR COUCHDB INITIALIZATION
78+
build:
79+
context: ../../infra/docker # Use the directory where Dockerfile.couchdb-setup and couchdb-init.sh are
80+
dockerfile: Dockerfile.couchdb-setup
81+
environment:
82+
- COUCHDB_USER=${COUCHDB_USER:-admin}
83+
- COUCHDB_PASSWORD=${COUCHDB_PASSWORD:-password}
84+
- COUCHDB_URL=http://couchdb:5984/ # Use the internal service name
85+
depends_on:
86+
couchdb:
87+
condition: service_healthy # Wait for couchdb to be healthy before attempting setup
88+
networks:
89+
- gofannon-net
90+
command: /app/couchdb-init.sh # Execute the initialization script
91+
92+
networks:
93+
gofannon-net:
94+
driver: bridge
95+
96+
volumes:
97+
minio-data:
98+
couchdb-data:

webapp/infra/docker/example.env

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# OPENAI_API_KEY=sk...
2+
# GEMINI_API_KEY=...
3+
4+
# CouchDB Credentials for local development
5+
COUCHDB_USER=admin
6+
COUCHDB_PASSWORD=password
7+
8+
# --- Observability Settings ---
9+
10+
# To enable AWS CloudWatch logging, provide all four AWS variables below.
11+
# The AWS keys will be used for both S3 (MinIO) and CloudWatch.
12+
# AWS_ACCESS_KEY_ID=your_aws_access_key
13+
# AWS_SECRET_ACCESS_KEY=your_aws_secret_key
14+
# AWS_DEFAULT_REGION=us-east-1
15+
# CLOUDWATCH_LOG_GROUP_NAME=gofannon-local-logs
16+
17+
# To enable Google Cloud Logging, set the project ID and ensure your environment
18+
# is authenticated (e.g., via `gcloud auth application-default login`).
19+
# The GOOGLE_CLOUD_PROJECT is also used by Firestore if configured.
20+
# GOOGLE_CLOUD_PROJECT=your-gcp-project-id

webapp/infra/docker/nginx.conf

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
server {
2+
# Listen on port 80 (standard HTTP port)
3+
listen 80;
4+
5+
# Set the root directory of your SPA files
6+
root /usr/share/nginx/html;
7+
8+
# Add index.html as a default file
9+
index index.html;
10+
11+
## Static File Serving and Caching ##
12+
location / {
13+
# Try to serve the requested file as-is, then as a directory, then fall back to the rewrite rule
14+
try_files $uri $uri/ /index.html;
15+
16+
# Optional: Add caching headers for static assets (adjust as needed)
17+
# expires 1y;
18+
# add_header Cache-Control "public, must-revalidate";
19+
}
20+
21+
22+
23+
## Error Page Handling ##
24+
error_page 500 502 503 504 /50x.html;
25+
location = /50x.html {
26+
root /usr/share/nginx/html;
27+
}
28+
}

webapp/packages/api/user-service/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async def startup_event():
7373

7474
app.add_middleware(
7575
CORSMiddleware,
76-
allow_origins=allowed_origins,
76+
allow_origins=["*"], #allowed_origins,
7777
allow_credentials=True,
7878
allow_methods=["*"],
7979
allow_headers=["*"], # For local/docker, "*" is fine for dev

0 commit comments

Comments
 (0)