diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0666e24 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +FROM python:3.10-slim + +WORKDIR /app + +# Install system dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends gcc build-essential && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Copy requirements first for better caching +RUN pip install --no-cache-dir poetry + +# Install Python dependencies without creating a virtualenv +COPY pyproject.toml poetry.lock ./ +RUN poetry config virtualenvs.create false \ + && poetry install --without dev --no-interaction --no-ansi --no-root + +# Copy application code +COPY . . + +# Set Python to run in unbuffered mode (recommended for Docker) +ENV PYTHONUNBUFFERED=1 +ENV PYTHONPATH=/app + +# Expose the port the app will run on +EXPOSE 8000 + +# Default to running only the API server; worker and train-api are separate Compose services +CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..2a14573 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,20 @@ +services: + api: + volumes: + - ./:/app:cached + command: uvicorn api.main:app --host 0.0.0.0 --port 8000 --reload + + worker: + volumes: + - ./:/app:cached + command: python scripts/run_worker.py + + train-api: + volumes: + - ./:/app:cached + command: python thirdparty/train_api.py + + frontend: + volumes: + - ./frontend:/app:cached + command: sh -c "apk update && apk add --no-cache xdg-utils && npm install && npx vite --host 0.0.0.0 --port 5173" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e3b20eb --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,120 @@ +services: + # Database service + postgresql: + image: postgres:14 + container_name: temporal-postgresql + environment: + POSTGRES_USER: temporal + POSTGRES_PASSWORD: temporal + POSTGRES_DB: temporal + volumes: + - postgresql:/var/lib/postgresql/data + networks: + - temporal-network + + # Temporal services + temporal: + image: temporalio/auto-setup:1.27.2 + container_name: temporal + ports: + - "7233:7233" + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + depends_on: + - postgresql + networks: + - temporal-network + + temporal-admin-tools: + image: temporalio/admin-tools:1.27 + container_name: temporal-admin-tools + depends_on: + - temporal + environment: + - TEMPORAL_CLI_ADDRESS=temporal:7233 + networks: + - temporal-network + + temporal-ui: + image: temporalio/ui:2.37.2 + container_name: temporal-ui + ports: + - "8080:8080" + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:8080 + depends_on: + - temporal + networks: + - temporal-network + + api: + build: + context: . + dockerfile: Dockerfile + container_name: temporal-ai-agent-api + ports: + - "8000:8000" + depends_on: + - temporal + networks: + - temporal-network + env_file: + - .env + environment: + - TEMPORAL_ADDRESS=temporal:7233 + + worker: + build: + context: . + dockerfile: Dockerfile + container_name: temporal-ai-agent-worker + depends_on: + - temporal + env_file: + - .env + environment: + - TEMPORAL_ADDRESS=temporal:7233 + command: python scripts/run_worker.py + networks: + - temporal-network + + train-api: + build: + context: . + dockerfile: Dockerfile + container_name: temporal-ai-agent-train-api + depends_on: + - temporal + env_file: + - .env + environment: + - TEMPORAL_ADDRESS=temporal:7233 + command: python thirdparty/train_api.py + networks: + - temporal-network + + frontend: + image: node:18-alpine + container_name: temporal-ai-agent-frontend + working_dir: /app + volumes: + - ./frontend:/app + command: sh -c "apk update && apk add --no-cache xdg-utils && npm install && npx vite --host 0.0.0.0" + ports: + - "5173:5173" + depends_on: + - api + networks: + - temporal-network + +networks: + temporal-network: + driver: bridge + +volumes: + postgresql: diff --git a/setup.md b/setup.md index f417f10..57400af 100644 --- a/setup.md +++ b/setup.md @@ -93,10 +93,32 @@ temporal server start-dev ``` See the [Temporal documentation](https://learn.temporal.io/getting_started/python/dev_environment/) for other platforms. +You can also run a local Temporal server using Docker Compose. See the `Development with Docker` section below. ## Running the Application -### Python Backend +### Docker +- All services are defined in `docker-compose.yml` (includes a Temporal server). +- **Dev overrides** (mounted code, live‑reload commands) live in `docker-compose.override.yml` and are **auto‑merged** on `docker compose up`. +- To start **development** mode (with hot‑reload): + ```bash + docker compose up -d + # quick rebuild without infra: + docker compose up -d --no-deps --build api train-api worker frontend + ``` +- To run **production** mode (ignore dev overrides): + ```bash + docker compose -f docker-compose.yml up -d + ``` + +Default urls: +* Temporal UI: [http://localhost:8080](http://localhost:8080) +* API: [http://localhost:8000](http://localhost:8000) +* Frontend: [http://localhost:5173](http://localhost:5173) + +### Local Machine (no docker) + +**Python Backend** Requires [Poetry](https://python-poetry.org/) to manage dependencies. @@ -119,7 +141,7 @@ poetry run uvicorn api.main:app --reload ``` Access the API at `/docs` to see the available endpoints. -### React UI +**React UI** Start the frontend: ```bash cd frontend @@ -127,8 +149,7 @@ npm install npx vite ``` Access the UI at `http://localhost:5173` - - + ## Goal-Specific Tool Configuration Here is configuration guidance for specific goals. Travel and financial goals have configuration & setup as below.