{"id":26168,"date":"2015-09-14T12:36:17","date_gmt":"2015-09-14T07:06:17","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=26168"},"modified":"2016-01-19T13:32:30","modified_gmt":"2016-01-19T08:02:30","slug":"docker-containers-and-aws-auto-scaling-hand-in-hand","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/docker-containers-and-aws-auto-scaling-hand-in-hand\/","title":{"rendered":"Docker containers and AWS Auto-scaling &#8211; Hand in Hand"},"content":{"rendered":"<p>In my <a href=\"http:\/\/www.tothenew.com\/blog\/setting-up-sendmail-inside-your-docker-container\/\">previous blog<\/a>, I talked about setting up sendmail inside a Docker container.\u00a0In this blog, we will talk about how to make your <a title=\"Docker DevOps\" href=\"http:\/\/www.tothenew.com\/devops-chef-puppet-docker\" target=\"_blank\">Docker<\/a> containers come up during Auto-scaling of AWS servers, start, and use a service like sendmail inside them. You can make changes to scripts based on your use-case. I just want to make the logic clear.<\/p>\n<h3><strong><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-26635 aligncenter\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/09\/cicd-with-docker-on-aws-1-638.jpg\" alt=\"cicd-with-docker-on-aws-1-638\" width=\"621\" height=\"399\" \/><\/strong><\/h3>\n<h3><\/h3>\n<p><strong><br \/>\nUse-case\u00a0<\/strong><\/p>\n<p>I had a PHP application running inside my Docker container (CentOS 7 based), being served by httpd (Apache2). This was single container running on a host machine. A use-case arose when I thought of what would happen when the traffic to my website increased or the CPU utilization went high etc. . I would have to scale my containers i.e. launch a new server and run a container inside that. Also, what I needed to do is keep the containers isolated &amp; check whether the container has come up in auto-scaling or not. So, that is what the blog is about.\u00a0So, I have made a script which you can add to user data in Launch Configuration.<\/p>\n<h3><strong>Prerequisites\u00a0<\/strong><\/h3>\n<p>What I will assume is that \u00a0you already have a Docker container running (CentOS 7 based), and it is serving some PHP application through httpd.<br \/>\nAlso, what more you need is :-<\/p>\n<ol>\n<li>An Auto-scaling group &amp; Launch Configuration in your AWS account.<\/li>\n<li>Your host machine&#8217;s AMI added to the Launch Configuration.<\/li>\n<li>Latest image of your running container committed to Docker Hub or you may locally commit the container image &amp; create an AMI from that and add to Launch Configuration group.<\/li>\n<li>Host machine may be Amazon Linux or CentOS\/RedHat. ( Even Ubuntu, but commands may slightly differ)<\/li>\n<li>sendmail service installed &amp; running on host machine. (This will be used to send an email when Docker container comes up)<\/li>\n<\/ol>\n<h3>How to implement it<\/h3>\n<p><strong>Explanation<\/strong> : Lets talk about the scripts. As we know every time a new container starts the entry in <strong>\/etc\/hosts<\/strong> changes to default with the new container ID. As sendmail requires a domain name to work, we will be using 2 scripts for sendmail about which we talked about in the previous blog, first being <strong>dockerscriptetchosts.sh<\/strong> and the other being<strong>\u00a0startsendmail.sh<\/strong>.\u00a0Let us go through them one by one before we come to our main script <strong>autodeploy.sh<\/strong><\/p>\n<p>So, the first script for sendmail is\u00a0<strong>dockerscriptetchosts.sh<\/strong><\/p>\n<pre>#!\/bin\/bash\r\n\r\nline=$(head -n 1 \/etc\/hosts) \r\nline2=$(echo $line | awk '{print $2}')\r\n\r\necho \"$line $line2.localdomain\" &gt;&gt; \/etc\/hosts<\/pre>\n<p>The above script has already been added to the image using ADD in Dockerfile. It makes the necessary entry to \/etc\/hosts of the Docker container which are as follows :-<\/p>\n<p><code>container_IP container_id container_id.localdomain<br \/>\n<\/code><\/p>\n<p>Next script is <strong>startsendmail.sh.<\/strong><\/p>\n<pre>#!\/bin\/bash\r\nsudo docker exec -itd $1 bash \/home\/dockerscriptetchosts.sh\r\nsudo docker exec -itd $1 \/etc\/init.d\/sendmail start\r\nsudo docker exec -itd $1 \/usr\/sbin\/httpd -k restart\r\n<\/pre>\n<p>This script is present on the host machine &amp; takes one parameter input (<strong>container_id<\/strong>) to execute which we will pass in the main script. It firstly runs <strong>docker exec<\/strong> command which in turn runs the command <strong>bash \/home\/dockerscriptetchosts.sh<\/strong>\u00a0inside the Docker container and in turn the next commands. The last command restarts httpd.<\/p>\n<p>The main script <strong>autodeploy.sh<\/strong> is below. Just go through it and I will explain the script just after that. You will need to put this bash script in the <strong>user-data<\/strong>.<\/p>\n<p>[js]#!\/bin\/bash<br \/>\nsudo docker pull ranvijayj\/prod:latest #this is if you want to pull from Docker Hub<\/p>\n<p>container_id=$(docker run -idt -p 80:80 &#8211;restart=&quot;always&quot; -v \/mnt\/code:\/opt\/code prod:latest)<\/p>\n<p>#check whether container is running or not<\/p>\n<p>sleep 5<\/p>\n<p>if [ `docker inspect -f {{.State.Running}} $container_id` == &quot;true&quot; ]; then<\/p>\n<p> echo &quot;Container has restarted .. Volume mounted&quot; | sendmail -s &quot; Container has come up in autoscaling&quot; ranvijay.jamwal@tothenew.com<br \/>\n sleep 20<br \/>\n http_status=$(curl -Is localhost:80 | head -n 1 | awk &#8216;{ print $2}&#8217;)<\/p>\n<p> if [ $http_status == 200 ]; then<\/p>\n<p> echo &quot;Container is SERVING the website&quot; | sendmail -s &quot; Container is serving the website&quot; ranvijay.jamwal@tothenew.com<\/p>\n<p> #once the container has started we need to start the sendmail service<br \/>\n #startsendmail can be present in any directory of AMI<br \/>\n bash \/home\/ec2-user\/startsendmail.sh<\/p>\n<p> else<br \/>\n echo &quot;Container has FAILED to serve the website.. http_status= $http_status&quot; | sendmail -s &quot; Container is NOT SERVING at port 80&quot; ranvijay.jamwal@tothenew.com<br \/>\n fi<\/p>\n<p>else<br \/>\n echo &quot;Container has not restarted\/started&quot; | sendmail -s &quot; Container has failed to come up in autoscaling &amp;amp; is NOT serving the website&quot; ranvijay.jamwal@tothenew.com<\/p>\n<p>fi [\/js]<\/p>\n<p>&nbsp;<\/p>\n<p>So, what the script is doing, is the following &amp; we will understand it line by line :-<\/p>\n<ol>\n<li>Using the Docker image we have defined it launches a container in detached mode<\/li>\n<li>It also exposes port 80 to the outside world, mounts directory<strong> \/mnt\/code<\/strong> from host machine to <strong>\/opt\/code<\/strong> using <strong>-v<\/strong> switch, \u00a0sets the variable &#8212;<strong>restart<\/strong> to &#8220;always&#8221; for the container &amp; the container ID is stored in the variable <strong>container_id.\u00a0<\/strong>Inside \/mnt\/code is your PHP code. The httpd service will start on its own as I already added a <strong>CMD<\/strong> via <strong>Dockerfile<\/strong> i.e.<br \/>\n<strong>ENTRYPOINT [&#8220;\/usr\/sbin\/httpd&#8221;]<\/strong><br \/>\n<strong> CMD [&#8220;-D&#8221;,&#8221;FOREGROUND&#8221;,&#8221;-k&#8221;,&#8221;start&#8221;]<\/strong><br \/>\nor you can use Nginx etc. You might have done this already<\/li>\n<li>Sleep for 5 seconds<\/li>\n<li>The first if statement checks if the container has started &amp; then sends an email to the specified email address according to the result. We are checking that using the command\u00a0<strong>docker inspect -f {{.State.Running}} $container_id` <\/strong>&amp; it should return a string &#8220;true&#8221;. Add a sleep of 20 seconds<\/li>\n<li>Next is checking if the container is serving the website on 80 port. For that we curl localhost:80. If it returns 200 then the website is working else it is not serving the website<\/li>\n<li>Now, since that is working, next is getting sendmail up &amp; running. For that execute the dockersendmail.sh script. This will work as we discussed above.<\/li>\n<\/ol>\n<p>Now, everything should be working fine &amp; your docker container will start when your servers auto-scale.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous blog, I talked about setting up sendmail inside a Docker container.\u00a0In this blog, we will talk about how to make your Docker containers come up during Auto-scaling of AWS servers, start, and use a service like sendmail inside them. You can make changes to scripts based on your use-case. I just want [&hellip;]<\/p>\n","protected":false},"author":174,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":9},"categories":[1174,2348],"tags":[248,1257,2366,1883,2335,2250,2249,2336],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/26168"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/174"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=26168"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/26168\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=26168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=26168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=26168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}