{"id":1247,"date":"2021-07-28T01:45:29","date_gmt":"2021-07-27T23:45:29","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=1247"},"modified":"2021-07-28T01:45:29","modified_gmt":"2021-07-27T23:45:29","slug":"docker-compose-part-ii","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2021\/07\/28\/docker-compose-part-ii\/","title":{"rendered":"Docker Compose (Part II)"},"content":{"rendered":"\n<p>Let\u00b4s say , we have a new site project with WordPress. To simplify infrastructure management, we want to deploy all the components in Docker containers. For this, we are going to create two containers:<\/p>\n\n\n\n<ul><li>a MySQL container;<\/li><li>a WordPress container.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" src=\"https:\/\/user.oc-static.com\/upload\/2019\/05\/10\/15574820463301_Capture%20d%E2%80%99e%CC%81cran%202019-05-10%20a%CC%80%2011.53.35.png\" alt=\"Structure de notre Docker Compose\" width=\"425\" height=\"298\"\/><\/figure>\n\n\n\n<p>First, we need to create a docker-compose.yml file at the root of our project. In it, we will describe all the resources and services necessary to achieve our goal.<\/p>\n\n\n\n<h4>Describe our first service: db<\/h4>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\">Set the version of Docker Compose<\/span><\/h5>\n\n\n\n<p>A docker-compose.yml file always begins with the following information:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-4.png\" alt=\"\" class=\"wp-image-1248\" width=\"810\" height=\"51\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-4.png 908w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-4-300x19.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-4-768x49.png 768w\" sizes=\"(max-width: 810px) 100vw, 810px\" \/><\/figure>\n\n\n\n<p>The version argument allows you to specify to Docker Compose which version you want to use. In our case, we will use version 3, which is currently the most used version. (<em>3.8 actually<\/em>)<\/p>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\">Declare the first service and its image<\/span><\/h5>\n\n\n\n<p>We are now going to declare our first service, and therefore create our WordPress stack!<\/p>\n\n\n\n<p>PS:<em> The set of containers that must be created must be defined under the <strong>services<\/strong> argument. Each container begins with a name ; in our case, our first container will be named <strong>db<\/strong>.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"906\" height=\"102\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-5.png\" alt=\"\" class=\"wp-image-1249\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-5.png 906w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-5-300x34.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-5-768x86.png 768w\" sizes=\"(max-width: 906px) 100vw, 906px\" \/><\/figure>\n\n\n\n<p>Then, you need to describe your container; in our case, we&#8217;re using the image argument which allows us to define the Docker image we want to use.<\/p>\n\n\n\n<p>PS:  Instead of <strong>&#8220;image&#8221;<\/strong> property ,<em>we could also have used the &#8220;<strong>build<\/strong>&#8221; argument by specifying the path to our Dockerfile; so, when running Docker Compose, it would have built the container through the Dockerfile before running it.<\/em><\/p>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\">Set the volume to persist our data<\/span><\/h5>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"920\" height=\"135\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-6.png\" alt=\"\" class=\"wp-image-1250\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-6.png 920w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-6-300x44.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-6-768x113.png 768w\" sizes=\"(max-width: 920px) 100vw, 920px\" \/><\/figure>\n\n\n\n<p>As a reminder, keep in mind that <strong>Docker containers are not made to run stateful services, <\/strong>and a database is by definition a stateful service. However, you can use the &#8220;<strong>volumes&#8221;<\/strong> argument which allows you to store the entire contents of the <em><strong>\/var\/lib\/mysql<\/strong><\/em> folder in a persistent disk. And therefore, to be able to keep the data locally on our host.<\/p>\n\n\n\n<p>PS: <em>This description is present thanks to the line <strong>db_data: \/var\/lib\/mysql<\/strong>.<\/em> <em> <span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>db_data<\/strong><\/span> is a volume created by Docker directly, which allows data to be written to the host disk without specifying the exact location. We could also have made a <strong>\/data\/mysql:\/var\/lib\/mysql <\/strong>which would also be functional.<\/em><\/p>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\">Set the container restart policy<\/span><\/h5>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"921\" height=\"163\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-7.png\" alt=\"\" class=\"wp-image-1251\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-7.png 921w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-7-300x53.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-7-768x136.png 768w\" sizes=\"(max-width: 921px) 100vw, 921px\" \/><\/figure>\n\n\n\n<p>PS: <em>The containers being by definition single-process, if this one encounters a fatal error, it can be brought to stop. In our case, if the MySQL server stops, it will restart automatically thanks to the<strong> restart: always<\/strong> argument.<\/em><\/p>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\">Set the environment variables<\/span><\/h5>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"933\" height=\"268\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-8.png\" alt=\"\" class=\"wp-image-1252\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-8.png 933w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-8-300x86.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-8-768x221.png 768w\" sizes=\"(max-width: 933px) 100vw, 933px\" \/><\/figure>\n\n\n\n<p>PS: <em>The supplied MySQL image has several environment variables that you can use; in our case, we will give the container the values ??of the different passwords and users that must exist on this database. When you want to give environment variables to a container, you need to use the <strong>environment<\/strong> argument, like we used in the docker-compose.yml file above.<\/em><\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Describe our second service: WordPress<\/h4>\n\n\n\n<p>In the second service, we create a container that will contain the necessary to make our site work with WordPress. This allows us to introduce two additional arguments.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-9.png\" alt=\"\" class=\"wp-image-1253\" width=\"737\" height=\"256\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-9.png 924w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-9-300x105.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-9-768x268.png 768w\" sizes=\"(max-width: 737px) 100vw, 737px\" \/><\/figure>\n\n\n\n<p>The first argument, &#8220;<strong>depends_on<\/strong>&#8220;, allows us to create a dependency between two containers. So Docker will start the <strong>db<\/strong> service before starting the <strong>WordPress<\/strong> service. Which is desirable behavior, because WordPress depends on the database to function properly.<\/p>\n\n\n\n<p>The second argument, &#8220;<strong>ports&#8221;<\/strong>, allows us to tell Docker Compose that we want to expose a port from our host machine to our container, and thus make it accessible from the outside.<\/p>\n\n\n\n<p><em><span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>Here is the docker-compose.yml file in its final version:<\/strong><\/span><\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-10.png\" alt=\"\" class=\"wp-image-1254\" width=\"697\" height=\"496\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-10.png 909w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-10-300x214.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-10-768x547.png 768w\" sizes=\"(max-width: 697px) 100vw, 697px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Launch your Docker Compose stack<\/h4>\n\n\n\n<p>When you run your containers with the<strong><em> docker-compose up -d<\/em><\/strong> command, you should have the following output:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-11.png\" alt=\"\" class=\"wp-image-1255\" width=\"684\" height=\"342\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-11.png 908w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-11-300x150.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-11-768x384.png 768w\" sizes=\"(max-width: 684px) 100vw, 684px\" \/><\/figure>\n\n\n\n<p>When executing this command, Docker Compose starts by checking whether we have the necessary images locally to launch the stacks. Otherwise, it downloads them from a registry, or builds them via a <strong><em>docker build<\/em><\/strong>.<\/p>\n\n\n\n<p>This then launches the two containers on your system; in our case, you will be able to see the result by opening the following URL in your browser:<strong><em> http:\/\/127.0.0.1:8000<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-12.png\" alt=\"\" class=\"wp-image-1256\" width=\"646\" height=\"403\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-12.png 914w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-12-300x187.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2021\/07\/image-12-768x480.png 768w\" sizes=\"(max-width: 646px) 100vw, 646px\" \/><\/figure>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-luminous-vivid-orange-color\"><strong>Summary<\/strong><\/span><\/h4>\n\n\n\n<p>Here are the arguments we have seen in this chapter:<\/p>\n\n\n\n<ul><li><strong><em>image<\/em> <\/strong>which allows to specify the source image for the container;<\/li><li><strong><em>build<\/em><\/strong> which allows you to specify the source <strong>Dockerfile<\/strong> to create the container image;<\/li><li><strong><em>volume<\/em><\/strong> that allows you to specify the mount points between the host system and the containers;<\/li><li><strong><em>restart<\/em><\/strong> which allows you to define the behavior of the container if case of the process  stopping;<\/li><li><strong><em>environment<\/em><\/strong> which allows you to define environment variables;<\/li><li><strong><em>depends_on<\/em><\/strong> which allows to say that the container depends on another container;<\/li><li><strong><em>ports<\/em><\/strong> which allows you to define the ports available between the host machine and the container.<\/li><\/ul>\n\n\n\n<h4><span class=\"has-inline-color has-luminous-vivid-orange-color\"><strong>Commands<\/strong><\/span><\/h4>\n\n\n\n<ul><li><strong><em>docker-compose ps<\/em><\/strong>  will allow you to see the status of your entire stack;<\/li><li><strong><em>docker-compose stop<\/em><\/strong>  will allow you to stop all the services of a stack.<\/li><li><strong><em>docker-compose down<\/em><\/strong>  will allow you to destroy all the resources of a stack;<\/li><li><strong><em>docker-compose config<\/em><\/strong>  will allow you to validate the syntax of your docker-compose.yml file.<\/li><li><strong><em>docker-compose logs -f &#8211;tail 5<\/em><\/strong>  will allow you to display the logs of your stack;<\/li><\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let\u00b4s say , we have a new site project with WordPress. To simplify infrastructure management, we want to deploy all the components in Docker containers. For this, we are going to create two containers: a MySQL container; a WordPress container. First, we need to create a docker-compose.yml file at the root of our project. In [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1257,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,221],"tags":[182,349,350,118],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1247"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1247"}],"version-history":[{"count":1,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1247\/revisions"}],"predecessor-version":[{"id":1258,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1247\/revisions\/1258"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1257"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}