Solarian Programmer

My programming ramblings

Docker on macOS - Installation and Getting Started with GCC 8 in a Docker container

Posted on March 26, 2019 by Paul

In this article I will show you how to install Docker on macOS. In order to exemplify the use of Docker, we’ll use a container to build and run a simple C or C++ application with GCC 8.

There is also a video version of this tutorial:

Start by downloading Docker Desktop for macOS. If you don’t have a Docker account, sign up for one it is free and it only takes a few minutes to create one. Once you are logged in, you should be able to get the Docker app for macOS. Open the dmg file and drag the installer to your Applications, you can safely accept all the default settings.

After the installation is finished, start the Docker application and wait for the message Docker Desktop is now up and running. Next, open a Terminal and check if the docker command is available:

1 docker version

This is what I see on my machine:

 1 ~ $ docker version
 2 Client: Docker Engine - Community
 3  Version:           18.09.2
 4  API version:       1.39
 5  Go version:        go1.10.8
 6  Git commit:        6247962
 7  Built:             Sun Feb 10 04:12:39 2019
 8  OS/Arch:           darwin/amd64
 9  Experimental:      false
10 
11 Server: Docker Engine - Community
12  Engine:
13   Version:          18.09.2
14   API version:      1.39 (minimum version 1.12)
15   Go version:       go1.10.6
16   Git commit:       6247962
17   Built:            Sun Feb 10 04:13:06 2019
18   OS/Arch:          linux/amd64
19   Experimental:     false
20 ~ $

As mentioned in the introduction, I will exemplify the use of a Docker container with a simple C application. Create a new directory for your application and name it myapp:

1 mkdir myapp
2 cd myapp

Next, let’s write a simple C program that will print Hello, World!, save the file as test.c:

1 #include <stdio.h>
2 
3 int main(void) {
4     printf("Hello, World\n");
5 }

In order to make our life easier and to be able to, optionally, add more files to the project we’ll also write a simple Makefile:

1 test: test.c
2 	gcc -std=c17 -Wall -Wextra -pedantic test.c -o test
3 
4 prog: test
5 	./test
6 
7 clean:
8 	rm test

At this point, myapp folder should contain two files: test.c and Makefile.

Next, we are going to create a temporary container in which we will build and run the above application. Our container will be based on the official GCC image from Docker Hub.

Make sure you are in myapp folder and run the next command from a Terminal:

1 docker run --rm -v "$PWD":/myapp -w /myapp gcc:8.3 make prog

The above command will mount the current folder as /myapp in the container, set the working folder to myapp. First time when you will run the command it will download the image from the Docker Hub. Finally make prog will be executed inside the container. Next time when you will run the command it will use the existing image and will be much faster.

This is what I see on my Mac if I run the above command:

 1 ~/myapp $ docker run --rm -v "$PWD":/myapp -w /myapp gcc:8.3 make prog
 2 Unable to find image 'gcc:8.3' locally
 3 8.3: Pulling from library/gcc
 4 22dbe790f715: Pull complete
 5 0250231711a0: Pull complete
 6 6fba9447437b: Pull complete
 7 c2b4d327b352: Pull complete
 8 270e1baa5299: Pull complete
 9 dcb7d967a3c2: Pull complete
10 bb72c68f6b76: Pull complete
11 d9e62e567147: Pull complete
12 bafa2d9f78b1: Pull complete
13 Digest: sha256:27442bf0830392b584494a7c2ebe36a2c493b6e18da8dab0757a3affdbee8a02
14 Status: Downloaded newer image for gcc:8.3
15 gcc -std=c17 -Wall -Wextra -pedantic test.c -o test
16 ./test
17 Hello, World
18 ~/myapp $

If your run the command again, it won’t pull (download) the image, because you already have it. Also, because the C file was not changed it will use the already created executable:

1 ~/myapp $ docker run --rm -v "$PWD":/myapp -w /myapp gcc:8.3 make prog
2 ./test
3 Hello, World
4 ~/myapp $

Change the C file, for example, you can print Hello, World from Docker!, save it and run the command again:

1 ~/myapp $ docker run --rm -v "$PWD":/myapp -w /myapp gcc:8.3 make prog
2 gcc -std=c17 -Wall -Wextra -pedantic test.c -o test
3 ./test
4 Hello, World from Docker!
5 ~/myapp $

This time the app was first recompiled and than executed.

While this approach is slower than using GCC directly on your macOS, it has the advantage that it doesn’t mess with your system and that it can be easily removed if necessary.

If you want to learn more about Docker, I recommend reading Docker: Up & Running by S. P. Kane and K. Matthias:


Show Comments