Update service ports to 12015 for backend and 12016 for frontend; adjust configurations and documentation accordingly
This commit is contained in:
+2
-1
@@ -44,4 +44,5 @@ htmlcov/
|
|||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
# instructions
|
# instructions
|
||||||
.github/instructions/
|
.github/instructions/
|
||||||
|
backend/data/
|
||||||
|
|||||||
+2
-2
@@ -16,7 +16,7 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
EXPOSE 12000
|
EXPOSE 12015
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "12000"]
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "12015"]
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ app = FastAPI(
|
|||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=[os.getenv("CORS_ORIGINS", "http://localhost:12001")],
|
allow_origins=[os.getenv("CORS_ORIGINS", "http://localhost:12016")],
|
||||||
allow_credentials=True,
|
allow_credentials=True,
|
||||||
allow_methods=["*"],
|
allow_methods=["*"],
|
||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
|
|||||||
+11
-11
@@ -13,7 +13,7 @@ Describes:
|
|||||||
│ ┌─────────────┐ ┌────────────────────┐ │
|
│ ┌─────────────┐ ┌────────────────────┐ │
|
||||||
│ │ frontend │ │ backend │ │
|
│ │ frontend │ │ backend │ │
|
||||||
│ │ (Flask) │ │ (FastAPI) │ │
|
│ │ (Flask) │ │ (FastAPI) │ │
|
||||||
│ │ :12001 │ │ :12000 │ │
|
│ │ :12016 │ │ :12015 │ │
|
||||||
│ └──────┬──────┘ └─────────┬──────────┘ │
|
│ └──────┬──────┘ └─────────┬──────────┘ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ └────────┬──────────┘ │
|
│ └────────┬──────────┘ │
|
||||||
@@ -33,8 +33,8 @@ Describes:
|
|||||||
|
|
||||||
| Building Block | Container / Process | Port |
|
| Building Block | Container / Process | Port |
|
||||||
| --------------- | ---------------------------- | ----- |
|
| --------------- | ---------------------------- | ----- |
|
||||||
| Flask frontend | `frontend` | 12001 |
|
| Flask frontend | `frontend` | 12016 |
|
||||||
| FastAPI backend | `backend` | 12000 |
|
| FastAPI backend | `backend` | 12015 |
|
||||||
| DuckDB | File on host (`data/app.db`) | — |
|
| DuckDB | File on host (`data/app.db`) | — |
|
||||||
|
|
||||||
## Infrastructure Level 2
|
## Infrastructure Level 2
|
||||||
@@ -50,25 +50,25 @@ All services are containerized and orchestrated with `docker compose`:
|
|||||||
│ │ Docker Network: app-network (bridge) │ │
|
│ │ Docker Network: app-network (bridge) │ │
|
||||||
│ │ ┌──────────────────────────────────────────────┐ │ │
|
│ │ ┌──────────────────────────────────────────────┐ │ │
|
||||||
│ │ │ Backend Container (FastAPI) │ │ │
|
│ │ │ Backend Container (FastAPI) │ │ │
|
||||||
│ │ │ - Port: 12000 │ │ │
|
│ │ │ - Port: 12015 │ │ │
|
||||||
│ │ │ - Service Name: backend │ │ │
|
│ │ │ - Service Name: backend │ │ │
|
||||||
│ │ │ - Volume Mount: /app/data ← host/data/ │ │ │
|
│ │ │ - Volume Mount: /app/data ← host/data/ │ │ │
|
||||||
│ │ ├──────────────────────────────────────────────┤ │ │
|
│ │ ├──────────────────────────────────────────────┤ │ │
|
||||||
│ │ │ Frontend Container (Flask) │ │ │
|
│ │ │ Frontend Container (Flask) │ │ │
|
||||||
│ │ │ - Port: 12001 │ │ │
|
│ │ │ - Port: 12016 │ │ │
|
||||||
│ │ │ - Service Name: frontend │ │ │
|
│ │ │ - Service Name: frontend │ │ │
|
||||||
│ │ │ - Depends on: backend (health check) │ │ │
|
│ │ │ - Depends on: backend (health check) │ │ │
|
||||||
│ │ ├──────────────────────────────────────────────┤ │ │
|
│ │ ├──────────────────────────────────────────────┤ │ │
|
||||||
│ │ │ Nginx Container (Reverse Proxy) │ │ │
|
│ │ │ Nginx Container (Reverse Proxy) │ │ │
|
||||||
│ │ │ - Port: 80 (HTTP), 443 (HTTPS) │ │ │
|
│ │ │ - Port: 80 (HTTP), 443 (HTTPS) │ │ │
|
||||||
│ │ │ - Config: nginx/docker-compose.conf │ │ │
|
│ │ │ - Config: nginx/docker-compose.conf │ │ │
|
||||||
│ │ │ - Routes: /api/* → backend:12000 │ │ │
|
│ │ │ - Routes: /api/* → backend:12015 │ │ │
|
||||||
│ │ │ / → frontend:12001 │ │ │
|
│ │ │ / → frontend:12016 │ │ │
|
||||||
│ │ └──────────────────────────────────────────────┘ │ │
|
│ │ └──────────────────────────────────────────────┘ │ │
|
||||||
│ └──────────────────────────────────────────────────────┘ │
|
│ └──────────────────────────────────────────────────────┘ │
|
||||||
│ ▲ │
|
│ ▲ │
|
||||||
│ Host Port Bindings │
|
│ Host Port Bindings │
|
||||||
│ 80:80, 443:443, 12000:12000, 12001:12001 │
|
│ 80:80, 443:443, 12015:12015, 12016:12016 │
|
||||||
└─────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────┘
|
||||||
│
|
│
|
||||||
Users / Internet
|
Users / Internet
|
||||||
@@ -79,7 +79,7 @@ All services are containerized and orchestrated with `docker compose`:
|
|||||||
1. Ensure Docker and Docker Compose are installed
|
1. Ensure Docker and Docker Compose are installed
|
||||||
2. Create `.env` with required environment variables
|
2. Create `.env` with required environment variables
|
||||||
3. Run: `docker compose up --build`
|
3. Run: `docker compose up --build`
|
||||||
4. Access via browser at `http://localhost:12001` or through Nginx at `http://localhost:80`
|
4. Access via browser at `http://localhost:12016` or through Nginx at `http://localhost:80`
|
||||||
|
|
||||||
**Benefits:**
|
**Benefits:**
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ All services are containerized and orchestrated with `docker compose`:
|
|||||||
- **Simplicity**: Single command to start entire stack
|
- **Simplicity**: Single command to start entire stack
|
||||||
- **Portability**: Run on any system with Docker installed
|
- **Portability**: Run on any system with Docker installed
|
||||||
- **Persistence**: DuckDB data survives container restarts via volume mounts
|
- **Persistence**: DuckDB data survives container restarts via volume mounts
|
||||||
- **Networking**: Service names enable automatic DNS resolution (backend:12000, frontend:12001)
|
- **Networking**: Service names enable automatic DNS resolution (backend:12015, frontend:12016)
|
||||||
- **Observability**: Easy logging with `docker compose logs`
|
- **Observability**: Easy logging with `docker compose logs`
|
||||||
|
|
||||||
**See**: [Docker Compose Deployment Guide](./deployment/docker-compose.md) for detailed instructions.
|
**See**: [Docker Compose Deployment Guide](./deployment/docker-compose.md) for detailed instructions.
|
||||||
@@ -101,6 +101,6 @@ If using Coolify instead of Docker Compose:
|
|||||||
3. **Data Persistence**: Named volume keeps DuckDB data at `/app/data`
|
3. **Data Persistence**: Named volume keeps DuckDB data at `/app/data`
|
||||||
4. **Fallback Path**: Use separate Nixpacks services only when one-stack Compose deploy is not suitable
|
4. **Fallback Path**: Use separate Nixpacks services only when one-stack Compose deploy is not suitable
|
||||||
|
|
||||||
**Note**: In Compose-based Coolify deployment, frontend reaches backend through Docker DNS at `http://backend:12000`. In Nixpacks-based deployment, use Coolify internal networking or colocate both services.
|
**Note**: In Compose-based Coolify deployment, frontend reaches backend through Docker DNS at `http://backend:12015`. In Nixpacks-based deployment, use Coolify internal networking or colocate both services.
|
||||||
|
|
||||||
**See**: [Coolify Deployment Guide](./deployment/coolify.md) for detailed instructions.
|
**See**: [Coolify Deployment Guide](./deployment/coolify.md) for detailed instructions.
|
||||||
|
|||||||
+21
-21
@@ -32,13 +32,13 @@ The application consists of two Python services:
|
|||||||
|
|
||||||
| Service | Framework | Port | Description |
|
| Service | Framework | Port | Description |
|
||||||
| -------- | ----------------- | ----- | ------------------------------------------ |
|
| -------- | ----------------- | ----- | ------------------------------------------ |
|
||||||
| Backend | FastAPI + uvicorn | 12000 | REST API, auth, AI generation, DuckDB |
|
| Backend | FastAPI + uvicorn | 12015 | REST API, auth, AI generation, DuckDB |
|
||||||
| Frontend | Flask + gunicorn | 12001 | SSR web UI, session auth, proxy to backend |
|
| Frontend | Flask + gunicorn | 12016 | SSR web UI, session auth, proxy to backend |
|
||||||
|
|
||||||
Coolify's built-in reverse proxy routes traffic:
|
Coolify's built-in reverse proxy routes traffic:
|
||||||
|
|
||||||
- `/api/*` → Backend (port 12000)
|
- `/api/*` → Backend (port 12015)
|
||||||
- `/` → Frontend (port 12001)
|
- `/` → Frontend (port 12016)
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ Use Coolify's **Docker Compose** resource with the dedicated compose file `docke
|
|||||||
3. Select the `ai.allucanget.biz` repository and `main` branch
|
3. Select the `ai.allucanget.biz` repository and `main` branch
|
||||||
4. Set **Compose File** to `docker-compose.coolify.yml`
|
4. Set **Compose File** to `docker-compose.coolify.yml`
|
||||||
5. Set **Base Directory** to `/`
|
5. Set **Base Directory** to `/`
|
||||||
6. Select the `frontend` service as the public-facing service on port `12001`
|
6. Select the `frontend` service as the public-facing service on port `12016`
|
||||||
7. Click **Create Resource**
|
7. Click **Create Resource**
|
||||||
|
|
||||||
### Step 2: Configure Environment Variables
|
### Step 2: Configure Environment Variables
|
||||||
@@ -72,15 +72,15 @@ Add these in Coolify before first deploy:
|
|||||||
| `APP_NAME` | `backend` | `AI Allucanget` |
|
| `APP_NAME` | `backend` | `AI Allucanget` |
|
||||||
| `CORS_ORIGINS` | `backend` | `https://ai.allucanget.biz` |
|
| `CORS_ORIGINS` | `backend` | `https://ai.allucanget.biz` |
|
||||||
| `FLASK_SECRET_KEY` | `frontend` | `openssl rand -hex 32` |
|
| `FLASK_SECRET_KEY` | `frontend` | `openssl rand -hex 32` |
|
||||||
| `BACKEND_URL` | `frontend` | `http://backend:12000` |
|
| `BACKEND_URL` | `frontend` | `http://backend:12015` |
|
||||||
|
|
||||||
### Step 3: Configure Domain and Proxy
|
### Step 3: Configure Domain and Proxy
|
||||||
|
|
||||||
1. Attach domain `ai.allucanget.biz` to the `frontend` service on port `12001`
|
1. Attach domain `ai.allucanget.biz` to the `frontend` service on port `12016`
|
||||||
2. Enable **Auto HTTPS** in Coolify
|
2. Enable **Auto HTTPS** in Coolify
|
||||||
3. Coolify terminates TLS and forwards traffic directly to `frontend:12001`
|
3. Coolify terminates TLS and forwards traffic directly to `frontend:12016`
|
||||||
|
|
||||||
No nginx service is needed in the Coolify stack. The frontend Flask app proxies `/api/*` calls to `http://backend:12000` internally. Coolify's own reverse proxy handles external TLS termination.
|
No nginx service is needed in the Coolify stack. The frontend Flask app proxies `/api/*` calls to `http://backend:12015` internally. Coolify's own reverse proxy handles external TLS termination.
|
||||||
|
|
||||||
### Step 4: Persistent Storage
|
### Step 4: Persistent Storage
|
||||||
|
|
||||||
@@ -103,11 +103,11 @@ No nginx service is needed in the Coolify stack. The frontend Flask app proxies
|
|||||||
4. Choose the `main` branch
|
4. Choose the `main` branch
|
||||||
5. Set **Build Pack** to `nixpacks`
|
5. Set **Build Pack** to `nixpacks`
|
||||||
6. **CRITICAL: Set Base Directory to `/backend`** — this tells Nixpacks to look in the `backend/` subdirectory for `requirements.txt` and the Python application
|
6. **CRITICAL: Set Base Directory to `/backend`** — this tells Nixpacks to look in the `backend/` subdirectory for `requirements.txt` and the Python application
|
||||||
7. Set **Ports Exposed** to `12000`
|
7. Set **Ports Exposed** to `12015`
|
||||||
8. Set **Start Command** to:
|
8. Set **Start Command** to:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
uvicorn app.main:app --host 0.0.0.0 --port 12000
|
uvicorn app.main:app --host 0.0.0.0 --port 12015
|
||||||
```
|
```
|
||||||
|
|
||||||
9. Click **Create Resource**
|
9. Click **Create Resource**
|
||||||
@@ -133,11 +133,11 @@ Add these as **Runtime** environment variables in Coolify:
|
|||||||
3. Choose the `main` branch
|
3. Choose the `main` branch
|
||||||
4. Set **Build Pack** to `nixpacks`
|
4. Set **Build Pack** to `nixpacks`
|
||||||
5. **CRITICAL: Set Base Directory to `/frontend`** — this tells Nixpacks to look in the `frontend/` subdirectory for `requirements.txt` and the Python application
|
5. **CRITICAL: Set Base Directory to `/frontend`** — this tells Nixpacks to look in the `frontend/` subdirectory for `requirements.txt` and the Python application
|
||||||
6. Set **Ports Exposed** to `12001`
|
6. Set **Ports Exposed** to `12016`
|
||||||
7. Set **Start Command** to:
|
7. Set **Start Command** to:
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
gunicorn app.main:app --bind 0.0.0.0:12001 --workers 2 --timeout 120
|
gunicorn app.main:app --bind 0.0.0.0:12016 --workers 2 --timeout 120
|
||||||
```
|
```
|
||||||
|
|
||||||
8. Click **Create Resource**
|
8. Click **Create Resource**
|
||||||
@@ -152,7 +152,7 @@ Add these as **Runtime** environment variables in Coolify:
|
|||||||
| Variable | Description | Example |
|
| Variable | Description | Example |
|
||||||
| ------------------ | ----------------------------------------- | --------------------------------------------------------------- |
|
| ------------------ | ----------------------------------------- | --------------------------------------------------------------- |
|
||||||
| `FLASK_SECRET_KEY` | Flask session cookie signing key | Generate with `openssl rand -hex 32` |
|
| `FLASK_SECRET_KEY` | Flask session cookie signing key | Generate with `openssl rand -hex 32` |
|
||||||
| `BACKEND_URL` | Internal URL to reach the backend service | `http://localhost:12000` (or use Coolify's internal networking) |
|
| `BACKEND_URL` | Internal URL to reach the backend service | `http://localhost:12015` (or use Coolify's internal networking) |
|
||||||
|
|
||||||
## Step 3: Configure Reverse Proxy
|
## Step 3: Configure Reverse Proxy
|
||||||
|
|
||||||
@@ -161,13 +161,13 @@ Coolify provides a built-in reverse proxy. Configure routing rules:
|
|||||||
### Backend Proxy Rules
|
### Backend Proxy Rules
|
||||||
|
|
||||||
- **Domain**: `api.ai.allucanget.biz` (or subdomain of your choice)
|
- **Domain**: `api.ai.allucanget.biz` (or subdomain of your choice)
|
||||||
- **Port**: `12000`
|
- **Port**: `12015`
|
||||||
- **Path**: `/api/*` → forward to backend
|
- **Path**: `/api/*` → forward to backend
|
||||||
|
|
||||||
### Frontend Proxy Rules
|
### Frontend Proxy Rules
|
||||||
|
|
||||||
- **Domain**: `ai.allucanget.biz`
|
- **Domain**: `ai.allucanget.biz`
|
||||||
- **Port**: `12001`
|
- **Port**: `12016`
|
||||||
- **Path**: `/` → forward to frontend
|
- **Path**: `/` → forward to frontend
|
||||||
|
|
||||||
### Nginx Configuration (Optional)
|
### Nginx Configuration (Optional)
|
||||||
@@ -180,7 +180,7 @@ If you need custom Nginx configuration, create `nginx/coolify.conf`:
|
|||||||
|
|
||||||
# Backend API proxy
|
# Backend API proxy
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://backend:12000;
|
proxy_pass http://backend:12015;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
@@ -189,7 +189,7 @@ location /api/ {
|
|||||||
|
|
||||||
# Frontend proxy
|
# Frontend proxy
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://frontend:12001;
|
proxy_pass http://frontend:12016;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
@@ -222,7 +222,7 @@ If you want to persist DuckDB data:
|
|||||||
### Docker Compose deployment fails in Coolify
|
### Docker Compose deployment fails in Coolify
|
||||||
|
|
||||||
- Verify Coolify uses `docker-compose.coolify.yml`, not local `docker-compose.yml`
|
- Verify Coolify uses `docker-compose.coolify.yml`, not local `docker-compose.yml`
|
||||||
- Verify public domain points to `frontend` service on port `12001`
|
- Verify public domain points to `frontend` service on port `12016`
|
||||||
- Do not add `nginx` to the Coolify stack — bind-mounting a local config file will fail since the file doesn't exist on the Coolify server
|
- Do not add `nginx` to the Coolify stack — bind-mounting a local config file will fail since the file doesn't exist on the Coolify server
|
||||||
|
|
||||||
### Backend healthcheck stays unhealthy
|
### Backend healthcheck stays unhealthy
|
||||||
@@ -240,7 +240,7 @@ If you want to persist DuckDB data:
|
|||||||
### Frontend can't reach backend
|
### Frontend can't reach backend
|
||||||
|
|
||||||
- Ensure `BACKEND_URL` points to the correct internal URL
|
- Ensure `BACKEND_URL` points to the correct internal URL
|
||||||
- If both services are on the same Coolify server, use `http://localhost:12000`
|
- If both services are on the same Coolify server, use `http://localhost:12015`
|
||||||
- Check that the backend service is running and healthy
|
- Check that the backend service is running and healthy
|
||||||
|
|
||||||
### CORS errors
|
### CORS errors
|
||||||
@@ -272,7 +272,7 @@ All required environment variables:
|
|||||||
|
|
||||||
- [ ] Repository pushed to Git
|
- [ ] Repository pushed to Git
|
||||||
- [ ] For Docker Compose: Coolify resource uses `docker-compose.coolify.yml`
|
- [ ] For Docker Compose: Coolify resource uses `docker-compose.coolify.yml`
|
||||||
- [ ] For Docker Compose: domain points to `frontend` service on port `12001`
|
- [ ] For Docker Compose: domain points to `frontend` service on port `12016`
|
||||||
- [ ] Backend service created with correct base directory (`/backend`)
|
- [ ] Backend service created with correct base directory (`/backend`)
|
||||||
- [ ] Backend environment variables configured
|
- [ ] Backend environment variables configured
|
||||||
- [ ] Frontend service created with correct base directory (`/frontend`)
|
- [ ] Frontend service created with correct base directory (`/frontend`)
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ docker compose up --build
|
|||||||
```
|
```
|
||||||
|
|
||||||
4. **Access the application**:
|
4. **Access the application**:
|
||||||
- Frontend UI: http://localhost:12001
|
- Frontend UI: http://localhost:12016
|
||||||
- Backend API: http://localhost:12000
|
- Backend API: http://localhost:12015
|
||||||
- API Health: http://localhost:12000/health
|
- API Health: http://localhost:12015/health
|
||||||
- Nginx Proxy: http://localhost:80 (routes to frontend) or http://localhost:80/api (routes to backend)
|
- Nginx Proxy: http://localhost:80 (routes to frontend) or http://localhost:80/api (routes to backend)
|
||||||
|
|
||||||
5. **View logs**:
|
5. **View logs**:
|
||||||
@@ -77,8 +77,8 @@ The `.env` file in the project root is automatically loaded by Docker Compose. R
|
|||||||
| `OPENROUTER_API_KEY` | API key for AI generation | `sk-or-v1-...` |
|
| `OPENROUTER_API_KEY` | API key for AI generation | `sk-or-v1-...` |
|
||||||
| `JWT_SECRET` | Secret for JWT token signing | (random hex string) |
|
| `JWT_SECRET` | Secret for JWT token signing | (random hex string) |
|
||||||
| `FLASK_SECRET_KEY` | Secret for Flask session cookies | (random hex string) |
|
| `FLASK_SECRET_KEY` | Secret for Flask session cookies | (random hex string) |
|
||||||
| `BACKEND_URL` | Internal URL for frontend to reach backend | `http://backend:12000` (Docker) or `http://localhost:12000` (local dev) |
|
| `BACKEND_URL` | Internal URL for frontend to reach backend | `http://backend:12015` (Docker) or `http://localhost:12015` (local dev) |
|
||||||
| `CORS_ORIGINS` | Allowed CORS origins for backend | `http://localhost:12001` (local) or `https://ai.allucanget.biz` (production) |
|
| `CORS_ORIGINS` | Allowed CORS origins for backend | `http://localhost:12016` (local) or `https://ai.allucanget.biz` (production) |
|
||||||
| `APP_URL` | Public URL of the backend | `http://localhost` or `https://ai.allucanget.biz` |
|
| `APP_URL` | Public URL of the backend | `http://localhost` or `https://ai.allucanget.biz` |
|
||||||
| `APP_NAME` | Application name | `AI Allucanget` |
|
| `APP_NAME` | Application name | `AI Allucanget` |
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ The `docker-compose.yml` defines the following volume:
|
|||||||
│ │
|
│ │
|
||||||
│ ┌──────────────────┐ ┌──────────────────────────┐ │
|
│ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||||||
│ │ Frontend │ │ Backend │ │
|
│ │ Frontend │ │ Backend │ │
|
||||||
│ │ Port 12001 │ │ Port 12000 │ │
|
│ │ Port 12016 │ │ Port 12015 │ │
|
||||||
│ │ Flask + Gunicorn│◄──►│ FastAPI + Uvicorn │ │
|
│ │ Flask + Gunicorn│◄──►│ FastAPI + Uvicorn │ │
|
||||||
│ │ (Service name: │ │ (Service name: backend) │ │
|
│ │ (Service name: │ │ (Service name: backend) │ │
|
||||||
│ │ frontend) │ │ │ │
|
│ │ frontend) │ │ │ │
|
||||||
@@ -128,8 +128,8 @@ Output example:
|
|||||||
|
|
||||||
```
|
```
|
||||||
NAME COMMAND SERVICE STATUS PORTS
|
NAME COMMAND SERVICE STATUS PORTS
|
||||||
ai-backend "uvicorn app.main:a…" backend Up 2m 0.0.0.0:12000->12000/tcp
|
ai-backend "uvicorn app.main:a…" backend Up 2m 0.0.0.0:12015->12015/tcp
|
||||||
ai-frontend "gunicorn app.main:…" frontend Up 2m 0.0.0.0:12001->12001/tcp
|
ai-frontend "gunicorn app.main:…" frontend Up 2m 0.0.0.0:12016->12016/tcp
|
||||||
ai-nginx "nginx -g daemon of…" nginx Up 2m 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
|
ai-nginx "nginx -g daemon of…" nginx Up 2m 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ docker compose down --rmi all
|
|||||||
|
|
||||||
**Solution**: Start Docker Desktop (Windows/Mac) or start the Docker daemon (Linux).
|
**Solution**: Start Docker Desktop (Windows/Mac) or start the Docker daemon (Linux).
|
||||||
|
|
||||||
### "Port 12000 or 12001 already in use"
|
### "Port 12015 or 12016 already in use"
|
||||||
|
|
||||||
**Error**: `Error response from daemon: bind: address already in use`
|
**Error**: `Error response from daemon: bind: address already in use`
|
||||||
|
|
||||||
@@ -199,8 +199,8 @@ docker compose down --rmi all
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
ports:
|
ports:
|
||||||
- "13000:12000" # Maps host:13000 to container:12000
|
- "13000:12015" # Maps host:13000 to container:12015
|
||||||
- "13001:12001" # Maps host:13001 to container:12001
|
- "13001:12016" # Maps host:13001 to container:12016
|
||||||
```
|
```
|
||||||
|
|
||||||
### Frontend cannot reach backend
|
### Frontend cannot reach backend
|
||||||
@@ -210,7 +210,7 @@ ports:
|
|||||||
**Ensure**:
|
**Ensure**:
|
||||||
|
|
||||||
1. Backend service is running: `docker compose ps`
|
1. Backend service is running: `docker compose ps`
|
||||||
2. `BACKEND_URL` in `.env` is set to `http://backend:12000` (not `localhost`)
|
2. `BACKEND_URL` in `.env` is set to `http://backend:12015` (not `localhost`)
|
||||||
3. Services are on the same Docker network: `docker compose ps` shows them in the same `docker-compose.yml`
|
3. Services are on the same Docker network: `docker compose ps` shows them in the same `docker-compose.yml`
|
||||||
|
|
||||||
### Database file not persisting
|
### Database file not persisting
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
EXPOSE 12001
|
EXPOSE 12016
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
CMD ["gunicorn", "app.main:app", "--bind", "0.0.0.0:12001", "--workers", "2", "--timeout", "120"]
|
CMD ["gunicorn", "app.main:app", "--bind", "0.0.0.0:12016", "--workers", "2", "--timeout", "120"]
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import os
|
|||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
SECRET_KEY = os.getenv("FLASK_SECRET_KEY", "dev-secret-change-in-production")
|
SECRET_KEY = os.getenv(
|
||||||
BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:12000")
|
"FLASK_SECRET_KEY", "dev-secret-change-in-production")
|
||||||
|
BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:12015")
|
||||||
SESSION_COOKIE_HTTPONLY = True
|
SESSION_COOKIE_HTTPONLY = True
|
||||||
SESSION_COOKIE_SAMESITE = "Lax"
|
SESSION_COOKIE_SAMESITE = "Lax"
|
||||||
|
|||||||
@@ -79,6 +79,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Video polling error:", e);
|
console.error("Video polling error:", e);
|
||||||
}
|
}
|
||||||
}, 12001);
|
}, 12016);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-2
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
# Backend API proxy
|
# Backend API proxy
|
||||||
upstream backend {
|
upstream backend {
|
||||||
server 127.0.0.1:12000;
|
server 127.0.0.1:12015;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Frontend proxy
|
# Frontend proxy
|
||||||
upstream frontend {
|
upstream frontend {
|
||||||
server 127.0.0.1:12001;
|
server 127.0.0.1:12016;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
# Backend API proxy - use Docker service name instead of localhost
|
# Backend API proxy - use Docker service name instead of localhost
|
||||||
upstream backend {
|
upstream backend {
|
||||||
server backend:12000;
|
server backend:12015;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Frontend proxy - use Docker service name instead of localhost
|
# Frontend proxy - use Docker service name instead of localhost
|
||||||
upstream frontend {
|
upstream frontend {
|
||||||
server frontend:12001;
|
server frontend:12016;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
|
|||||||
Reference in New Issue
Block a user