Running Go applications using Docker Compose in GoLand
- Go development with Docker Containers
- Debugging a Go application inside a Docker container
- Running Go applications using Docker Compose in GoLand (this post)
- 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.