{"id":834,"date":"2021-04-20T13:47:26","date_gmt":"2021-04-20T11:47:26","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=834"},"modified":"2022-09-11T22:18:38","modified_gmt":"2022-09-11T20:18:38","slug":"docker-compose-introduction","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2021\/04\/20\/docker-compose-introduction\/","title":{"rendered":"Docker Compose ( Introduction)"},"content":{"rendered":"\n<p>Docker Compose is a tool that allows you to describe (in a YAML file) and manage (in command line) several containers as a set of interconnected services.<\/p>\n\n\n\n<p>Let\u00b4s assume we are working on a Rails application with 2 dependancies : PostgreSQL &amp; Redis.  we will for example create 3 containers:<\/p>\n\n\n\n<ul><li>a PostgreSQL container<\/li><li>a Redis container<\/li><li>a container for our application code<\/li><\/ul>\n\n\n\n<p>We will then be able to start our set of containers with a single <strong>docker-compose up<\/strong> command.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Without Docker Compose, we would have had to run 3 <strong>docker run<\/strong> commands with a lot of arguments to achieve the same result. In addition, it would have required that we write a rather precise README so that the other members of the team obtain the same result. <span class=\"has-inline-color has-vivid-cyan-blue-color\">With Docker Compose, this configuration is done in a file that is versioned with the rest of the application code.<\/span><\/p>\n\n\n\n<p>In the <span class=\"has-inline-color has-vivid-cyan-blue-color\">docker-compose.yml<\/span> file, each container is described with a set of parameters that correspond to the options available during a <strong>docker run<\/strong>: the image to use, the volumes to mount, the ports to open, etc.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Here is an example of a Docker Compose configuration file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: \"2\"\n\nservices:\n  db:\n    image: postgres\n  web:\n    build: .\n    command: python3 manage.py runserver 0.0.0.0:8000\n    volumes:\n      - .:\/code\n    ports:\n      - \"8000:8000\"\n    depends_on:\n      - db<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-red-color\">Installation<\/span><\/h4>\n\n\n\n<p>Docker Compose is not installed with Docker. It is therefore necessary to install it before you can use it.<\/p>\n\n\n\n<p>Here is its installation on Linux (Ubuntu)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt install docker-compose<\/code><\/pre>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-red-color\">Some useful commands<\/span><\/h4>\n\n\n\n<ul><li><strong>docker-compose up<\/strong> starts the services described in the docker-compose.yml and does not give the cursor (shell) back.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose up -d<\/strong> starts the services described in the docker-compose.yml  and returns (shell) control to us once the services are started.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose pull<\/strong>  refresh all  the services with the latest version . (Pulls an image associated with the service defined in &nbsp;<code>docker-compose.yml<\/code>).<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose up \u2013build<\/strong> rebuilds services before launching them.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose down<\/strong> stops the services.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose restart<\/strong> restarts all services.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose restart &lt;service&gt;<\/strong> restarts one specified services.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose exec &lt;service&gt; bash<\/strong>. Provides a bash console on one of the services. We can add the option -it for interactive purpose: ( <strong>docker-compose -it exec <strong>&lt;service&gt;<\/strong> bash<\/strong>)<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose logs<\/strong> returns all service logs since the last start and gives us the (shell)  control back.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose logs -f <\/strong> displays service logs and continues to &#8220;listen&#8221; to them without giving us (shell) controls back.<\/li><\/ul>\n\n\n\n<ul><li><strong>docker-compose logs -f &lt;service&gt;<\/strong>Display the logs on one of the services\/container only  and continue listening to them<\/li><\/ul>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Difference between docker-compose and Dockerfile<\/h4>\n\n\n\n<p>The key difference between the Dockerfile and docker-compose is that the Dockerfile describes how to\u00a0<em>build<\/em>\u00a0Docker images, while <code>docker-compose<\/code>\u00a0is used to describe how to\u00a0<em>run<\/em>\u00a0Docker images as  set of containers.<\/p>\n\n\n\n<p>For example, a<span class=\"has-inline-color has-vivid-cyan-blue-color\"> Dockerfile<\/span> that describes how to create a custom Nginx image that hosts your HTML files might look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM nginx:latest\r\nCOPY .\/hello-world.html \/usr\/share\/nginx\/html\/<\/code><\/pre>\n\n\n\n<p>When the image is assembled, this Dockerfile tells the\u00a0<code>docker build<\/code>\u00a0command to start with the latest Nginx image, and then to copy your\u00a0<em>hello-world.html<\/em>\u00a0file into the file serving folder of Nginx.<\/p>\n\n\n\n<h5>Dockerfile image building<\/h5>\n\n\n\n<p>To create a new, custom image based on this example Dockerfile, run the\u00a0<code>docker build<\/code>\u00a0command<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker build -t my-nginx-image:latest .<\/code><\/pre>\n\n\n\n<p>Note that the dot at the end tells the\u00a0<code>docker build<\/code>\u00a0command to look for the Dockerfile in the current directory. Leave this out and you\u2019ll get the \u201cdocker build requires exactly 1 argument\u201d error.<\/p>\n\n\n\n<p>After this command runs, a query of the Docker images installed on your local computer includes an image named\u00a0<em>my-nginx-image<\/em>\u00a0in the listing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker images\r\nREPOSITORY     TAG    IMAGE ID     CREATED     SIZE\r\nmy-nginx-image latest c58ef9bfbb57 7 days ago 144MB<\/code><\/pre>\n\n\n\n<p>a\u00a0<span class=\"has-inline-color has-vivid-cyan-blue-color\"><em>docker-compose.yaml<\/em>\u00a0<\/span>file that describes how to run the image created with the Dockerfile above might look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '3.9'\r\nservices:\r\n  my-nginx-service:\r\n    container_name: my-website\r\n    image: my-nginx-image:latest\r\n    cpus: 1.5\r\n    mem_limit: 2048m\r\n    ports:\r\n      - \"8080:80\"<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Docker Compose is a tool that allows you to describe (in a YAML file) and manage (in command line) several containers as a set of interconnected services. Let\u00b4s assume we are working on a Rails application with 2 dependancies : PostgreSQL &amp; Redis. we will for example create 3 containers: a PostgreSQL container a Redis [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1,208],"tags":[207,180],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/834"}],"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=834"}],"version-history":[{"count":7,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/834\/revisions"}],"predecessor-version":[{"id":2194,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/834\/revisions\/2194"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=834"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=834"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=834"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}