File size: 5,673 Bytes
046508a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | # Dockerfile Explanation
This Dockerfile is specifically designed for **LangGraph Cloud/LangServe deployment**. It uses the official LangGraph API base image and configures your agent graphs to be served as REST APIs.
## Line-by-Line Breakdown
### 1. Base Image (Line 1)
```dockerfile
FROM langchain/langgraph-api:3.12
```
- **Purpose**: Uses the official LangGraph API base image with Python 3.12
- **What it includes**: Pre-configured LangGraph runtime, LangServe server, and all LangGraph dependencies
- **Why**: This image already has everything needed to serve LangGraph workflows as REST APIs
---
### 2. Install Node Dependencies (Line 9)
```dockerfile
RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt nodes
```
- **Purpose**: Installs the `nodes` package (likely a dependency from your `langgraph.json`)
- **`PYTHONDONTWRITEBYTECODE=1`**: Prevents creating `.pyc` files (smaller image)
- **`uv pip`**: Uses `uv` (fast Python package installer) instead of regular `pip`
- **`--system`**: Installs to system Python (not virtual env)
- **`--no-cache-dir`**: Doesn't cache pip downloads (smaller image)
- **`-c /api/constraints.txt`**: Uses constraint file from base image (ensures compatible versions)
---
### 3. Copy Your Code (Line 14)
```dockerfile
ADD . /deps/job_writer
```
- **Purpose**: Copies your entire project into `/deps/job_writer` in the container
- **Why `/deps/`**: LangGraph API expects dependencies in this directory
- **What gets copied**: All your source code, `pyproject.toml`, `requirements.txt`, etc.
---
### 4. Install Your Package (Lines 19-21)
```dockerfile
RUN for dep in /deps/*; do
echo "Installing $dep";
if [ -d "$dep" ]; then
echo "Installing $dep";
(cd "$dep" && PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e .);
fi;
done
```
- **Purpose**: Installs your `job_writer` package in editable mode (`-e`)
- **How it works**:
- Loops through all directories in `/deps/`
- For each directory, changes into it and runs `pip install -e .`
- The `-e` flag installs in "editable" mode (changes to code are reflected)
- **Why**: Makes your package importable as `job_writing_agent` inside the container
---
### 5. Register Your Graphs (Line 25)
```dockerfile
ENV LANGSERVE_GRAPHS='{"job_app_graph": "/deps/job_writer/src/job_writing_agent/workflow.py:job_app_graph", ...}'
```
- **Purpose**: Tells LangServe which graphs to expose as REST APIs
- **Format**: JSON mapping of `graph_name` β `module_path:attribute_name`
- **What it does**:
- `job_app_graph` β Exposes `JobWorkflow.job_app_graph` property as an API endpoint
- `research_workflow` β Exposes the research subgraph
- `data_loading_workflow` β Exposes the data loading subgraph
- **Result**: Each graph becomes a REST API endpoint like `/invoke/job_app_graph`
---
### 6. Protect LangGraph API (Lines 33-35)
```dockerfile
RUN mkdir -p /api/langgraph_api /api/langgraph_runtime /api/langgraph_license && \
touch /api/langgraph_api/__init__.py /api/langgraph_runtime/__init__.py /api/langgraph_license/__init__.py
RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir --no-deps -e /api
```
- **Purpose**: Prevents your dependencies from accidentally overwriting LangGraph API packages
- **How**:
1. Creates placeholder `__init__.py` files for LangGraph packages
2. Reinstalls LangGraph API (without dependencies) to ensure it's not overwritten
- **Why**: If your `requirements.txt` has conflicting versions, this ensures LangGraph API stays intact
---
### 7. Cleanup Build Tools (Lines 37-41)
```dockerfile
RUN pip uninstall -y pip setuptools wheel
RUN rm -rf /usr/local/lib/python*/site-packages/pip* ...
RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx
```
- **Purpose**: Removes all build tools to make the image smaller and more secure
- **What gets removed**:
- `pip`, `setuptools`, `wheel` (Python build tools)
- `uv` and `uvx` (package installers)
- **Why**: These tools aren't needed at runtime, only during build
- **Security**: Smaller attack surface (can't install malicious packages at runtime)
---
### 8. Set Working Directory (Line 45)
```dockerfile
WORKDIR /deps/job_writer
```
- **Purpose**: Sets the default directory when the container starts
- **Why**: Makes it easier to reference files relative to your project root
---
## How It Works at Runtime
When this container runs:
1. **LangServe starts automatically** (from base image)
2. **Reads `LANGSERVE_GRAPHS`** environment variable
3. **Imports your graphs** from the specified paths
4. **Exposes REST API endpoints**:
- `POST /invoke/job_app_graph` - Main workflow
- `POST /invoke/research_workflow` - Research subgraph
- `POST /invoke/data_loading_workflow` - Data loading subgraph
5. **Handles state management** automatically (checkpointing, persistence)
## Example API Usage
Once deployed, you can call your agent like this:
```bash
curl -X POST http://your-deployment/invoke/job_app_graph \
-H "Content-Type: application/json" \
-d '{
"resume_path": "...",
"job_description_source": "...",
"content": "cover_letter"
}'
```
## Key Points
β
**Optimized for LangGraph Cloud** - Uses official base image
β
**Automatic API generation** - No need to write FastAPI code
β
**State management** - Built-in checkpointing and persistence
β
**Security** - Removes build tools from final image
β
**Small image** - No-cache installs, no bytecode files
This is the **easiest deployment option** for LangGraph apps - just build and push this Docker image!
|