Although some other alternatives are available, such as the rkt container engine, Docker Engine has become the de facto containerization platform in the past 2-3 years. In "Using Java with Docker Engine," we discussed creating a Java application with Docker Engine. Docker Engine makes better use of the operating system kernel in comparison to a virtualization platform such as VirtualBox or VMWare because a single Docker container does not make use of a whole OS kernel, whereas a single virtual machine does. Each Docker container includes its own filesystem and networking, which makes it an isolated process on the Docker Engine. A single Docker Engine with multiple Docker containers running in isolation makes it feasible to run different applications and even have some containers make use of other containers. One of the main benefits of Docker Engine is the ease of installation and configuration for software. In this tutorial, we shall discuss using C++ on Docker Engine. This tutorial has the following sections:
Docker is pre-installed on some OSes, such as CoreOS, and needs to be installed if some other OS—such as Ubuntu, Amazon Linux, or Redhat Linux—is used. We shall be using CoreOS. We shall use the CoreOS Linux (Stable) on EC2, which may be accessed at https://aws.amazon.com/marketplace/pp/B01H62FDJM?qid=1478625912213&sr=0-1&ref_=srh_res_product_title. Click Continue. Select 1-Click Launch and the default Version, which is the latest available. Select a Region and a EC2 Instance Type.
Select the "default" security group, which provides access from all Source IPs. Select a Key Pair, which may have been created previously.
Click Launch with 1-click.
A single instance of CoreOS Linux gets started on EC2. Obtain the Public DNS or the Public IP address for the CoreOS instance from the Console.
Using the Key Pair and the Public IP (or Public DNS) SSH, log in into the CoreOS instance.
- ssh -i "coreos.pem" core@54.197.150.238
The CoreOS instance gets logged into and the command prompt gets displayed.
We shall use a Hello World C++ application to demonstrate the use of C++ on Docker, and the application HelloWorld.cpp is listed:
- #include <iostream>
- using namespace std;
- int main()
- {
- cout << "Hello world" << endl;
- cout << "From a C++ Program" << endl;
- return 0;
- }
Create a file called HelloWorld.cpp in a vi editor and copy the listing to the file.
Two options are available to run the C++ application:
We shall be using the Docker image "gcc" available on the Docker Hub. The "gcc" Docker image is the GNU Compiler Collection with support for several languages, including C and C++. Two of the main commands that could be used for C/C++ application are gcc and g++. The differences between the two are discussed in the following table.
gcc | g++ |
GNU C Compiler | GNU C++ Compiler |
Compiles *.c and *.cpp files as C and C++, repectively | Compiles *.c and *.cpp, but they are treated as C++ files |
Does not link in the C++ libraries | Automatically links in the C++ libraries |
Should be used with C applications | Should be used with C++ applications |
Next, we shall use the g++ command to run a C++ application. Create a Dockerfile (in a vi editor) in the same directory as the HelloWorld.cpp file. A Dockerfile contains instructions to build a Docker image that could be used to run a Docker container. Copy the following listing to the Dockerfile.
- FROM gcc:4.9
- COPY . /HelloWorld
- WORKDIR /HelloWorld
- RUN g++ --o HelloWorld HelloWorld.cpp
- CMD ["./HelloWorld"]
The Dockerfile instructions are as follows.
Dockerfile Instruction | Description |
FROM gcc:4.9 | The Docker image to use as the base image is gcc with tag 4.9. |
COPY . /HelloWorld | Copy the files in the current directory to the /HelloWorld directory. |
WORKDIR /HelloWorld | Set the /HelloWorld directory as the working directory. |
RUN g++ --o HelloWorld HelloWorld.cpp | Run the gcc command g++ with output as "HelloWorld" and input as "HelloWorld.cpp". The command generates a runnable application called "HelloWorld" |
CMD ["./HelloWorld"] | Run the compiled, runnable application ./HelloWorld |
The Dockerfile is shown in the vi editor.
The root directory should list two files: Dockerfile and HelloWorld.cpp.
Before creating a Docker image, create the directory /HelloWorld and set its permissions to global (777).
- sudo mkdir /HelloWorld
- chmod 777 /HelloWorld
Run the docker build command to create a Docker image called helloworld:v1 from the Dockerfile.
- docker build -t helloworld:v1 .
The Docker image gets created.
Subsequently, list the Docker images.
- docker images
The helloworld image tag v1 gets listed.
Having created the Docker image, run the a Docker container with the docker run command. The Docker container may optionally be named, "HelloWorld" for example, with the --name option. If the --name option is not used, a random name is used for the Docker container. The --rm option is called the "Clean up" option and removes the Docker container and the filesystem & volumes associated with the container after it has run. Run the following docker run command for the Docker image helloworld:v1.
- docker run -it --rm --name HelloWorld helloworld:v1
The C++ application in the Docker image runs to produce an output.
It was mentioned previously that the g++ command is used for C++ applications and the gcc command is used for C applications. The main difference between the two is that gcc does not link the standard C++ libraries. But, the standard C++ libraries could be linked explicitly when using the gcc commnd; this is what we shall discuss in this section. Before creating a Docker image using the gcc command, remove the Docker image helloworld:v1 because we will create the same name Docker image with gcc.
- docker rmi helloworld:v1
The standard C++ libraries could be linked when using the gcc command with the --lstdc++ option. Modify the Dockerfile to replace the g++ command with the gcc command as in following listing.
- FROM gcc:4.9
- COPY . /HelloWorld
- WORKDIR /HelloWorld
- RUN gcc --o HelloWorld HelloWorld.cpp --lstdc++
- CMD ["./HelloWorld"]
The modified Dockerfile is shown in the vi editor.
The same two files, Dockerfile and HelloWorld.cpp, should get listed.
Run the same docker build command to create the Docker image helloworld:v1.
- docker build -t helloworld:v1
A Docker image gets generated, but contains a different command, the gcc command instead of the g++ command to run the C++ application. List the Docker images, and the helloworld:v1 Docker image should get listed in addition to the gcc Docker image.
Next, run the same docker run command to run a Docker container for the Docker image helloworld:v1.
- docker run --it --rm --name HelloWorld helloworld:v1
The same output get generated.
The Docker containers get removed when using the --rm option. List the running and exited Docker containers with the following commands, respectively:
- docker ps
- docker ps -a
Because the Docker containers have been removed no Docker container should get listed running or exited.
In the previous two sections, we compiled the Docker application into a Docker image with docker build and subsequently ran a Docker container with docker run. In the next section, we shall not create a Docker image but instead only compile the HelloWorld.cpp file into a runnable application with docker run with the g++ command being invoked as a command arg to the docker run command. Subsequently, we shall run the application binaries HelloWorld, separately.
To compile only the HelloWorld.cpp application into HelloWorld runnable application, run the following command that invokes the g++ GNU C++ compiler.
- docker run --rm --v "$PWD":/HelloWorld
- --w /HelloWorld gcc:4.9 g++
- --o HelloWorld HelloWorld.cpp
The --rm option removes the container after it has run, but does not remove the application binaries generated. The --v option adds the current directory as a volume and the --w option sets the working directory to the volume.
Subsequently, listing the files lists the HelloWorld application generated.
Next, run the HelloWorld application.
- ./HelloWorld
The C++ application output gets generated.
We used the g++ compiler with the docker run command to generate the application binaries, but the gcc command with the --lstdc++ option may be used just as well.
- docker run --rm --v /HelloWorld
- --w /HelloWorld gcc:4.9 gcc
- --o HelloWorld HelloWorld.cpp
- --lstdc++
The Docker images and containers, if any, may be removed after the C++ application has been run. Remove all Docker containers that have exited.
- sudo docker rm $(sudo docker ps --a --q)
All exited Docker container should get removed.
Remove the Docker image helloworld:v1 with the docker rmi command.
- docker rmi helloworld:v1
The Docker image gets removed.
Listing the Docker images may still list some images and some images could be called <none>.
- docker images
The <none> images are called dangling images. These are just some images that did not get downloaded properly or built properly.
Remove all the dangling images.
- sudo docker rmi $(sudo docker images --f
- "dangling=true" --q)
All the dangling images should get removed.
Listing the images lists only the gcc:4.9 Docker image, which could be kept for subsequent use.
In this tutorial, we introduced using C++ with Docker Engine.
联系客服