{"id":321,"date":"2018-10-16T09:43:34","date_gmt":"2018-10-16T09:43:34","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw93\/?p=321"},"modified":"2018-10-17T07:36:08","modified_gmt":"2018-10-17T07:36:08","slug":"flexible-images-or-using-s2i-for-image-configuration","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/flexible-images-or-using-s2i-for-image-configuration\/","title":{"rendered":"Flexible Images or Using S2I for Image Configuration"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/developers.redhat.com\/blog\/wp-content\/uploads\/2014\/08\/shadowman-solo-from-external-web-265x200-e1491942587315.jpeg\" alt=\"\" width=\"175\" height=\"132\" \/><\/p>\n<p>Container images usually come with pre-defined tools or services with minimal or limited possibilities of further configuration. This brought us into a way of thinking of how to provide images that contain reasonable default settings but are, at the same time, easy to extend. And to make it more fun, this would be possible to achieve both on a single Linux host and in an orchestrated OpenShift environment.<\/p>\n<p>Source-to-image (S2I) has been introduced three years ago to allow developers to build containerized applications by simply providing source code as an input. So why couldn\u2019t we use it to make configuration files as an input instead? We can, of course!<\/p>\n<h2>Creating an Extensible Image<\/h2>\n<p>Creating S2I builder images was already described in an <a href=\"https:\/\/blog.openshift.com\/create-s2i-builder-image\/\">article<\/a> by Maciej Szulik and creating images that are extensible and flexible enough to be adjusted with custom configuration is not much different. So let\u2019s focus on the bits that are essential for making an image configurable.<\/p>\n<h3>Required Scripts<\/h3>\n<p>The two scripts that every builder image must provide are; assemble and <b>run, <\/b>both are included in the s2i\/bin\/ directory.<\/p>\n<h4>assemble<\/h4>\n<p>The assemble script defines how the application image is assembled.<\/p>\n<p>Let\u2019s look at the <a href=\"https:\/\/github.com\/sclorg\/nginx-container\">official Software Collections nginx<\/a> S2I builder image to see its default behavior. When you open the assemble script (snippet below), you see that by default the <i>nginx<\/i> builder image looks in the <i>nginx-cfg\/<\/i> and <i>nginx-default-cfg\/<\/i> directories within the provided source code where it expects to find your configuration files used for creating a customized application image.<\/p>\n<p>if [ -d .\/nginx-cfg ]; then<br \/>\necho &#8220;&#8212;&gt; Copying nginx configuration files&#8230;&#8221;<br \/>\nif [ &#8220;$(ls -A .\/nginx-cfg\/*.conf)&#8221; ]; then<br \/>\ncp -v .\/nginx-cfg\/*.conf &#8220;$&#8221;<br \/>\nrm -rf .\/nginx-cfg<br \/>\nfi<br \/>\nfi<\/p>\n<p>if [ -d .\/nginx-default-cfg ]; then<br \/>\necho &#8220;&#8212;&gt; Copying nginx default server configuration files&#8230;&#8221;<br \/>\nif [ &#8220;$(ls -A .\/nginx-default-cfg\/*.conf)&#8221; ]; then<br \/>\ncp -v .\/nginx-default-cfg\/*.conf &#8220;$&#8221;<br \/>\nrm -rf .\/nginx-default-cfg<br \/>\nfi<br \/>\nfi<\/p>\n<h4>run<\/h4>\n<p>The run script is responsible for running the application container. In the <a href=\"https:\/\/github.com\/sclorg\/nginx-container\/blob\/master\/1.12\/s2i\/bin\/run\">nginx<\/a> case, once the application container is run, the nginx server is started on the foreground.<\/p>\n<p>exec \/usr\/sbin\/nginx -g &#8220;daemon off;&#8221;<\/p>\n<h4>Labels<\/h4>\n<p>To tell s2i where it should expect the scripts, you need to define a label in the Dockerfile:<\/p>\n<p>LABEL io.openshift.s2i.scripts-url=&#8221;image:\/\/\/usr\/libexec\/s2i&#8221;<\/p>\n<p>Alternatively, you can also specify custom <i>assemble<\/i> and <i>run<\/i> scripts by collocating them with your source\/config files; the scripts baked in the builder image would then be overridden.<\/p>\n<h3>Optional Scripts<\/h3>\n<p>Since S2I provides quite a complex set of capabilities, you should always provide documentation on how users are expected to use your image. Test configuration (or application) might come in handy as well.<\/p>\n<h4>usage<\/h4>\n<p>This script outputs instructions on how to use the image when the container is run.<\/p>\n<h4>test\/run and test\/test-app<\/h4>\n<p>These scripts will test the application source code and run of the builder image.<\/p>\n<p>To make the creation of these images easier, you can take advantage of the <a href=\"https:\/\/github.com\/container-images\/s2i-container-image-template\">S2I container image template<\/a>.<\/p>\n<h2>Extending an Image with Custom Configuration<\/h2>\n<p>Now let\u2019s have a look at how you can use such an image in the real world.<\/p>\n<p>Again, we\u2019re going to take the above nginx image to demonstrate how to adjust it to build a containerized application with custom configuration.<\/p>\n<p>One of the advantages of using source-to-image for configuration is that it can be used on any standalone Linux platform as well as in an orchestrated OpenShift environment.<\/p>\n<p>On Red Hat Enterprise Linux, it is as easy as running the following command:<\/p>\n<p>$ s2i build https:\/\/github.com\/sclorg\/nginx-container.git &#8211;context-dir=1.12\/test\/test-app\/ registry.access.redhat.com\/rhscl\/nginx-112-rhel7 nginx-sample-app<\/p>\n<p>The s2i build command takes the configuration files in the <i>test\/test-app<\/i>\/ directory and injects them in the output <i>nginx-sample-app<\/i> image.<\/p>\n<p>Note that by default, s2i takes a repository as an input and looks for files in its root directory. In this case, the configuration files are in a subdirectory, hence specifying the \u2013context-dir.<\/p>\n<p>$ docker run &#8211;rm -p 8080:8080 nginx-sample-app<\/p>\n<p>Running the container will then show you a website informing you that your Nginx server is working.<\/p>\n<p>And similarly in OpenShift:<\/p>\n<p>$ oc new-app registry.access.redhat.com\/rhscl\/nginx-112-rhel7~https:\/\/github.com\/sclorg\/nginx-container.git &#8211;context-dir=1.12\/test\/test-app\/ &#8211;name nginx-test-app<\/p>\n<p>The <i>oc new-app<\/i> command creates and deploys a new image <i>nginx-test-app<\/i> modified with the configuration provided in the <i>test\/test-app\/<\/i> directory.<\/p>\n<p>After creating a route, you should see the same message as above.<\/p>\n<h2>Advantages of Using an S2I Builder Image for Extension<\/h2>\n<p>To sum it up, there are a number of reasons to leverage S2I for your project.<\/p>\n<ul>\n<li><b>Flexibility<\/b> \u2013 You can customize a service to fit your needs by providing a configuration file that rewrites the values used in a container by default. And it doesn\u2019t end there: do you want to install an additional plugin that is not included in your database image by default or install and run arbitrary commands? S2I-enabled images allow for this.<\/li>\n<li><b>Any platform<\/b> \u2013 You can use S2I for building standalone containers on several Linux platforms that provide the s2i RPM package, including Red Hat Enterprise Linux, CentOS, and Fedora or take advantage of the s2i binary. The S2I build strategy is one of the integrated build strategies in OpenShift, so you can easily leverage it for building containers deployed in an orchestrated environment as well.<\/li>\n<li><b>Separated images and service configuration <\/b>\u2013 Although having a clear distinction between images and service configuration allows you to perform adjustments that are more complex, the build reproducibility remains preserved at the same time.<\/li>\n<\/ul>\n<h2>Pull and Run a Flexible Image Now<\/h2>\n<p>The following images are now available as S2I builders from the <a href=\"https:\/\/access.redhat.com\/containers\">Red Hat Container Catalog<\/a> and can be easily extended as demonstrated above:<\/p>\n<ul>\n<li><a href=\"https:\/\/access.redhat.com\/containers?tab=tech-details#\/registry.access.redhat.com\/rhscl-beta\/mongodb-34-rhel7\">MongoDB<\/a><\/li>\n<li><a href=\"https:\/\/access.redhat.com\/containers\/?tab=overview#\/registry.access.redhat.com\/rhscl\/mariadb-102-rhel7\">MariaDB<\/a><\/li>\n<li><a href=\"https:\/\/access.redhat.com\/containers\/?tab=overview#\/registry.access.redhat.com\/rhscl\/nginx-112-rhel7\">Nginx<\/a><\/li>\n<li><a href=\"https:\/\/access.redhat.com\/containers\/?tab=overview#\/registry.access.redhat.com\/rhscl\/varnish-4-rhel7\">Varnish<\/a><\/li>\n<\/ul>\n<p>More images will appear in the Catalog soon. In the meantime, you can try out their <a href=\"https:\/\/github.com\/sclorg\">upstream counterparts<\/a>.<\/p>\n<p>The source-to-image project contains extensive documentation with examples, so head over to the <a href=\"https:\/\/github.com\/openshift\/source-to-image\">project\u2019s GitHub page<\/a> if you\u2019d like to learn more.<\/p>\n<h2>Resources<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/openshift\/source-to-image\">https:\/\/github.com\/openshift\/source-to-image<\/a><\/li>\n<li><a href=\"http:\/\/docs.projectatomic.io\/container-best-practices\/#_builder_images\">http:\/\/docs.projectatomic.io\/container-best-practices\/#_builder_images<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/container-images\/s2i-container-image-template\">https:\/\/github.com\/container-images\/s2i-container-image-template<\/a><\/li>\n<li><a href=\"https:\/\/blog.openshift.com\/override-s2i-builder-scripts\/\">https:\/\/blog.openshift.com\/override-s2i-builder-scripts\/<\/a><\/li>\n<li><a href=\"https:\/\/blog.openshift.com\/create-s2i-builder-image\/\">https:\/\/blog.openshift.com\/create-s2i-builder-image\/<\/a><\/li>\n<\/ul>\n<p><a href=\"https:\/\/developers.redhat.com\/?intcmp=70160000000xZNgAAM\"><b>Join the Red Hat Developer Program<\/b><\/a><b> (it\u2019s free) and get access to related cheat sheets, books, and product downloads.<\/b><\/p>\n<p>Take advantage of your Red Hat Developers membership and download RHEL today at no cost.<\/p>\n<p><a href=\"https:\/\/developers.redhat.com\/blog\/2017\/11\/29\/flexible-images-using-s2i-image-configuration\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Container images usually come with pre-defined tools or services with minimal or limited possibilities of further configuration. This brought us into a way of thinking of how to provide images that contain reasonable default settings but are, at the same time, easy to extend. And to make it more fun, this would be possible to &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/flexible-images-or-using-s2i-for-image-configuration\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Flexible Images or Using S2I for Image Configuration&#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":[2],"tags":[],"class_list":["post-321","post","type-post","status-publish","format-standard","hentry","category-docker"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/321","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=321"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/321\/revisions"}],"predecessor-version":[{"id":464,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/321\/revisions\/464"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}