Skip to main content

Docker Deployment

The entire system deploys as three Docker services with a single command.

Quick Deploy

git clone https://github.com/sinhaparth5/distributed-graph-system
cd distributed-graph-system
docker compose up --build

Docker Compose Configuration

services:
frontend:
build: ./frontend
args:
VITE_API_BASE: http://localhost:8000
ports:
- "3000:80"
depends_on:
- mpi-master

mpi-master:
build: .
environment:
- NODE_ROLE=master
ports:
- "8000:8000"
networks:
mpi-network:
ipv4_address: 172.28.1.2

mpi-worker:
build: .
environment:
- NODE_ROLE=worker
networks:
mpi-network:
ipv4_address: 172.28.1.3
depends_on:
- mpi-master

networks:
mpi-network:
driver: bridge
ipam:
config:
- subnet: 172.28.1.0/24

Frontend Multi-Stage Build

# Stage 1: Build React app
FROM node:22-alpine AS builder
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
ARG VITE_API_BASE=http://localhost:8000
ENV VITE_API_BASE=$VITE_API_BASE
RUN pnpm build

# Stage 2: Serve with nginx
FROM nginx:1.27-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

VITE_API_BASE is a build argument — Vite bakes environment variables into the JavaScript bundle at build time. The pre-compiled WASM artifacts (graph_wasm_bg.wasm, graph_wasm.js) are included in the source tree and copied into the Docker build context.

Backend Dockerfile

FROM rust:1.75-slim AS builder

# Install OpenMPI
RUN apt-get update && apt-get install -y \
openmpi-bin libopenmpi-dev \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src

RUN cargo build --release

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y openmpi-bin && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/server /usr/local/bin/server
COPY hostfile /etc/mpi/hostfile

ENTRYPOINT ["/usr/local/bin/server"]

nginx Configuration

server {
listen 80;
root /usr/share/nginx/html;
index index.html;

# SPA fallback for React Router
location / {
try_files $uri $uri/ /index.html;
}

# Long cache for hashed assets
location ~* \.(js|css|wasm|png|jpg|ico)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}

# No cache for index.html
location = /index.html {
add_header Cache-Control "no-cache";
}

# Gzip compression
gzip on;
gzip_types text/plain application/javascript text/css application/wasm;
}

Scaling Workers

To add more MPI workers, update the compose file:

mpi-worker-2:
build: .
environment:
- NODE_ROLE=worker
networks:
mpi-network:
ipv4_address: 172.28.1.4
depends_on:
- mpi-master

And add the new worker to the MPI hostfile used by the master.

Viewing Logs

# All services
docker compose logs -f

# Just the backend
docker compose logs -f mpi-master

# Just the worker
docker compose logs -f mpi-worker

Rebuilding After Changes

# Rebuild a specific service
docker compose build mpi-master
docker compose up mpi-master

# Full rebuild
docker compose down && docker compose up --build