Docker Deployment

This tutorial shows how to deploy ros2_medkit using Docker containers.

Overview

Docker deployment is useful for:

  • Reproducible environments

  • CI/CD pipelines

  • Production deployments

  • Testing with simulation (e.g., Nav2, Isaac Sim)

Quick Start with Demo

The selfpatch_demos repository includes a complete Docker setup with TurtleBot3 and Nav2:

git clone https://github.com/selfpatch/selfpatch_demos.git
cd selfpatch_demos/demos/turtlebot3_integration
docker-compose up

This starts:

  • TurtleBot3 simulation with Nav2

  • ros2_medkit_gateway

  • sovd_web_ui (Web UI)

Access the UI at http://localhost:3000 (Docker container maps port 80 to 3000).

Note

Port confusion:

Building the Gateway Image

Using the provided Dockerfile:

cd ros2_medkit
docker build -t ros2_medkit_gateway:latest \
  -f src/ros2_medkit_gateway/Dockerfile .

Multi-stage build for smaller images:

# Build stage
FROM ros:jazzy AS builder
WORKDIR /ws
COPY . src/ros2_medkit
RUN apt-get update && rosdep install --from-paths src --ignore-src -r -y
RUN colcon build --packages-select ros2_medkit_gateway

# Runtime stage
FROM ros:jazzy
COPY --from=builder /ws/install /opt/ros2_medkit
ENV ROS_PACKAGE_PATH=/opt/ros2_medkit
ENTRYPOINT ["/opt/ros2_medkit/ros2_medkit_gateway/lib/ros2_medkit_gateway/gateway_node"]

Docker Compose Configuration

Example docker-compose.yml for your own setup:

version: '3.8'

services:
  gateway:
    image: ros2_medkit_gateway:latest
    ports:
      - "8080:8080"
    environment:
      - ROS_DOMAIN_ID=42
    command: >
      ros2 launch ros2_medkit_gateway gateway.launch.py
      server_host:=0.0.0.0
    networks:
      - ros2_net

networks:
  ros2_net:
    driver: bridge

Network Configuration

Important: When running in Docker, configure the gateway to listen on all interfaces:

server:
  host: "0.0.0.0"  # Listen on all interfaces, not just localhost

ROS 2 Discovery:

For containers to discover each other, use the same ROS_DOMAIN_ID:

environment:
  - ROS_DOMAIN_ID=42

Or use the DDS discovery configuration for specific peers.

CORS for Web UI

When the Web UI runs in a separate container or host, enable CORS:

cors:
  allowed_origins:
    - "http://localhost:5173"
    - "http://web_ui:80"
  allowed_methods: ["GET", "PUT", "POST", "DELETE", "OPTIONS"]
  allowed_headers: ["Content-Type", "Accept", "Authorization"]

Volume Mounts

For development (live code changes):

volumes:
  - ./src:/ws/src:ro
  - ./config:/ws/config:ro

For certificates:

volumes:
  - ./certs:/etc/ros2_medkit/certs:ro

Health Checks

Add health checks to ensure the gateway is ready:

services:
  gateway:
    # ...
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s

Production Considerations

  1. Use specific image tags (not latest):

    image: ros2_medkit_gateway:<version-tag>
    
  2. Set resource limits:

    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
    
  3. Enable TLS for production:

    See Configuring HTTPS/TLS for certificate configuration.

  4. Use secrets for credentials:

    secrets:
      jwt_secret:
        file: ./secrets/jwt_secret.txt
    
    services:
      gateway:
        secrets:
          - jwt_secret
    
  5. Configure logging:

    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    

Running with Simulation

Nav2 + TurtleBot3:

See the TurtleBot3 integration demo for a complete example.

Isaac Sim:

The gateway’s topic-based discovery works with Isaac Sim which publishes topics without creating ROS 2 nodes:

docker-compose up gateway
# Start Isaac Sim separately
# Gateway will discover /carter1, /carter2, etc. from topics

Troubleshooting

Container can’t connect to ROS 2 network

  • Ensure all containers use the same network

  • Check ROS_DOMAIN_ID is consistent

  • Try network_mode: host for development

Gateway returns empty areas/components

  • Wait for ROS 2 discovery (can take a few seconds)

  • Check that other nodes are running and visible

Web UI can’t connect to gateway

  • Verify CORS is configured correctly

  • Check the gateway host is 0.0.0.0, not 127.0.0.1

See Also