{"id":535,"date":"2017-11-28T13:01:51","date_gmt":"2017-11-28T21:01:51","guid":{"rendered":"http:\/\/andrewwippler.com\/?p=535"},"modified":"2017-11-28T13:01:51","modified_gmt":"2017-11-28T21:01:51","slug":"reusable-containers-with-confd","status":"publish","type":"post","link":"https:\/\/andrewwippler.com\/2017\/11\/28\/reusable-containers-with-confd\/","title":{"rendered":"Reusable containers with confd"},"content":{"rendered":"

I recently had the need to populate a file in a docker container based upon whether or not the container is in production or development.\u00a0I eventually came across confd<\/a>\u00a0which let me populate data in files based upon particular environment variables.\u00a0While confd excels with distributed key value stores, my needs (and infrastructure) is at a much simpler level.<\/p>\n

\"\"<\/a><\/p>\n

Confd requires a few folders to store a toml (\/etc\/confd\/conf.d\/) and a template file (\/etc\/confd\/templates\/). When confd runs, it will look at the contents of each toml file in the conf.d directory and process them according to their instructions.<\/p>\n

In my repository example<\/a>, I am wanting a container to say hello to me when it senses a NAME environment variable and print out the current datetime. If no environment variable is set, only the datetime is printed out. To do this, I must create the toml file to look like this<\/a>:<\/p>\n

[template]\nsrc = \"echo.tmpl\"\ndest = \"\/echo\"\n<\/code><\/pre>\n

This file is instructing confd to generate the echo file, place it in the root (\/) and use \/etc\/confd\/templates\/echo.tmpl<\/a> as the contents.<\/p>\n

When we are building the container, we must include these configuration files and ensure confd is ran to generate the destination file. My example Dockerfile<\/a> is doing just that by including all of the files in the container and running the docker-entrypoint script<\/a> which is basically running confd and the newly generated file.<\/p>\n

 andrew@wipplerxps > ~\/git_repos\/confd $  docker build -t blog-confd .\nSending build context to Docker daemon 57.34 kB\nStep 1\/9 : FROM centos:7.4.1708\n ---> 5076a7d1a386\nStep 2\/9 : LABEL maintainer \"andrew.wippler@gmail.com\"\n ---> Using cache\n ---> d712b31f7449\nStep 3\/9 : RUN mkdir -p \/etc\/confd\/{conf.d,templates}\n ---> Running in f340bdcdf973\n ---> 1f0faa9b962f\nRemoving intermediate container f340bdcdf973\nStep 4\/9 : COPY docker\/confd\/ \/etc\/confd\/\n ---> fb16dffc63ac\nRemoving intermediate container 133128cb7fc1\nStep 5\/9 : ADD https:\/\/github.com\/kelseyhightower\/confd\/releases\/download\/v0.14.0\/confd-0.14.0-linux-amd64 \/usr\/local\/bin\/confd\nDownloading 17.61 MB\/17.61 MB\n ---> a62b388274e6\nRemoving intermediate container 3f9ec343a5ab\nStep 6\/9 : RUN chmod +x \/usr\/local\/bin\/confd\n ---> Running in 1489dd02ea45\n ---> ab99a5fc5f95\nRemoving intermediate container 1489dd02ea45\nStep 7\/9 : COPY docker\/docker-entrypoint.sh \/var\/local\/\n ---> 16906971c8ef\nRemoving intermediate container 7a17a8e17e22\nStep 8\/9 : RUN chmod a+x \/var\/local\/docker-entrypoint.sh\n ---> Running in 1562a6d06432\n ---> f963372159b1\nRemoving intermediate container 1562a6d06432\nStep 9\/9 : ENTRYPOINT \/var\/local\/docker-entrypoint.sh\n ---> Running in 1b7e12c38b4c\n ---> f7d260597e0a\nRemoving intermediate container 1b7e12c38b4c\nSuccessfully built f7d260597e0a\n andrew@wipplerxps > ~\/git_repos\/confd $  docker run blog-confd\n2017-11-28T20:05:24Z 0931113b25f4 \/usr\/local\/bin\/confd[7]: INFO Backend set to env\n2017-11-28T20:05:24Z 0931113b25f4 \/usr\/local\/bin\/confd[7]: INFO Starting confd\n2017-11-28T20:05:24Z 0931113b25f4 \/usr\/local\/bin\/confd[7]: INFO Backend source(s) set to \n2017-11-28T20:05:24Z 0931113b25f4 \/usr\/local\/bin\/confd[7]: INFO Target config \/echo out of sync\n2017-11-28T20:05:24Z 0931113b25f4 \/usr\/local\/bin\/confd[7]: INFO Target config \/echo has been updated\nThe current time is: Tue Nov 28 20:05:24 UTC 2017\n andrew@wipplerxps > ~\/git_repos\/confd $  docker run -e NAME=\"Andrew Wippler\" blog-confd\n2017-11-28T20:05:52Z 223f28e8d18f \/usr\/local\/bin\/confd[7]: INFO Backend set to env\n2017-11-28T20:05:52Z 223f28e8d18f \/usr\/local\/bin\/confd[7]: INFO Starting confd\n2017-11-28T20:05:52Z 223f28e8d18f \/usr\/local\/bin\/confd[7]: INFO Backend source(s) set to \n2017-11-28T20:05:52Z 223f28e8d18f \/usr\/local\/bin\/confd[7]: INFO Target config \/echo out of sync\n2017-11-28T20:05:52Z 223f28e8d18f \/usr\/local\/bin\/confd[7]: INFO Target config \/echo has been updated\nHello Andrew Wippler\nThe current time is: Tue Nov 28 20:05:34 UTC 2017\n andrew@wipplerxps > ~\/git_repos\/confd $\n<\/code><\/pre>\n

While it is fun to say hello to yourself once in a while, I am using confd to modify an nginx.conf. When I pass in the SSL environment variable, nginx will listen on port 443 with a self signed cert and forward all HTTP traffic to HTTPS. Obviously in production, I want to use a real SSL cert. Using confd allows me to have the same docker container in development and production – the only difference being a configuration change.<\/p>\n","protected":false},"excerpt":{"rendered":"

I recently had the need to populate a file in a docker container based upon whether or not the container is in production or development.\u00a0I eventually came across confd\u00a0which let me populate data in files based upon particular environment variables.\u00a0While confd excels with distributed key value stores, my needs (and infrastructure) is at a much […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[6],"tags":[60,82,75,4],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts\/535"}],"collection":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/comments?post=535"}],"version-history":[{"count":2,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts\/535\/revisions"}],"predecessor-version":[{"id":539,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/posts\/535\/revisions\/539"}],"wp:attachment":[{"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/media?parent=535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/categories?post=535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andrewwippler.com\/wp-json\/wp\/v2\/tags?post=535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}