{"id":22,"date":"2019-05-05T17:42:13","date_gmt":"2019-05-05T17:42:13","guid":{"rendered":"http:\/\/blog.nikster.de\/wordpress\/?p=22"},"modified":"2019-05-06T22:18:30","modified_gmt":"2019-05-06T22:18:30","slug":"how-to-build-a-webservice-with-docker","status":"publish","type":"post","link":"https:\/\/blog.nikster.de\/wordpress\/index.php\/2019\/05\/05\/how-to-build-a-webservice-with-docker\/","title":{"rendered":"How to build a webservice with docker"},"content":{"rendered":"\n<p>To start building a new Service, you&#8217;ll need an image first.<br>Our Service will be an apache Server which delivers an application.<\/p>\n\n\n\n<p>So get an image from dockerhub or build your own (as described in my <a href=\"https:\/\/blog.nikster.de\/wordpress\/index.php\/2019\/05\/04\/how-to-build-your-own-docker-image\/\">last post).<\/a><br><br>We&#8217;ll start by creating a working directory for our files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir docker_perl_hello_world \ncd docker_perl_hello_world<\/code><\/pre>\n\n\n\n<p>Let&#8217;s add a simple Perlscript, that prints &#8220;Hello World!&#8221; (I had this lying around already, but use whatever language you prefer).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vi mywebsite\/index.pl\n\n#!\/usr\/bin\/perl print \"Content-type: text\/html\\n\\n\"; \nprint &lt;&lt;HTML; \n&lt;html> \n &lt;head> \n  &lt;title>Simple Perl Script&lt;\/title> \n &lt;\/head> \n  &lt;body> \n   &lt;h1>Perl says:&lt;\/h1> \n   &lt;p>Hello World!&lt;\/p> \n  &lt;\/body> \nHTML \nexit;<\/code><\/pre>\n\n\n\n<p>don&#8217;t forget to make this executable<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod +x mywebsite\/index.p<\/code><\/pre>\n\n\n\n<p>Now, let&#8217;s create a simple vhost config for apache, so that it knows what to do with our script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vi 001-perlcgi.conf\n\n&lt;VirtualHost *:80>\n      ServerName localhost      \n      DocumentRoot \/var\/www\/html\/        \n        &lt;Directory \"\/var\/www\/html\/perl\">\n                  AllowOverride None\n                  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch\n                  Order allow,deny\n                  Allow from all\n                  AddHandler cgi-script .pl\n        &lt;\/Directory>\n      ErrorLog \/var\/log\/apache2\/perlcgi-error.log\n      CustomLog \/var\/log\/apache2\/perlcgi-access.log combined\n &lt;\/VirtualHost>\n<\/code><\/pre>\n\n\n\n<p>this is the heart of  our build and requires some explanation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vi Dockerfile\n\n# Dockerfile for Apache Server \nFROM stretchbase:latest \nLABEL maintainer \"nkalle@nikster.de\" \nLabel description \"Apache Webserver with perl cgi\" \n\n# install Apache and remove unneeded data \nRUN apt-get update &amp;&amp; apt-get install -y apache2 libapache2-mod-perl2 &amp;&amp; apt-get -y clean &amp;&amp; rm -rf \/var\/cache\/apt \/var\/lib\/apt\/lists\/* \n\n# copy the vhost definition for our service \nCOPY 001-perlcgi.conf \/etc\/apache2\/sites-available\/ \n\n# enable the default and the perl-script page \nRUN a2ensite 001-perlcgi \nRUN a2enmod cgi \nEXPOSE 80 \n\n#copy the script to its destination \nRUN mkdir \/var\/www\/html\/perl \nCOPY mywebsite\/ \/var\/www\/html\/perl \nCMD [\"\/usr\/sbin\/apache2ctl\", \"-D\", \"FOREGROUND\"]<\/code><\/pre>\n\n\n\n<p>We have created the Dockerfile, this contains all the information the Docker daemon needs to assemble our new container, and within it, our service.<\/p>\n\n\n\n<p>&#8220;FROM&#8221;  tells docker which baseimage it should use (in this case the image that we built in the <a href=\"https:\/\/blog.nikster.de\/wordpress\/index.php\/2019\/05\/04\/how-to-build-your-own-docker-image\/\">last post<\/a>).<br>&#8220;LABEL&#8221; adds additional info.<br>The &#8220;RUN&#8221; Keyword allows us to run all kinds of commands inside the conatiner, thus configuring it.<br>Here, I&#8217;m updating the apt repo information, so that the latest version of apache and libapache-mod-perl2 can be installed.<br>Afterwards I&#8217;m cleaning up, to keep the Image as small as possible.<br>Now we&#8217;ll &#8220;COPY&#8221; our vhost.conf to the right place. And then enable it and the cgi Module with the &#8220;RUN&#8221; Keyword.<br>&#8220;EXPOSE&#8221; tells docker which port to expose (with apache that&#8217;s usually 80 and\/or 443), this can be mapped to what you like later.<br>Last we have &#8220;CMD&#8221;, which is pretty much the same as &#8220;ENTRYPOINT&#8221; to my understanding. It tells the container which command to execute (we&#8217;ll run apache).<br>The Syntax is important here.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>It&#8217;s time to assemble our new conatiner:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker build -f Dockerfile -t apacheperl .<\/code><\/pre>\n\n\n\n<p>docker build -f tells Docker to use this File in particular and -t tells it to immediately tag the image after the build (last post we did this in a separate step).<\/p>\n\n\n\n<p>After a few minutes the build should be finished and you should see your new container with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker image ls\nREPOSITORY              TAG                 IMAGE ID            CREATED             SIZE\napacheperl              latest              57b87ae05e5a        24 minutes ago      361MB<\/code><\/pre>\n\n\n\n<p>Now, run it with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d --name \"apache-perl-test\" --network test-net -p 8082:80 apacheperl<\/code><\/pre>\n\n\n\n<p>And then access it via:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:\/\/localhost:8082\/perl\/index.pl<\/code><\/pre>\n\n\n\n<p>You have build a containerized web service!<br><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Remark on Service start: there are more convenient way to bring up and maintain your service with docker compose or kubernetes for example.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Remark on the Dockerfile:<br>If we would be using official images, we could do some of the configuration, that we put into the vhost definition, via &#8220;ENV&#8221; Variables.<br>&#8220;ENV&#8221; are environment variables one can use to configure some aspects of the container. The only way I found to lookup all possible variables of an image, is to check out it&#8217;s documentation on dockerhub (in this case: <a href=\"https:\/\/docs.docker.com\/samples\/library\/mariadb\/\">mariadb).<\/a><br>One can set ones own environment variables at buildtime, using ARG, they van be accessed by ENV then<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ENV APACHE_RUN_USER=www-data \\    \nAPACHE_RUN_GROUP=www-data \\\nAPACHE_LOG_DIR=\/var\/log\/apache2 <\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>To start building a new Service, you&#8217;ll need an image first.Our Service will be an apache Server which delivers an application. So get an image from dockerhub or build your own (as described in my last post). We&#8217;ll start by creating a working directory for our files: Let&#8217;s add a simple Perlscript, that prints &#8220;Hello &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.nikster.de\/wordpress\/index.php\/2019\/05\/05\/how-to-build-a-webservice-with-docker\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How to build a webservice with docker&#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":[21,15,3,18,12,20,19],"class_list":["post-22","post","type-post","status-publish","format-standard","hentry","category-docker","tag-apache","tag-debian","tag-docker","tag-how-to","tag-howto","tag-perl","tag-webservice","entry"],"_links":{"self":[{"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/22","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=22"}],"version-history":[{"count":3,"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/22\/revisions"}],"predecessor-version":[{"id":28,"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/22\/revisions\/28"}],"wp:attachment":[{"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.nikster.de\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}