{"id":36063,"date":"2019-03-21T00:59:21","date_gmt":"2019-03-21T07:59:21","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/premier-developer\/?p=36063"},"modified":"2019-03-19T14:00:28","modified_gmt":"2019-03-19T21:00:28","slug":"mixing-windows-and-linux-containers-with-docker-compose","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/mixing-windows-and-linux-containers-with-docker-compose\/","title":{"rendered":"Mixing Windows and Linux containers with Docker Compose"},"content":{"rendered":"<p><span class=\"x-hidden-focus\">Premier Developer Consultant <\/span><a href=\"https:\/\/www.linkedin.com\/in\/randyrpatterson\/\" target=\"_blank\" rel=\"noopener\">Randy Patterson<\/a> explores how to mix Windows and Linux containers with Docker Compose.<\/p>\n<hr \/>\n<p>Running Linux containers on a Windows host has been <a href=\"https:\/\/devblogs.microsoft.com\/premier-developer\/running-docker-windows-and-linux-containers-simultaneously\/\">available<\/a> for awhile now. However, getting Windows and Linux containers to communicate without Docker Compose results in using the containers\u2019 IP Addresses. This is not a good solution since container IP Addresses change often. A better solution is to take advantage of the Docker Compose <a href=\"https:\/\/docs.docker.com\/compose\/networking\/\">networking<\/a> and use the service name instead of the IP address. A Windows host has no problem running Linux containers but Docker Compose does not automatically support multi-platform hosts.<\/p>\n<p>The <a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/compose-file-v2\/#platform\"><em>platform<\/em><\/a> configuration option was added to Docker Compose files starting with version 2.4 and then removed beginning with version 3.x. It is a <a href=\"https:\/\/github.com\/docker\/compose\/pull\/5985\">know bug<\/a> and the expectation is that the <em>platform<\/em> option will return soon. When this article was written, it has not yet appeared in version 3.x so we will continue to use file format version 2.4 for our Docker Compose yaml files.<\/p>\n<h2>Setting up your environment<\/h2>\n<p>Running Linux containers on Windows and platform support in Docker Compose requires Windows 1803 or greater. I am running Windows 10 1809.<\/p>\n<p><img decoding=\"async\" width=\"460\" height=\"423\" class=\"wp-image-36064\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-17.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-17.png 460w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-17-300x276.png 300w\" sizes=\"(max-width: 460px) 100vw, 460px\" \/><\/p>\n<p>In addition, you must be running the latest version of Docker for Windows and have the experimental features enabled.<\/p>\n<p><img decoding=\"async\" width=\"1294\" height=\"488\" class=\"wp-image-36065\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9efec91.png\" alt=\"C:\\Users\\ranpat\\AppData\\Local\\Temp\\SNAGHTML9efec91.PNG\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9efec91.png 1294w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9efec91-300x113.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9efec91-768x290.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9efec91-1024x386.png 1024w\" sizes=\"(max-width: 1294px) 100vw, 1294px\" \/><\/p>\n<p>If you are running different versions of Windows or Docker your mileage may vary.<\/p>\n<h3>Source Code<\/h3>\n<p>Next, grab the source code located in the GitHub repo <a href=\"https:\/\/github.com\/RandyPatterson\/DockerComposeMultiPlatform\">here<\/a> containing two solutions<\/p>\n<ol>\n<li><em>Webtier.sln<\/em> \u2013 Asp.Net MVC application running .NET Framework 4.6.x and a Dockerfile for creating a Windows image hosting IIS.<\/li>\n<li><em>ApiTier.sln<\/em> \u2013 Asp.Net Core 2.1 application and a Dockerfile for creating a Linux image to host the application<\/li>\n<\/ol>\n<p>The application is a simple web page that displays the hostname of the Web Tier then calls the API Tier to get and display the API hostname. When running in containers, the container Id is displayed. Your Id\u2019s will be different<\/p>\n<p><img decoding=\"async\" width=\"782\" height=\"364\" class=\"wp-image-36066\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-18.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-18.png 782w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-18-300x140.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-18-768x357.png 768w\" sizes=\"(max-width: 782px) 100vw, 782px\" \/><\/p>\n<h2>Docker-Compose<\/h2>\n<p>The docker-compose.yml file, located in the root of the <a href=\"https:\/\/github.com\/RandyPatterson\/DockerComposeMultiPlatform\">solution<\/a>, adds the <strong><em>platform: windows<\/em><\/strong> parameter to the <em>webtier<\/em> service and the <strong><em>platform: linux<\/em><\/strong> parameter to the apitier service.<\/p>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">version: '2.4'\r\nservices:\r\n  webtier:\r\n    image: webtier:win\r\n    platform: windows\r\n    ports:\r\n      - 80\r\n    build:\r\n      context: .\\WebTier\r\n      dockerfile: Dockerfile\r\n    depends_on:\r\n      - apitier\r\n    environment:\r\n      ApiHost: \"apitier\"\r\n\r\n  apitier:\r\n    image: apitier:linux\r\n    platform: linux\r\n    expose: \r\n      - 80\r\n    build:\r\n      context: .\\ApiTier\r\n      dockerfile: Dockerfile \r\n<\/pre>\n<p>Next, bring up the multi-container, multi-platform application using docker-compose. Start a powershell prompt in the solutions root folder, the same folder that contains the <em>docker-compose.yml<\/em> file. Type the command:<\/p>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">docker-compose up -d<\/pre>\n<p>Docker Compose will create the images if they do not already exist, then create the virtual network to host the containers and finally start the containers in the correct order.<\/p>\n<p><img decoding=\"async\" width=\"1900\" height=\"951\" class=\"wp-image-36067\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9a0e9f1.png\" alt=\"C:\\Users\\ranpat\\AppData\\Local\\Temp\\SNAGHTML9a0e9f1.PNG\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9a0e9f1.png 1900w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9a0e9f1-300x150.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9a0e9f1-768x384.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/c-users-ranpat-appdata-local-temp-snaghtml9a0e9f1-1024x513.png 1024w\" sizes=\"(max-width: 1900px) 100vw, 1900px\" \/><\/p>\n<p>Finally, retrieve the host port of the <em>webtier<\/em> container<\/p>\n<pre class=\"nums:false nums-toggle:false lang:default decode:true\">docker-compose ps<\/pre>\n<p><img decoding=\"async\" width=\"1291\" height=\"190\" class=\"wp-image-36068\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-19.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-19.png 1291w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-19-300x44.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-19-768x113.png 768w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-19-1024x151.png 1024w\" sizes=\"(max-width: 1291px) 100vw, 1291px\" \/><\/p>\n<p>Use your browser to navigate to <a href=\"http:\/\/localhost:38736\">http:\/\/localhost:38736<\/a> (your port number will be different)<\/p>\n<p><img decoding=\"async\" width=\"554\" height=\"344\" class=\"wp-image-36069\" src=\"http:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-20.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-20.png 554w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2019\/03\/word-image-20-300x186.png 300w\" sizes=\"(max-width: 554px) 100vw, 554px\" \/><\/p>\n<p>If the Windows Web Tier was able to communicate with the Linux API Tier, you will see the id for each of the containers (your id\u2019s will be different) on the web page.<\/p>\n<p>Using the <a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/compose-file-v2\/#platform\">platform<\/a> option in your configuration files allows Docker Compose to mix Windows and Linux containers when hosted on a multi-platform host like Windows. Keep in mind that this is an experimental feature and is not yet ready for production environments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Running Linux containers on a Windows host has been available for awhile now. However, getting Windows and Linux containers to communicate without Docker Compose results in using the containers\u2019 IP Addresses. This is not a good solution since container IP Addresses change often.<\/p>\n","protected":false},"author":582,"featured_media":36070,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[25],"tags":[2,29,27,314],"class_list":["post-36063","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","tag-containers","tag-docker","tag-linux","tag-randy-patterson"],"acf":[],"blog_post_summary":"<p>Running Linux containers on a Windows host has been available for awhile now. However, getting Windows and Linux containers to communicate without Docker Compose results in using the containers\u2019 IP Addresses. This is not a good solution since container IP Addresses change often.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/36063","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/582"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=36063"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/36063\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/36070"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=36063"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=36063"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=36063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}