Docker provides a consistent way to package and deploy your mock APIs. This guide shows you how to containerize Apicentric services for local development, CI/CD, and production environments.
Why use Docker
Consistency : Same environment across development, testing, and production
Isolation : Services run independently without conflicting dependencies
Portability : Easy to share and deploy across different machines
CI/CD integration : Simple to run in automated pipelines
Quick start
The fastest way to run Apicentric in Docker:
docker run -p 8080:8080 -v $( pwd ) /services:/app/services apicentric/apicentric:latest
Basic Dockerfile
Create a Dockerfile for your mock services:
FROM debian:bookworm-slim
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
libssl3 \
curl \
&& rm -rf /var/lib/apt/lists/*
# Install Apicentric
RUN curl -fsSL https://raw.githubusercontent.com/pmaojo/apicentric/main/scripts/install.sh | sh
# Create directories
WORKDIR /app
RUN mkdir -p /app/services /app/data
# Copy service definitions
COPY services/ /app/services/
# Set environment variables
ENV APICENTRIC_PORT=8080
ENV APICENTRIC_HOST=0.0.0.0
ENV RUST_LOG=info,apicentric=debug
# Expose port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Start simulator
CMD [ "apicentric" , "simulator" , "start" , "--services-dir" , "/app/services" ]
Create your service directory
mkdir -p services
cat > services/api.yaml << EOF
name: my-api
server:
port: 8080
base_path: /api
endpoints:
- method: GET
path: /health
responses:
200:
content_type: application/json
body: '{"status": "healthy"}'
EOF
docker build -t my-mock-api .
docker run -p 8080:8080 my-mock-api
curl http://localhost:8080/api/health
Multi-stage build
For production deployments, use a multi-stage build to include both the Rust backend and WebUI:
# Stage 1: Build Frontend
FROM node:22-alpine AS frontend-builder
WORKDIR /app/webui
# Copy package files
COPY webui/package*.json ./
RUN npm ci
# Copy frontend source
COPY webui/ ./
# Build Next.js application
RUN npm run build
# Stage 2: Build Backend
FROM rust:1.92-bookworm AS backend-builder
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# Copy Cargo files
COPY Cargo.toml Cargo.lock ./
# Copy source code
COPY src/ ./src/
COPY examples/ ./examples/
# Build with default features
RUN cargo build --release --bin apicentric
# Stage 3: Runtime
FROM debian:bookworm-slim
WORKDIR /app
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
libssl3 \
curl \
&& rm -rf /var/lib/apt/lists/*
# Copy backend binary
COPY --from=backend-builder /app/target/release/apicentric /usr/local/bin/apicentric
# Copy frontend build
COPY --from=frontend-builder /app/webui/.next/standalone ./webui
COPY --from=frontend-builder /app/webui/.next/static ./webui/.next/static
COPY --from=frontend-builder /app/webui/public ./webui/public
# Create directories for data and services
RUN mkdir -p /app/data /app/services
# Copy service definitions
COPY services/ /app/services/
# Set environment variables
ENV APICENTRIC_PORT=8080
ENV APICENTRIC_HOST=0.0.0.0
ENV APICENTRIC_DATA_DIR=/app/data
ENV APICENTRIC_SERVICES_DIR=/app/services
ENV RUST_LOG=info,apicentric=debug
# Expose ports
EXPOSE 8080 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Start cloud server
CMD [ "apicentric" , "cloud" ]
Build it:
docker build -f Dockerfile.production -t my-mock-api:prod .
Docker Compose
Manage multiple services with Docker Compose:
version : '3.8'
services :
apicentric :
build : .
ports :
- "8080:8080"
volumes :
- ./services:/app/services
- ./data:/app/data
environment :
- APICENTRIC_PORT=8080
- APICENTRIC_HOST=0.0.0.0
- RUST_LOG=info,apicentric=debug
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost:8080/health" ]
interval : 30s
timeout : 3s
retries : 3
start_period : 5s
restart : unless-stopped
# Additional service for different API
users-api :
build : .
ports :
- "9001:9001"
volumes :
- ./services/users:/app/services
environment :
- APICENTRIC_PORT=9001
restart : unless-stopped
# Another mock API
products-api :
build : .
ports :
- "9002:9002"
volumes :
- ./services/products:/app/services
environment :
- APICENTRIC_PORT=9002
restart : unless-stopped
Start all services:
Stop all services:
Volume mounting
Mount service definitions for hot-reloading during development:
docker run -p 8080:8080 \
-v $( pwd ) /services:/app/services \
-v $( pwd ) /data:/app/data \
my-mock-api
Changes to service files will be detected automatically, and services will reload without restarting the container.
Environment variables
Configure Apicentric using environment variables:
docker run -p 8080:8080 \
-e APICENTRIC_PORT= 8080 \
-e APICENTRIC_HOST= 0.0.0.0 \
-e APICENTRIC_SERVICES_DIR=/app/services \
-e APICENTRIC_DATA_DIR=/app/data \
-e RUST_LOG=info,apicentric=debug \
-v $( pwd ) /services:/app/services \
my-mock-api
Or use an .env file with Docker Compose:
APICENTRIC_PORT = 8080
APICENTRIC_HOST = 0.0.0.0
RUST_LOG = info, apicentric = debug
Reference it in docker-compose.yml:
services :
apicentric :
build : .
env_file : .env
volumes :
- ./services:/app/services
CI/CD integration
GitHub Actions
.github/workflows/docker.yml
name : Build and Push Docker Image
on :
push :
branches : [ main ]
jobs :
docker :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v3
- name : Set up Docker Buildx
uses : docker/setup-buildx-action@v2
- name : Build image
run : docker build -t my-mock-api:${{ github.sha }} .
- name : Test services
run : |
docker run -d -p 8080:8080 --name test-api my-mock-api:${{ github.sha }}
sleep 5
curl -f http://localhost:8080/api/health || exit 1
docker stop test-api
- name : Push to registry
if : success()
run : |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker tag my-mock-api:${{ github.sha }} my-mock-api:latest
docker push my-mock-api:latest
GitLab CI
stages :
- build
- test
- deploy
build :
stage : build
image : docker:latest
services :
- docker:dind
script :
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
test :
stage : test
image : docker:latest
services :
- docker:dind
script :
- docker run -d -p 8080:8080 --name test-api $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- sleep 5
- apk add curl
- curl -f http://localhost:8080/api/health
Production best practices
Avoid latest tags in production:
FROM debian:bookworm-slim@sha256:...
FROM gcr.io/distroless/base-debian12
COPY --from=builder /usr/local/bin/apicentric /apicentric
CMD [ "/apicentric" , "simulator" , "start" ]
RUN useradd -m -u 1000 apicentric
USER apicentric
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
docker run -p 8080:8080 \
--secret api_key \
-e API_KEY_FILE=/run/secrets/api_key \
my-mock-api
Kubernetes deployment
Deploy to Kubernetes:
apiVersion : apps/v1
kind : Deployment
metadata :
name : apicentric
spec :
replicas : 2
selector :
matchLabels :
app : apicentric
template :
metadata :
labels :
app : apicentric
spec :
containers :
- name : apicentric
image : my-mock-api:latest
ports :
- containerPort : 8080
env :
- name : APICENTRIC_PORT
value : "8080"
- name : RUST_LOG
value : "info,apicentric=debug"
volumeMounts :
- name : services
mountPath : /app/services
livenessProbe :
httpGet :
path : /health
port : 8080
initialDelaySeconds : 10
periodSeconds : 30
readinessProbe :
httpGet :
path : /health
port : 8080
initialDelaySeconds : 5
periodSeconds : 10
resources :
requests :
memory : "128Mi"
cpu : "100m"
limits :
memory : "512Mi"
cpu : "500m"
volumes :
- name : services
configMap :
name : apicentric-services
---
apiVersion : v1
kind : Service
metadata :
name : apicentric
spec :
selector :
app : apicentric
ports :
- port : 80
targetPort : 8080
type : LoadBalancer
Apply it:
kubectl apply -f k8s/deployment.yaml
Troubleshooting
Check logs:
docker logs < container-i d >
Services not loading
Verify volume mount:
docker exec -it < container-i d > ls /app/services
Port conflicts
Use different host ports:
docker run -p 9090:8080 my-mock-api
Permission issues
Ensure proper file permissions:
When mounting volumes on Windows, use absolute paths and ensure Docker Desktop has access to the directory.
Next steps
Contract testing Run contract tests in Docker
Digital twin setup Containerize IoT device twins
Creating mocks Learn about service definitions
Import specs Import existing API specifications