{"id":1876,"date":"2021-07-28T20:54:54","date_gmt":"2021-07-29T00:54:54","guid":{"rendered":"https:\/\/lowtek.ca\/roo\/?p=1876"},"modified":"2021-09-06T10:43:31","modified_gmt":"2021-09-06T14:43:31","slug":"managing-docker-containers-with-makefiles","status":"publish","type":"post","link":"https:\/\/lowtek.ca\/roo\/2021\/managing-docker-containers-with-makefiles\/","title":{"rendered":"Managing docker containers with makefiles"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1877\" src=\"https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2021\/07\/oldschool.png\" alt=\"\" width=\"1200\" height=\"470\" srcset=\"https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2021\/07\/oldschool.png 1200w, https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2021\/07\/oldschool-500x196.png 500w, https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2021\/07\/oldschool-1024x401.png 1024w, https:\/\/lowtek.ca\/roo\/wp-content\/uploads\/2021\/07\/oldschool-768x301.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\n<p style=\"text-align: right;\">\u00a0<span style=\"color: #808080;\"><em>Image\u00a0<a class=\"ext-link\" style=\"color: #808080;\" href=\"https:\/\/www.flickr.com\/photos\/54568729@N00\/9636183501\" rel=\"external \">by<\/a>\u00a0Jason Scott, licensed under\u00a0CC-BY-2.0.<\/em><\/span><\/p>\n<p>I&#8217;m very old school when it comes to managing my personal infrastructure. When I came across<a href=\"https:\/\/twitter.com\/jessfraz\"> Jessie Frazelle<\/a>&#8216;s blog on <a href=\"https:\/\/blog.jessfraz.com\/post\/personal-infrastructure\/\">her personal infrastructure<\/a> I was inspired to adopt a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Make_(software)\">makefile<\/a> based approach. There are a <a href=\"https:\/\/philpep.org\/blog\/a-makefile-for-your-dockerfiles\/\">couple<\/a> of <a href=\"https:\/\/opensource.com\/article\/21\/7\/manage-containers-makefile\">others<\/a> who&#8217;ve written about similar approaches.<\/p>\n<p>Here is a generic version of my makefile for containers which are built and hosted on one of the container repositories<\/p>\n<pre class=\"lang:default decode:true \">#\r\n# comment\r\n# https:\/\/hub.docker.com\/r\/project\/name\r\n#\r\nNAME = containername\r\nREPO = project\/name:latest\r\n#\r\nROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))\r\n\r\n# Create the container\r\nbuild:\r\n        docker create \\\r\n                --name=$(NAME) \\\r\n                -p 8000:3000 \\\r\n                -e VARIABLE=true \\\r\n                -v $(ROOT_DIR)\/config\/:\/path\/in\/container\/ \\\r\n                --restart=unless-stopped \\\r\n                $(REPO) \r\n\r\n# Start the container\r\nstart:\r\n        docker start $(NAME)\r\n\r\n# Update the container\r\nupdate:\r\n        docker pull $(REPO)\r\n        - docker rm $(NAME)-old\r\n        docker rename $(NAME) $(NAME)-old\r\n        make build\r\n        docker stop $(NAME)-old\r\n        make start\r\n<\/pre>\n<p>There are 3 targets: <code>build<\/code>, <code>start<\/code>, <code>update<\/code>. The update leaves the old container with a <code>-old<\/code> name. This is useful if you have to roll back to a previous version if for some reason the new container breaks. You could even create a <code>rollback<\/code> target that did this automatically.<\/p>\n<p>Now, this is great if there is an existing container repository that has a container for you to pull, but things need to change if you are starting with a Dockerfile and building your own container.<\/p>\n<pre class=\"lang:default decode:true \">#\r\n# comment\r\n# https:\/\/github.com\/project\/name\r\n#\r\nNAME = containername\r\n#\r\nROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))\r\n\r\n# Create the container\r\nbuild:\r\n        git pull\r\n        docker build . --tag $(NAME)\r\n        docker create \\\r\n                --name=$(NAME) \\\r\n                --restart=unless-stopped \\\r\n                $(NAME)\r\n\r\n# Start the container\r\nstart:\r\n        docker start $(NAME)\r\n\r\n# Update the container\r\nupdate:\r\n        - docker rm $(NAME)-old\r\n        docker rename $(NAME) $(NAME)-old\r\n        make build\r\n        docker stop $(NAME)-old\r\n        make start\r\n<\/pre>\n<p>Again, I&#8217;ve used the same <code>build<\/code>, <code>start<\/code>, <code>update<\/code> commands and have a built in assumption that the Makefile lives in the root of the git project. Instead of pulling from a container registry, we pull the latest from the git project and do a local build.<\/p>\n<p>Having a very similar structure helps with consistency of managing my docker containers.<\/p>\n<p>One day I would like to further enhance these makefiles to support checking for updates, be that a newer container build or git changes. Adding a post update check to ensure that the container has started would be very good too.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0Image\u00a0by\u00a0Jason Scott, licensed under\u00a0CC-BY-2.0. I&#8217;m very old school when it comes to managing my personal infrastructure. When I came across Jessie Frazelle&#8216;s blog on her personal infrastructure I was inspired to adopt a makefile based approach. There are a couple of others who&#8217;ve written about similar approaches. Here is a generic version of my makefile &hellip; <a href=\"https:\/\/lowtek.ca\/roo\/2021\/managing-docker-containers-with-makefiles\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Managing docker containers with makefiles&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-1876","post","type-post","status-publish","format-standard","hentry","category-computing"],"_links":{"self":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts\/1876","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/comments?post=1876"}],"version-history":[{"count":3,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts\/1876\/revisions"}],"predecessor-version":[{"id":1880,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/posts\/1876\/revisions\/1880"}],"wp:attachment":[{"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/media?parent=1876"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/categories?post=1876"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lowtek.ca\/roo\/wp-json\/wp\/v2\/tags?post=1876"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}