Features Tutorials

Running Go applications using Docker Compose in GoLand

Updated and validated on November 17, 2022. You can find more tutorials on how to use containers here. You may also refer to the Docker and Kubernetes sections of our Help documentation.

  1. Go development with Docker Containers
  2. Debugging a Go application inside a Docker container
  3. Running Go applications using Docker Compose in GoLand (this post)
  4. Using Kubernetes from GoLand

Today we’ll be continuing our series on how to use Docker to run and debug Go applications.

In this post, we’ll use Docker Compose to run and debug our application. For this article, we’ll be using the source code here and we’ll switch to the compose branch before we start.

Running Go applications using Docker Compose

Let’s start with running the application using Docker Compose.

Looking at the project we’ve already created, the docker-compose.yaml file might resemble the one found in the repository :

version: "3.8"

services:
  web:
    container_name: dockerdev
    build: ./
    ports:
      - "8000:8000"
    environment:
      DD_DB_HOST: db
    command: /server
    depends_on:
      - db
  db:
    container_name: dockerdev-db
    image: postgres:14.1-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: goland
      POSTGRES_PASSWORD: goland
      POSTGRES_DB: goland
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

In the database section, we need to create a new file called init.sql. The contents of this file are used to set up the database needed for the service to run.

Finally, let’s run the Sync packages of <project> quick-fix in the main.go file to download the pgx library and run the application. This step is needed if you don’t already have version 4.5.0 of pgx in your modules cache.

Running a Docker Compose-based application is similar to other Run Configurations. Click on the double-green arrow button next to the services directive in the docker-compose.yaml. To run just a single service, click on the green arrow next to the service type you want to run, e.g. web or db in our sample configuration above.

Once the configuration runs, a new section called Compose will be available in the Services Tool Window under the Docker node. This will show every suite of Docker Compose services that are running.

Every service definition can be explored, and all running instances are shown for each service. The information available for a container in a Docker Compose service is the same as what’s available for a regular Docker container.

Note: If you are starting heavier services, like a database server, or the services need a bit of initialization time, then your Go service needs to take the startup time of those services into account. In our example code, this is handled using the getDBConnection function, which attempts to connect to the database a few times with an exponential backoff before giving up.

Restarting a Docker Compose service

After making changes to our code, we need to restart our service to reload these changes. At the moment, using the IDE to restart it is a bit complex, as doing so requires you to take the following steps:

  • Go to Run | Edit Configurations and duplicate the existing Docker Compose configuration.
  • Edit the newly created configuration to add the name of the service that should be restarted, and enable the –build option to force the image to be rebuilt before running it

After you do these steps, you can then stop the existing service, remove the existing container, and then launch the newly created configuration.

Pro tip: You can stop and remove the service at the same time using the Delete feature.

Debugging Go applications with Docker Compose

To debug an application using Docker Compose, we need to make changes to both the Dockerfile and docker-compose.yaml files. We can switch to the compose-debug branch of the repository to make this easier to follow.

Now, the docker-compose.yaml file looks like this:

version: "3.8"

services:
  web:
    container_name: dockerdev
    build: ./
    ports:
      - "8000:8000"
      - "40000:40000"
    environment:
      DD_DB_HOST: db
    security_opt:
      - "seccomp:unconfined"
    cap_add:
      - SYS_PTRACE
    command: /dlv --headless --listen=:40000 --api-version=2 exec /server
    depends_on:
      - db
  db:
    container_name: dockerdev-db
    image: postgres:14.1-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: goland
      POSTGRES_PASSWORD: goland
      POSTGRES_DB: goland
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

Note: The important parts here are the security_opt and cap_add properties, as they allow the debugger to run in the Docker environment.

Here’s what your Go Remote debug configuration should look like. 

Running this would be similar to running a regular Docker Compose configuration. We can connect to the container with a Go Remote configuration and our debugger session will start just like it would if we were debugging a regular configuration.

This concludes our article today. We’ve discussed how to use Docker Compose and how to run and debug our application from GoLand. 

In the next article, we’ll cover how to use Kubernetes from the IDE and how to run and debug our applications using it.

Please share your feedback with us, either in the comments section below, on our issue tracker, or by tweeting to us @GoLandIDE.

image description