How to Dockerize my Go App for Development?

My Go Project uses DockerCompose which contains two services :- nginx and mysql.

I intend to dockerize my Go web server as well. I was researching on how to best set up the development environment of my Go project using Docker.

There are two ways I was thinking of getting this done. Can you advise which one is better and why? Also, could you point me to any additional resources that would help me in this regard?

a) Copy the Go App source code to my container in the docker file. And build and run instructions for the Go App also go in the DockerFile. This however, has a disadvantage that any code change will require me to rebuild the image and then start a container for the new image.

b) Share a volume containing the source code of the app with the container. This seems better to me, since now, I can directly attach to my container and build / run the Go binary again.

On our dev team, we take the latter (option b) route for both development and CI builds. You just need to take care to set up your WORKING_DIR and possibly GOPATH correctly.

Also, when building your go webserver image parent the image from SCRATCH and you’ll end up with really small docker images.

Here’s my advice: the Go toolchain is pretty standardized and pretty easy to get. Glide is a good tool for ensuring that an application package is using specific known versions of its dependencies (up to the limits of dependency tracking in the Go ecosystem). Docker does not need to be part of the ordinary development path.

If you really truly have specialized host-system requirements then Vagrant is a purpose-built tool for building developer virtual machines, and it deals with some of the irritating details like “make the application source code visible inside the container”.

The sequence I’d strongly recommend is:

(0) Most developers don’t need Docker, until and unless they need to deploy a test copy of the whole application.
(1) Developers have their own IDE, local go binary, libraries, etc.
(2) Developers write code, go test, get code reviews, repeat, without using Docker at all.
(3) go build a binary of the application.
(4) In a Dockerfile, COPY the application binary into a standard base distribution image (or if you’re brave and built a static binary, into a FROM scratch image).
(5) Your CI system does the go build and docker build automatically to create Docker images.

(If you have very current versions of Docker then you could use a multi-stage build for the last two steps, but from what I can see those versions aren’t widely available in environments like RHEL or cloud CI products.)

Yes, this is the totally normal way to use Docker. Note that this also means that any code change means deleting the old running container, so if you do have persistent data, you need to make sure it’s stored somewhere that will outlive this (IME a database is best, a Docker volume or host directory mount is okay).

This is tricky to set up (read through the forum history, similar questions get asked multiple times a week) and I don’t feel like you really gain much by doing this. You’re also requiring your developers to routinely run commands as root as part of their build sequence which seems like a poor practice from an overall security point of view.

Also, you’ll never deploy your application this way so you’re introducing two different ways to “run the application in Docker” and that will confuse things further.

Thanks for the elaborate reply @dmaze.

My development team needs to have a full test environment on their local since the go code needs to interact with MySQL and with RabbitMQ.

I went ahead with Docker since setting up MySQL and RabbitMQ on Windows/Mac can be a pain and therefore, concluded that Docker would be a good fit since it would give a Linux runtime for all the applications (same as the production environment).

I could have considered Vagrant as well. Just since Docker containers are easy to start (quicker startup times) and the same containers can also be deployed to production, I thought that Docker might be a good fit.

I have now invested into Docker considerably. Can you suggest the best way on how to dockerize the Go app for development?

Thanks for replying @dannchurch. :slight_smile:

Will be careful with everything you mentioned.