{"id":109,"date":"2022-08-04T19:11:22","date_gmt":"2022-08-04T17:11:22","guid":{"rendered":"https:\/\/www.mutareb.com\/?p=109"},"modified":"2022-12-05T20:19:18","modified_gmt":"2022-12-05T18:19:18","slug":"intro-to-docker-and-docker-compose","status":"publish","type":"post","link":"https:\/\/www.mutareb.com\/index.php\/2022\/08\/04\/intro-to-docker-and-docker-compose\/","title":{"rendered":"Intro to Docker and Docker compose"},"content":{"rendered":"\n<p>we will use docker containers to manage the different services. Here is an example of a http server container and an api server container, that we will use as an example for two containers built to communicate with each other, open a port to the host and automate the start up including the build and shutdown processes.<\/p>\n\n\n\n<p>what is docker anyway? Here is a list of basic commands to get started<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker pull ubuntu\ndocker container ls -a\ndocker ps\ndocker ps -aq\ndocker rm container\ndocker rmi image\ndocker images\ndocker create --name nameit nginx\ndocker attach nameit\ndocker start nameit\ndocker run -it --name nameit nginx\ndocker run -d -p 8080:80 --name nameit2 -v nginx\ndocker exec -it nameit2 bash<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>For setting up our docker server container, using a http_server.Docker file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># this container is based on ubuntu:18.04 image\nFROM ubuntu:20.04\n# run some commands as root to install needed packages               \nRUN apt-get update -y\nRUN apt-get install -y nano\nRUN apt-get install -y python3.8\nRUN apt-get install -y sudo\n# create user with temp pw, add him to group and delete tmp pw\nRUN useradd p_server_user -p 'temporary' -u 1001 -m\nRUN passwd -d p_server_user\nRUN usermod -aG sudo p_server_user\n# from here on we run commands as the user\nUSER p_server_user\n# set some env variables\nWORKDIR \/home\/p_server_user\/src\nENV PORT=8888\n# expose port to host\nEXPOSE 8888\n<\/code><\/pre>\n\n\n\n<p>now to automate the process of building and starting the server container with a shell script<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\ndocker build \\\n--file=http_server.Dockerfile \\\n--tag=\"http_server:0.1\" \\\n.\n\ndocker create \\\n--interactive \\\n--tty \\\n--rm \\\n--name=http_server\\\n--publish-all \\\n--mount type=bind,source=\"$(pwd)\/src\",target=\/home\/p_server_user\/src \\\n--workdir \/home\/p_server_user\/src \\\nserver_container:0.1\n\ndocker start http_server\ndocker port http_server\ndocker attach http_server<\/code><\/pre>\n\n\n\n<p>don&#8217;t forget to make it executable<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chmod +x server_builder.sh\n.\/server_builder.sh<\/code><\/pre>\n\n\n\n<p>Now we will make the same for the node.js api server that the http container will communicate with, this is the api_server.Dockerfile:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># this container is based on node:12.18-slim image\nFROM node:12.18-slim\n# run some commands as root to install needed packages\nRUN apt-get update -y\nRUN apt-get install -y nano\nRUN apt-get install -y sudo\n# add default container user to group and delete default pw\nRUN passwd -d node\nRUN usermod -aG sudo -u 1001 node\n# from here on we run commands as the user\nUSER node\n# set some env variables\nWORKDIR \/home\/node\/src\n# node container launches into nodejs env, we want it to start into shell, this forward this comman\nCMD &#91;\"\/bin\/bash\"]\nENV PORT=12345\n# expose port to host\nEXPOSE 12345\n<\/code><\/pre>\n\n\n\n<p>then the deployment shell script<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\ndocker build \\\n--file=api_server.Dockerfile \\\n--tag=\"api_server:0.1\" \\\n.\n\ndocker create \\\n--interactive \\\n--tty \\\n--rm \\\n--name=api_server \\\n--publish-all \\\n--mount type=bind,source=\"$(pwd)\/src\",target=\/home\/node\/src \\\n--workdir \/home\/node\/src \\\napi_server:0.1\n\ndocker start api_server\ndocker port api_server\ndocker attach api_server\n<\/code><\/pre>\n\n\n\n<p>We will create a simple express.js function on the api server as a backend for the http server. For that we will need to install express, and initiate npm with our service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm init # give it a name like api_server\nnpm install express<\/code><\/pre>\n\n\n\n<p>then let&#8217;s create our service, e.g. api_server.js:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/local\/bin\/node\n\nvar express = require('express');\nvar app = express();\n\napp.listen(process.env.PORT);\n\napp.get(\n '\/person',\n function (req, res) {\n  res.json({\n   name: 'Tom',\n   surname: 'Jerry'\n  })\n }\n);<\/code><\/pre>\n\n\n\n<p>Now we can let docker compose take care of handling the set up of these containers and especially the communication between them. For that we will create our composer config file docker-compose.yml<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '3'\n\nservices:\n        api:\n                image: api_server:0.1\n                container_name: api_server\n                build:\n                        context: .\/api_server\n                        dockerfile: api_server.Dockerfile\n                command: \/home\/node\/src\/api_server.js\n                volumes:\n                        - .\/api_server\/src:\/home\/node\/src\n                              \n\n        web:\n                image: http_server:0.1\n                container_name: http_server\n                build:\n                        context: .\/http_server\n                        dockerfile: http_server.Dockerfile\n                command: \/home\/http_server_user\/src\/http_server.py\n                volumes:\n                        - .\/http_server\/src:\/home\/http_server_user\/src\n                ports:\n                        - 8080:8888\n                environment:\n                        - API_SERVER_URL=http:\/\/api:12345\n<\/code><\/pre>\n\n\n\n<p>once we run docker-compose, we will have the http server available on localhost:8080, the api server will not be reachable from outside the container, except for http server. Now let&#8217;s create the start.sh scripts:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n\ndocker-compose up -d --build\ndocker port http_server<\/code><\/pre>\n\n\n\n<p>and respectively the stop.sh script, don&#8217;t forget to make them executable!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\ndocker-compose down<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>we will use docker containers to manage the different services. Here is an example of a http server container and an api server container, that we will use as an example for two containers built to communicate with each other, open a port to the host and automate the start up including the build and&hellip; <a class=\"more-link\" href=\"https:\/\/www.mutareb.com\/index.php\/2022\/08\/04\/intro-to-docker-and-docker-compose\/\">Continue reading <span class=\"screen-reader-text\">Intro to Docker and Docker compose<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[28],"series":[],"class_list":["post-109","post","type-post","status-publish","format-standard","hentry","category-automation","tag-docker","entry"],"_links":{"self":[{"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/posts\/109","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/comments?post=109"}],"version-history":[{"count":7,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/posts\/109\/revisions"}],"predecessor-version":[{"id":116,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/posts\/109\/revisions\/116"}],"wp:attachment":[{"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/media?parent=109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/categories?post=109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/tags?post=109"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mutareb.com\/index.php\/wp-json\/wp\/v2\/series?post=109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}