Connecting services with Docker Compose

Now that you have containerized the Golang application, you will use Docker Compose to connect your services together. You will connect the Golang application, Prometheus, and Grafana services together to monitor the Golang application with Prometheus and Grafana.

Creating a Docker Compose file

Create a new file named compose.yml in the root directory of your Golang application. The Docker Compose file contains instructions to run multiple services and connect them together.

Here is a Docker Compose file for a project that uses Golang, Prometheus, and Grafana. You will also find this file in the go-prometheus-monitoring directory.

services:
  api:
    container_name: go-api
    build:
      context: .
      dockerfile: Dockerfile
    image: go-api:latest
    ports:
      - 8000:8000
    networks:
      - go-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 5
    develop:
      watch:
        - path: .
          action: rebuild
      
  prometheus:
    container_name: prometheus
    image: prom/prometheus:v2.55.0
    volumes:
      - ./Docker/prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090
    networks:
      - go-network
  
  grafana:
    container_name: grafana
    image: grafana/grafana:11.3.0
    volumes:
      - ./Docker/grafana.yml:/etc/grafana/provisioning/datasources/datasource.yaml
      - grafana-data:/var/lib/grafana
    ports:
      - 3000:3000
    networks:
      - go-network
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=password

volumes:
  grafana-data:

networks:
  go-network:
    driver: bridge

Understanding the Docker Compose file

The Docker Compose file consists of three services:

  • Golang application service: This service builds the Golang application using the Dockerfile and runs it in a container. It exposes the application's port 8000 and connects to the go-network network. It also defines a health check to monitor the application's health. You have also used healthcheck to monitor the health of the application. The health check runs every 30 seconds and retries 5 times if the health check fails. The health check uses the curl command to check the /health endpoint of the application. Apart from the health check, you have also added a develop section to watch the changes in the application's source code and rebuild the application using the Docker Compose Watch feature.

  • Prometheus service: This service runs the Prometheus server in a container. It uses the official Prometheus image prom/prometheus:v2.55.0. It exposes the Prometheus server on port 9090 and connects to the go-network network. You have also mounted the prometheus.yml file from the Docker directory which is present in the root directory of your project. The prometheus.yml file contains the Prometheus configuration to scrape the metrics from the Golang application. This is how you connect the Prometheus server to the Golang application.

    global:
      scrape_interval: 10s
      evaluation_interval: 10s
    
    scrape_configs:
      - job_name: myapp
        static_configs:
          - targets: ["api:8000"]

    In the prometheus.yml file, you have defined a job named myapp to scrape the metrics from the Golang application. The targets field specifies the target to scrape the metrics from. In this case, the target is the Golang application running on port 8000. The api is the service name of the Golang application in the Docker Compose file. The Prometheus server will scrape the metrics from the Golang application every 10 seconds.

  • Grafana service: This service runs the Grafana server in a container. It uses the official Grafana image grafana/grafana:11.3.0. It exposes the Grafana server on port 3000 and connects to the go-network network. You have also mounted the grafana.yml file from the Docker directory which is present in the root directory of your project. The grafana.yml file contains the Grafana configuration to add the Prometheus data source. This is how you connect the Grafana server to the Prometheus server. In the environment variables, you have set the Grafana admin user and password, which will be used to log in to the Grafana dashboard.

    apiVersion: 1
    datasources:
    - name: Prometheus (Main)
      type: prometheus
      url: http://prometheus:9090
      isDefault: true

    In the grafana.yml file, you have defined a Prometheus data source named Prometheus (Main). The type field specifies the type of the data source, which is prometheus. The url field specifies the URL of the Prometheus server to fetch the metrics from. In this case, the URL is http://prometheus:9090. prometheus is the service name of the Prometheus server in the Docker Compose file. The isDefault field specifies whether the data source is the default data source in Grafana.

Apart from the services, the Docker Compose file also defines a volume named grafana-data to persist the Grafana data and a network named go-network to connect the services together. You have created a custom network go-network to connect the services together. The driver: bridge field specifies the network driver to use for the network.

Building and running the services

Now that you have the Docker Compose file, you can build the services and run them together using Docker Compose.

To build and run the services, run the following command in the terminal:

$ docker compose up

The docker compose up command builds the services defined in the Docker Compose file and runs them together. You will see the similar output in the terminal:

 ✔ Network go-prometheus-monitoring_go-network  Created                                                           0.0s 
 ✔ Container grafana                            Created                                                           0.3s 
 ✔ Container go-api                             Created                                                           0.2s 
 ✔ Container prometheus                         Created                                                           0.3s 
Attaching to go-api, grafana, prometheus
go-api      | [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
go-api      | 
go-api      | [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
go-api      |  - using env:     export GIN_MODE=release
go-api      |  - using code:    gin.SetMode(gin.ReleaseMode)
go-api      | 
go-api      | [GIN-debug] GET    /metrics                  --> main.PrometheusHandler.func1 (3 handlers)
go-api      | [GIN-debug] GET    /health                   --> main.main.func1 (4 handlers)
go-api      | [GIN-debug] GET    /v1/users                 --> main.main.func2 (4 handlers)
go-api      | [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
go-api      | Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
go-api      | [GIN-debug] Listening and serving HTTP on :8000
prometheus  | ts=2025-03-15T05:57:06.676Z caller=main.go:627 level=info msg="No time or size retention was set so using the default time retention" duration=15d
prometheus  | ts=2025-03-15T05:57:06.678Z caller=main.go:671 level=info msg="Starting Prometheus Server" mode=server version="(version=2.55.0, branch=HEAD, revision=91d80252c3e528728b0f88d254dd720f6be07cb8)"
grafana     | logger=settings t=2025-03-15T05:57:06.865335506Z level=info msg="Config overridden from command line" arg="default.log.mode=console"
grafana     | logger=settings t=2025-03-15T05:57:06.865337131Z level=info msg="Config overridden from Environment variable" var="GF_PATHS_DATA=/var/lib/grafana"
grafana     | logger=ngalert.state.manager t=2025-03-15T05:57:07.088956839Z level=info msg="State
.
.
grafana     | logger=plugin.angulardetectorsprovider.dynamic t=2025-03-15T05:57:07.530317298Z level=info msg="Patterns update finished" duration=440.489125ms

The services will start running, and you can access the Golang application at http://localhost:8000, Prometheus at http://localhost:9090/health, and Grafana at http://localhost:3000. You can also check the running containers using the docker ps command.

$ docker ps

Summary

In this section, you learned how to connect services together using Docker Compose. You created a Docker Compose file to run multiple services together and connect them using networks. You also learned how to build and run the services using Docker Compose.

Related information:

Next, you will learn how to develop the Golang application with Docker Compose and monitor it with Prometheus and Grafana.

Next steps

In the next section, you will learn how to develop the Golang application with Docker. You will also learn how to use Docker Compose Watch to rebuild the image whenever you make changes to the code. Lastly, you will test the application and visualize the metrics in Grafana using Prometheus as the data source.

Page options