# Docker Setup Guide for Grateful Journal

## Goal

This Docker setup runs the full app locally with three containers:

- Frontend (React app served by nginx)
- Backend (FastAPI)
- MongoDB

The setup is intentionally private to the local machine:

- Frontend is available only at `http://127.0.0.1:8000`
- Backend is not published to the host
- MongoDB is not published to the host
- Backend and MongoDB are reachable only from other containers in the same Docker Compose network

This means other devices on the same network cannot access the UI, backend, or database.

## Files Added for Docker

- Root `Dockerfile` for the frontend build and nginx runtime
- `backend/Dockerfile` for FastAPI
- `docker-compose.yml` for orchestration
- `nginx/default.conf` for SPA serving and API proxying
- Root `.env` for frontend build variables
- `backend/.env` for backend runtime variables

## Prerequisites

- Docker Desktop installed and running
- Docker Compose available via `docker compose`

## Environment Files

### Frontend

The root `.env` file is used during the frontend image build.

Current values:

```env
VITE_FIREBASE_API_KEY=...
VITE_FIREBASE_AUTH_DOMAIN=react-test-8cb04.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=react-test-8cb04
VITE_FIREBASE_STORAGE_BUCKET=react-test-8cb04.firebasestorage.app
VITE_FIREBASE_MESSAGING_SENDER_ID=1036594341832
VITE_FIREBASE_APP_ID=1:1036594341832:web:9db6fa337e9cd2e953c2fd
VITE_API_URL=/api
```

`VITE_API_URL=/api` is important because nginx proxies `/api` requests to the backend container internally.

### Backend

The `backend/.env` file is loaded by the backend container at runtime.

Current values:

```env
MONGODB_URI=mongodb://mongo:27017
MONGODB_DB_NAME=grateful_journal
API_PORT=8001
ENVIRONMENT=production
FRONTEND_URL=http://localhost:8000
```

`MONGODB_URI=mongodb://mongo:27017` works because Docker Compose gives the MongoDB service the hostname `mongo` on the internal network.

## Network Model

### Frontend

The frontend service is published with:

```yaml
ports:
    - "127.0.0.1:8000:80"
```

This binds the container to localhost only. The app is reachable from your machine, but not from another device on your LAN.

### Backend

The backend uses:

```yaml
expose:
    - "8001"
```

`expose` makes port 8001 available to other containers, but not to your host machine or network.

### MongoDB

MongoDB has no `ports` section, so it is not reachable from outside Docker. Only the backend can talk to it over the Compose network.

## Start the Stack

From the project root:

```bash
docker compose up --build
```

Then open:

- Frontend: `http://127.0.0.1:8000`

The backend API and MongoDB stay internal.

## Stop the Stack

```bash
docker compose down
```

To also remove the database volume:

```bash
docker compose down -v
```

## Rebuild After Changes

If you change frontend code, backend code, or environment variables:

```bash
docker compose up --build
```

If you want a full rebuild without cache:

```bash
docker compose build --no-cache
docker compose up
```

## Data Persistence

MongoDB data is stored in the named Docker volume `mongo_data`.

That means:

- Restarting containers keeps the data
- Removing the containers keeps the data
- Running `docker compose down -v` removes the data

## API Flow

Browser requests follow this path:

1. Browser loads the frontend from nginx on `127.0.0.1:8000`
2. Frontend sends API requests to `/api`
3. nginx forwards `/api` to `http://backend:8001/api/`
4. Backend connects to MongoDB at `mongodb://mongo:27017`

This avoids exposing the backend directly to the host.

## Firebase Note

The frontend still requires the Firebase JavaScript SDK because login happens in the browser.

The backend does not currently verify Firebase ID tokens, so `firebase-admin` is not part of this Docker setup.

If backend token verification is added later, that would be a separate change.

## Troubleshooting

### Docker command not found

Install Docker Desktop and confirm this works:

```bash
docker --version
docker compose version
```

### Frontend loads but API calls fail

Check that:

- `backend/.env` contains `MONGODB_URI=mongodb://mongo:27017`
- Root `.env` contains `VITE_API_URL=/api`
- All containers are healthy with `docker compose ps`

### Want to inspect MongoDB from the host

This setup does not expose MongoDB intentionally.

If you want host access temporarily for debugging, add a port mapping to the MongoDB service, but that weakens the local-only isolation model.
