{"id":20375,"date":"2018-08-14T09:10:45","date_gmt":"2018-08-14T16:10:45","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/?p=20375"},"modified":"2022-08-11T17:16:34","modified_gmt":"2022-08-11T17:16:34","slug":"c-development-with-docker-containers-in-visual-studio-code","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/c-development-with-docker-containers-in-visual-studio-code\/","title":{"rendered":"C++ development with Docker containers in Visual Studio Code"},"content":{"rendered":"<p><div class=\"alert alert-info\"><p class=\"alert-divider\"><i class=\"fabric-icon fabric-icon--Info\"><\/i><strong>Content outdated<\/strong><\/p> For up-to-date documentation see <a class=\"Hyperlink SCXW116474031 BCX8\" href=\"https:\/\/code.visualstudio.com\/docs\/remote\/containers\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW116474031 BCX8\" lang=\"EN-GB\" xml:lang=\"EN-GB\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW116474031 BCX8\" data-ccp-charstyle=\"Hyperlink\">Developing inside a Container using Visual Studio Code Remote Development<\/span><\/span><\/a>.<\/div>Containers allow developers to package up an application with all the parts it needs, such as libraries and other dependencies, and ship it all out as one image. This is especially useful for C++ cross-platform development \u2013 with containers you can choose to target a platform that runs on a completely different operating system than your developer machine. And even if they are running on the same OS, the container technology ensures that the application will run on any other machines regardless of any customized settings that machine might have that could differ from the machine used for writing and testing the code.<\/p>\n<p><a href=\"https:\/\/www.docker.com\/\">Docker<\/a> is a very popular container platform that makes it easy to create, deploy, and run applications by using containers, and whether you are a seasoned Docker developer or just getting started, Visual Studio Code has great support for working with Docker containers inside the editor.<\/p>\n<p>In this blog post, we are going to walk through how to create a Docker image for C++, start Docker containers, and build and run a C++ \u201cHelloWorld\u201d app in the container using Visual Studio Code.<\/p>\n<h2>Install tools<\/h2>\n<p>First, let\u2019s get the tools you would need in this walkthrough:<\/p>\n<ol>\n<li>Install Docker on your machine: <a href=\"https:\/\/docs.docker.com\/docker-for-mac\/install\/\">for Mac<\/a>, <a href=\"https:\/\/docs.docker.com\/docker-for-windows\/install\/\">for Windows<\/a>, or <a href=\"https:\/\/docs.docker.com\/install\/linux\/docker-ce\/ubuntu\/\">for Linux.<\/a><\/li>\n<li>Install Visual Studio Code: <a href=\"https:\/\/code.visualstudio.com\/\">https:\/\/code.visualstudio.com\/<\/a>.<\/li>\n<li>Docker support for VS Code is provided by an extension. To install the Docker extension, open the Extensions view in VS Code and search for docker to filter the results. Select the Microsoft <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=PeterJausovec.vscode-docker\">Docker<\/a> extension, click on Install, and reload VS Code when completed.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/1.png\"><img decoding=\"async\" class=\"alignnone wp-image-20485 size-full\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/1.png\" alt=\"\" width=\"857\" height=\"396\" \/><\/a><\/li>\n<\/ol>\n<h2>Get our C++ \u201cHelloWorld\u201d app ready<\/h2>\n<p>Let\u2019s first work on a C++ \u201cHelloWorld\u201d app, which we\u2019re going to build and run in a Docker container later in this walkthrough. First, create a new folder on your disk and open it in VS Code. Then add a new file named <strong>Test.cpp<\/strong> in the folder. Your VS Code window should look like this:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/2.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20495\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/2.png\" alt=\"\" width=\"321\" height=\"483\" \/><\/a><\/p>\n<p>Now let\u2019s put the following content into the <strong>Test.cpp<\/strong> file. Save the file and we are done here.<\/p>\n<pre>#include &lt;iostream&gt;\r\n\r\nint main(int argc, char const *argv[])\r\n{\r\n  std::cout &lt;&lt; \"Hello Docker container!\" &lt;&lt; std::endl;\r\n  return 0;\r\n}\r\n<\/pre>\n<h2>Build a Docker image for C++ development<\/h2>\n<p>With Docker, you can build images by specifying the step by step commands needed to build the image in a Dockerfile. A Dockerfile is just a text file that contains the build instructions.<\/p>\n<p><strong>1. Create a Dockerfile<\/strong>. The VS Code Docker extension provides a command for adding a Dockerfile to your workspace. With the folder that we created in the previous section opened in VS Code, in the Command Palette (F1), select command <strong>Docker: Add Docker files to Workspace\u00a0<\/strong>to generate\u00a0<strong>Dockerfile<\/strong>,\u00a0<strong>docker-compose.yml<\/strong>,\u00a0<strong>docker-compose.debug.yml<\/strong>, and\u00a0<strong>.dockerignore<\/strong>\u00a0files for your workspace type.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/3.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20505\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/3.png\" alt=\"\" width=\"879\" height=\"217\" \/><\/a><\/p>\n<p>You will be prompted with a list of platforms or languages you could target. In this walkthrough, let\u2019s choose <strong>Other<\/strong> from the list, which will give us a generic Dockerfile from which we can build our C++ specific image.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/41.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20515\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/41.png\" alt=\"\" width=\"687\" height=\"313\" \/><\/a><\/p>\n<p><strong>2. Add build instructions to the Dockerfile<\/strong>. Now we are going to edit the generated <strong>Dockerfile<\/strong> with instructions for how the Docker image should be built. The Docker extension enables a great experience for editing Dockerfile by providing auto-completion suggestions, snippets, QuickInfo, and linting for the Docker commands.<\/p>\n<p>In the following sections, we will describe how to build a C++ development environment with GCC and Clang as the compiler. Depending on which compiler you choose, you only need to follow one of the two sections (2.1 or 2.2).<\/p>\n<p><strong>2.1 Build a Docker image for a Clang environment<\/strong><\/p>\n<p>For building a C++ development environment with the Clang compiler, let\u2019s copy the following content into the <strong>Dockerfile<\/strong>, which installs Clang on top of a base Ubuntu image.<\/p>\n<pre># Get the base Ubuntu image from Docker Hub\r\nFROM ubuntu:latest\r\n\r\n# Update apps on the base image\r\nRUN apt-get -y update &amp;&amp; apt-get install -y\r\n\r\n# Install the Clang compiler\r\nRUN apt-get -y install clang\r\n\r\n# Copy the current folder which contains C++ source code to the Docker image under \/usr\/src\r\nCOPY . \/usr\/src\/dockertest1\r\n\r\n# Specify the working directory\r\nWORKDIR \/usr\/src\/dockertest1\r\n\r\n# Use Clang to compile the Test.cpp source file\r\nRUN clang++ -o Test Test.cpp\r\n\r\n# Run the output program from the previous step\r\nCMD [\".\/Test\"]\r\n<\/pre>\n<p><strong>2.1 Build a Docker image for a GCC environment<\/strong><\/p>\n<p>You can follow similar steps as above to build an image that installs GCC instead of Clang. Or, you could use a base image that has GCC pre-installed to simplify the steps. Let\u2019s copy the following into the <strong>Dockerfile<\/strong> to use an image pre-installed with GCC:<\/p>\n<pre># Get the GCC preinstalled image from Docker Hub\r\nFROM gcc:4.9\r\n\r\n# Copy the current folder which contains C++ source code to the Docker image under \/usr\/src\r\nCOPY . \/usr\/src\/dockertest1\r\n\r\n# Specify the working directory\r\nWORKDIR \/usr\/src\/dockertest1\r\n\r\n# Use GCC to compile the Test.cpp source file\r\nRUN g++ -o Test Test.cpp\r\n\r\n# Run the program output from the previous step\r\nCMD [\".\/Test\"]\r\n<\/pre>\n<p><strong>3. Build the Docker image<\/strong>. Now that we have the build instructions in the <strong>Dockerfile<\/strong>, we can go ahead build the Docker image. <strong>Docker: Build Image<\/strong> is one of the Docker commands the Docker extension provides in the Command Palette.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/5.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20525\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/5.png\" alt=\"\" width=\"879\" height=\"216\" \/><\/a><\/p>\n<p>Another way to invoke the Docker Build command is to right click on the <strong>Dockerfile<\/strong> itself in the VS Code Explorer window and select <strong>Build Image.<\/strong><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/6.png\"><img decoding=\"async\" class=\"alignnone wp-image-20535 size-mediumlarge\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/6-330x350.png\" alt=\"\" width=\"330\" height=\"350\" \/><\/a><\/p>\n<p>You will then get a prompt asking for the name and version to tag the image.<\/p>\n<p>While the build is in progress, you can see in the VS Code Terminal window how each step specified in the <strong>Dockerfile<\/strong> is being executed by Docker. See the following screenshot as an example.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/7.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20545\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/7-1024x512.png\" alt=\"\" width=\"879\" height=\"440\" \/><\/a><\/p>\n<p>Once completed, you can find the built image under the <strong>Images<\/strong> node in the <strong>Docker<\/strong> tab in VS Code. The following screenshot shows the image we just built appearing at the top of the image list.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/8.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20555\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/8.png\" alt=\"\" width=\"455\" height=\"428\" \/><\/a><\/p>\n<p>One thing to note is that our base image \u201cUbuntu:latest\u201d is also in the list. This means it could be reused as the base for other images to be built on top of, with only the image difference stored, which is a huge disk space saving compared with spinning up multiple full VMs.<\/p>\n<h2>Run Docker containers<\/h2>\n<p>Now that we have an image, let\u2019s try to run it. There\u2019re two ways to run an image using the Docker extension.\u00a0 <strong>Run<\/strong> will execute the image and run the default CMD you specified above. In this case we will <strong>Run Interactive<\/strong> which will execute the CMD but also give us an interactive terminal which we can use to see what is going on inside the running container.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/9.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20565\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/9.png\" alt=\"\" width=\"489\" height=\"419\" \/><\/a><\/p>\n<p>In the Docker:Explorer window, we see the container we just started is running:<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/101.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20575\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/101.png\" alt=\"\" width=\"563\" height=\"479\" \/><\/a><\/p>\n<p>In the Terminal window, we can see the default CMD we specified in the Dockerfile, which is to run our <strong>Test<\/strong> app (CMD [\u201c.\/Test\u201d]), has been executed by Docker and we got the output just as expected.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/11.png\"><img decoding=\"async\" class=\"alignnone size-large wp-image-20585\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/11.png\" alt=\"\" width=\"843\" height=\"210\" \/><\/a><\/p>\n<h2>Wrap-up<\/h2>\n<p>In this blog post, we walked through step by step for how to use the VS Code Docker extension to build Docker images, start Docker containers, and build and run C++ programs in the container. In a future post we\u2019ll cover how to attach to a process in the container and debug it.\u00a0If you have any suggestions for future topics regarding using C++ with containers, please let us know by leaving comments below.<\/p>\n<p>Also, if you are using containers or doing cloud development with C++ we would love to hear from you. If you could take a few minutes to take our <a href=\"https:\/\/www.surveymonkey.com\/r\/MLL8FDG\">C++ cloud and container development survey<\/a>, it will help us focus on topics that are important to you on the blog and in the form of product improvements.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Containers allow developers to package up an application with all the parts it needs, such as libraries and other dependencies, and ship it all out as one image. This is especially useful for C++ cross-platform development \u2013 with containers you can choose to target a platform that runs on a completely different operating system than [&hellip;]<\/p>\n","protected":false},"author":269,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[292,275],"tags":[293,276],"class_list":["post-20375","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-containers","category-visual-studio-code","tag-containers","tag-vscode"],"acf":[],"blog_post_summary":"<p>Containers allow developers to package up an application with all the parts it needs, such as libraries and other dependencies, and ship it all out as one image. This is especially useful for C++ cross-platform development \u2013 with containers you can choose to target a platform that runs on a completely different operating system than [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/20375","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/269"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=20375"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/20375\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=20375"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=20375"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=20375"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}