Post

Local Development with Docker Compose

Applications generally have external dependencies, such as databases, message queues, and other services. Setting up and managing these dependencies can be time-consuming and error-prone, especially for developers who are new to the application. Docker Compose is a tool that allows you to define and manage multi-container Docker applications. It provides a simple way to set up and run your application and its dependencies in a consistent environment.

Lets walk through an example of how to use Docker Compose for local development.

Use git to clone an exiting application with multiple external dependencies.

1
git clone git@github.com:rizvn/go-mcp-server-demo.git mcp-server-demo

The compose file is located under docker-compose dir

1
cd  mcp-server-demo/docker-compose

Below is the docker compose file for the application. It defines three services:

  • keycloak
  • nginx
  • mcp-server
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
name: mcp-demo
services:
  # Define the Keycloak service
  keycloak:
    image: quay.io/keycloak/keycloak:26.4.0
    command:
      - start-dev
      - --proxy-headers=xforwarded
    environment:
      # Keycloak admin user
      KC_BOOTSTRAP_ADMIN_USERNAME: admin
      KC_BOOTSTRAP_ADMIN_PASSWORD: admin

      # Keycloak configuration
      KC_HOSTNAME_STRICT: false
      KC_HOSTNAME_STRICT_HTTPS: false
      KC_HTTP_ENABLED: true
      KC_HEALTH_ENABLED: true
      KC_METRICS_ENABLED: true

      # JVM options for development
      KC_LOG_LEVEL: INFO

    ports:
      - "9000:8080"
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/health/ready || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 120s
    
    volumes:
      #  use this config for keycloak in development  
      - ./keycloakdb1.mv.db:/opt/keycloak/data/h2/keycloakdb.mv.db

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    depends_on:
      - keycloak
    volumes:
      # use this config for nginx in development
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    restart: unless-stopped

  mcp-server:
    # build from source code for development
    build:
      context: ../mcp-server
      dockerfile: Dockerfile
    restart: unless-stopped
    environment:
      ISSUER_URL: http://host.docker.internal/realms/demo
      MCP_SERVER_URL: http://localhost:8000
    ports:
      - "8000:8000"

Running the following to bring up all the application

1
docker compose up -d

It will create project named mcp-demo and will start all the services defined in the compo

You can use standard commands interact with the containers. Below are some examples of useful commands for managing the containers and viewing logs.:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# list all projects
docker compose ls -a 

# list all running containers for a project
docker compose -p mcp-demo ps

# view logs for all containers
docker compose -p mcp-demo logs -f

# stop and remove all containers
docker compose -p mcp-demo down

# stop and remove a specific container
docker compose -p mcp-demo stop mcp-server

If you make changes to the source code of mcp-server, you can rebuild the image and restart the container to see the changes.

1
2
docker compose -p mcp-demo build mcp-server
docker compose -p mcp-demo restart mcp-server
This post is licensed under CC BY 4.0 by the author.