Skip to content

Add Docker support with multi-stage builds for frontend and agent #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/build
**/dist
LICENSE
README.md
113 changes: 113 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# syntax=docker/dockerfile:1

# Frontend and agent in a single Dockerfile with multiple stages

# Version variables
ARG NODE_VERSION=22.14.0
ARG PNPM_VERSION=9.0.6
ARG PYTHON_VERSION=3.11

################################################################################
# Base stage for frontend (Next.js)
FROM node:${NODE_VERSION}-alpine as frontend-base

# Working directory
WORKDIR /usr/src/app

# Install pnpm
RUN --mount=type=cache,target=/root/.npm \
npm install -g pnpm@${PNPM_VERSION}

################################################################################
# Production dependencies for frontend
FROM frontend-base as frontend-deps

# Download dependencies
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
--mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --prod --frozen-lockfile

################################################################################
# Build stage for frontend
FROM frontend-deps as frontend-build

# Install all dependencies including dev
RUN --mount=type=bind,source=package.json,target=package.json \
--mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \
--mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile

# Copy source files
COPY . .
# Build the application
RUN pnpm run build

################################################################################
# Final stage for frontend
FROM frontend-base as frontend-final

# Configure Node.js for production
ENV NODE_ENV production

# Run as non-root user
USER node

# Copy package.json
COPY package.json .

# Copy dependencies and compiled files
COPY --from=frontend-deps /usr/src/app/node_modules ./node_modules
COPY --from=frontend-build /usr/src/app/.next ./.next
COPY --from=frontend-build /usr/src/app/public ./public

# Expose port
EXPOSE 3000

# Command to run the application
CMD pnpm start

################################################################################
# Base stage for agent (Python)
FROM python:${PYTHON_VERSION}-slim as agent-base

# Install system dependencies
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Install Poetry
RUN pip install poetry

# Configure Poetry to not create virtual environments
RUN poetry config virtualenvs.create false

# Working directory
WORKDIR /usr/src/app/agent

################################################################################
# Dependencies stage for agent
FROM agent-base as agent-deps

# Copy Poetry configuration files
COPY agent/pyproject.toml ./

# Regenerate the lock file first
RUN poetry lock

# Install dependencies without installing the project itself
RUN poetry install --no-interaction --no-ansi --no-root

# Explicitly install langgraph-api package
RUN pip install "langgraph-cli[inmem]" langgraph-api

################################################################################
# Final stage for agent
FROM agent-deps as agent-final

# Copy agent source code
COPY agent/ ./

# Expose port
EXPOSE 8123

# Command to run the agent
CMD poetry run langgraph dev --host 0.0.0.0 --port 8123 --no-browser
44 changes: 44 additions & 0 deletions README.Docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Docker Setup

This project combines a Next.js frontend and a Python langgraph agent.

## Quick Start

```bash
# Start both applications
docker compose up

# Rebuild and start
docker compose build && docker compose up

# Run in background
docker compose up -d

# Stop containers
docker compose down

```

## Access Points

- Frontend: http://localhost:3000
- Agent: http://localhost:8123

## Logs

```bash
# All services
docker compose logs

# Specific service
docker compose logs frontend
docker compose logs agent

# Follow logs
docker compose logs -f
```

## Troubleshooting

The agent container auto-restarts up to 5 times if it fails.
Check logs with `docker compose logs agent`.
51 changes: 51 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Composition file for the complete application (frontend + agent)
services:
# Service for Next.js frontend application
frontend:
build:
context: .
dockerfile: Dockerfile
target: frontend-final
environment:
NODE_ENV: production
ports:
- "3000:3000"
networks:
- app-network
restart: unless-stopped
# Wait for the agent to be up and running
depends_on:
- agent

# Service for Python agent application
agent:
build:
context: .
dockerfile: Dockerfile
target: agent-final
ports:
- "8123:8123"
networks:
- app-network
restart: on-failure:5
# Optional volume for agent data persistence
volumes:
- agent-data:/usr/src/app/agent/data
# Add healthcheck to verify agent is running correctly
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8123/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

# Network definition for service communication
networks:
app-network:
driver: bridge

# Volumes for data persistence
volumes:
agent-data: