{"id":5587,"date":"2019-09-15T15:37:15","date_gmt":"2019-09-15T20:37:15","guid":{"rendered":"https:\/\/www.rushworth.us\/lisa\/?p=5587"},"modified":"2019-09-23T14:18:14","modified_gmt":"2019-09-23T19:18:14","slug":"building-a-docker-container-from-a-parent-image","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=5587","title":{"rendered":"Building a Docker Image From a Parent Image"},"content":{"rendered":"<p>Docker maintains a registry of pre-built images that may be all you need. <a href=\"https:\/\/www.rushworth.us\/lisa\/?p=5594\" target=\"_blank\" rel=\"noopener noreferrer\">Put some thought into it, though \u2013 don\u2019t just trust any image you find on the registry<\/a>. When a pre-built image doesn\u2019t meet your needs, you can make your own image based on any base image.<\/p>\n<p>I create a new folder to hold the build instructions, additional configuration files, and notes about the build process. In that folder, create a file named \u201cDockerfile\u201d which controls the image build.<\/p>\n<p>You\u2019ll need to specify the base image for your build using the FROM directive. I have examples here for installing sqlite3 on both a CentOS and Ubuntu base image. Add LABELs indicating the purpose of the image and who maintains it. Use the \u201cRUN\u201d directives to provide instructions to modify the base image to your needs \u2013 install what you want, create folders or files, clean up anything you don\u2019t want.<\/p>\n<p>The ENTRYPOINT is what runs when the container starts \u2013 it can be an executable, as in this case, or a script file.<\/p>\n<p>If you need to expose ports for inter-container communication, add a list of ports to expose. SQLite is self-contained, but a microservice environment may have \u201cEXPOSE 21443\u201d to allow other containers to communicate with it on port 21443. <em>Note<\/em> this is different than binding the container port to a host \u2013 my Apache web server container has 443 bound; but that\u2019s done in the \u201cdocker run\u201d line where the container is built, <em>not<\/em> in the Dockerfile for the image.<\/p>\n<p><strong><em>Example \u2013 SQLite3 on CentOS<\/em><\/strong><\/p>\n<pre>FROM centos:latest\r\n\r\nLABEL \"version\": \"latest\"\r\nLABEL \"description\": \"CentOS server running SQLite3\"\r\nLABEL \"maintainer\": \"DockerImages@lisa.rushworth.us\"\r\n\r\nRUN yum -y install glibc.i686\r\nRUN yum -y install zlib.i686\r\nRUN yum -y install wget\r\nRUN yum -y install unzip\r\n\r\nRUN cd \/root &amp;&amp; wget https:\/\/sqlite.org\/2019\/sqlite-tools-linux-x86-3290000.zip &amp;&amp; unzip -j -d \/usr\/bin -o \/root\/sqlite-tools-linux-x86-3290000.zip &amp;&amp; rm -f \/root\/sqlite-tools-linux-x86-3290000.zip\r\n\r\nRUN rm -rf \/var\/lib\/apt\/lists\/* \/tmp\/* \/var\/tmp\/*\r\n\r\nRUN mkdir -p \/db\r\n\r\nWORKDIR \/db\r\n\r\nENTRYPOINT [ \"sqlite3\" ]<\/pre>\n<p><strong><em>Example \u2013 SQLite3 on Ubuntu<\/em><\/strong><\/p>\n<pre>FROM ubuntu:latest\r\n\r\nLABEL \"version\": \"latest\"\r\nLABEL \"description\": \"Ubuntu server running SQLite3\"\r\nLABEL \"maintainer\": \"DockerImages@lisa.rushworth.us\"\r\n\r\nRUN DEBIAN_FRONTEND=noninteractive apt-get -yq update\r\n\r\nRUN DEBIAN_FRONTEND=noninteractive apt-get -yq install sqlite3\r\n\r\nRUN rm -rf \/var\/lib\/apt\/lists\/* \/tmp\/* \/var\/tmp\/*\r\n\r\nRUN mkdir -p \/db\r\n\r\nWORKDIR \/db\r\n\r\nENTRYPOINT [ \"sqlite3\" ]<\/pre>\n<p>Save your Dockerfile and build your container using \u201cdocker build -t image\/name .\u201d<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"980\" height=\"423\" class=\"wp-image-5588\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-16.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-16.png 980w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-16-300x129.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-16-768x331.png 768w\" sizes=\"auto, (max-width: 980px) 100vw, 980px\" \/><\/p>\n<p>Use \u201cdocker images\u201d to confirm the image has been successfully created.<\/p>\n<p><a href=\"https:\/\/www.rushworth.us\/lisa\/?attachment_id=5604\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5604 size-full\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/ReplacementImage-ListImages.png\" alt=\"\" width=\"878\" height=\"474\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/ReplacementImage-ListImages.png 878w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/ReplacementImage-ListImages-300x162.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/ReplacementImage-ListImages-768x415.png 768w\" sizes=\"auto, (max-width: 878px) 100vw, 878px\" \/><\/a><\/p>\n<p>And start a container using your image:<\/p>\n<pre>docker run -it --name ljrimagetest ljr\/sqllite3<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"978\" height=\"223\" class=\"wp-image-5590\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-18.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-18.png 978w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-18-300x68.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-18-768x175.png 768w\" sizes=\"auto, (max-width: 978px) 100vw, 978px\" \/><\/p>\n<p>If you are having problems starting your container, change the entrypoint to something like \u201c\/bin\/bash\u201d \u2013 this will drop you to the host\u2019s command line instead of the application. From there, you can troubleshoot your launch problems and sort the problem. The CentOS sqlite install, as an example, required glib and zlib components to run. Rather than trying something, rebuilding the image, launching a container, and looping until sqlite3 launched \u2026 I used bash as my entrypoint, installed packages until the application ran, and <em>then<\/em> modified the Dockerfile and rebuilt the image.<\/p>\n<p>At this point, you can tag the image and upload it to a registry. I use my GitLab server to store Docker images. There is a DockerImages repository<\/p>\n<p>To tag the image, use<\/p>\n<pre>docker tag ljr\/sqllite3 gitlab.rushworth.us:4567\/lisa\/dockerimages\/sqllite3:latest<\/pre>\n<p>And upload the image to your registry (you may need to authenticate first)<\/p>\n<pre>docker push gitlab.rushworth.us:4567\/lisa\/dockerimages\/sqllite3:latest<\/pre>\n<p>If you are using GitLab as your registry, navigate to the repository. Select Packages =&gt; Container Registry<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"221\" height=\"473\" class=\"wp-image-5591\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-19.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-19.png 221w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-19-140x300.png 140w\" sizes=\"auto, (max-width: 221px) 100vw, 221px\" \/><\/p>\n<p>Here\u2019s my Sqlite3 image<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1315\" height=\"287\" class=\"wp-image-5592\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-20.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-20.png 1315w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-20-300x65.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-20-768x168.png 768w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2019\/09\/word-image-20-1024x223.png 1024w\" sizes=\"auto, (max-width: 1315px) 100vw, 1315px\" \/><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Docker maintains a registry of pre-built images that may be all you need. Put some thought into it, though \u2013 don\u2019t just trust any image you find on the registry. When a pre-built image doesn\u2019t meet your needs, you can make your own image based on any base image. I create a new folder to &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[623],"tags":[231],"class_list":["post-5587","post","type-post","status-publish","format-standard","hentry","category-containerized-development-and-deployment","tag-docker"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/5587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5587"}],"version-history":[{"count":4,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/5587\/revisions"}],"predecessor-version":[{"id":5605,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/5587\/revisions\/5605"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}