{"id":161,"date":"2019-12-23T09:00:16","date_gmt":"2019-12-23T14:00:16","guid":{"rendered":"http:\/\/blog.voipxswitch.com\/?p=161"},"modified":"2021-01-17T11:25:15","modified_gmt":"2021-01-17T16:25:15","slug":"freeswitch-container-from-scratch-using-dind","status":"publish","type":"post","link":"https:\/\/blog.voipxswitch.com\/?p=161","title":{"rendered":"freeswitch container from scratch using DIND"},"content":{"rendered":"\n<p>In this post, I&#8217;m going to demonstrate how to build a docker container from a <a href=\"https:\/\/hub.docker.com\/_\/scratch\/\">scratch<\/a> image that will run <em>FreeSWITCH<\/em>. I&#8217;ve always liked scratch because it&#8217;s the most minimal docker image available, and in my mind, that really meshes well with the entire concept of docker containers. But I&#8217;ll give a bit of my background with scratch and why I&#8217;ve used it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Scratch is simple with <em>Go<\/em><\/h3>\n\n\n\n<p>I&#8217;ve worked with docker containers as microservices for many years now. And I&#8217;ve used <a href=\"https:\/\/golang.org\/\"><em>go<\/em><\/a> to build 99% of microservices I&#8217;ve ever written. <em>Go<\/em> and docker seem to go hand in hand when building microservices. When building microservices written in <em>go<\/em>, the most practical docker image is <a href=\"https:\/\/hub.docker.com\/_\/scratch\/\">scratch<\/a>. <\/p>\n\n\n\n<p>Scratch works great for software written in <em>go<\/em> because <em>go<\/em> doesn&#8217;t have any dependencies on external libraries. You can compile your <em>go<\/em> code for the target environment and add the binary to your container based on scratch. Depending on the size of your <em>go<\/em> code, you&#8217;ll end up with a container that&#8217;s only a few megabytes. <\/p>\n\n\n\n<p><em>Example:<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># compile your go app:\nCGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o myapp<\/pre>\n\n\n\n<p><em>Dockerfile<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM scratch\nADD myapp \/\nCMD [\"\/myapp\"]<\/pre>\n\n\n\n<p><em>Build your container and run it:<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker build . -t myapp:latest\ndocker run --rm --name myapp myapp:latest<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Not so simple with <em>FreeSWITCH<\/em><\/h3>\n\n\n\n<p>I&#8217;ve talked about how easy it is to use scratch with software written in <em>go<\/em>. But when you are dealing with software written in C which require external libraries, like <em>FreeSWITCH<\/em>, it becomes difficult to use the scratch image. The reason for this is, scratch doesn&#8217;t come with <strong>any<\/strong> libraries at all. This means if you want to use scratch for something like <em>FreeSWITCH<\/em>, you must include those externally linked libraries in your docker container.<\/p>\n\n\n\n<p>Thankfully, the external libraries <em>FreeSWITCH<\/em> requires are readily available when you install it on Debian. They will automatically be installed when you use the SignalWire apt-get repo. But finding and adding those external libraries into your docker container isn&#8217;t so easy.<\/p>\n\n\n\n<p>I spent a bit of time building <em>FreeSWITCH<\/em> in a container based on a Debian image. Then I stumbled upon the <a href=\"https:\/\/github.com\/signalwire\/freeswitch\/blob\/f6c10f8622e997548a486e5bf4f700b37e12a4eb\/docker\/base_image\/README.md\">SignalWire<\/a> repo which contained a handy script (<code><a href=\"https:\/\/github.com\/signalwire\/freeswitch\/blob\/f6c10f8622e997548a486e5bf4f700b37e12a4eb\/docker\/base_image\/make_min_archive.sh\">make_min_archive.sh<\/a><\/code>) to find all the linked libraries <em>FreeSWITCH<\/em> depends on. I borrowed (and modified) the <code>make_min_archive.sh<\/code> script quite a bit to fit my needs. Once I was able to build <em>FreeSWITCH<\/em> in a Debian based container, I wanted to take it a step further and use scratch. I learned about Docker-In-Docker (DinD) at some point along the way. <\/p>\n\n\n\n<p>DinD is a method to use a single Dockerfile to run multiple docker images in order to build a single container. With DinD, I used a Debian 10 image to install <em>FreeSWITCH<\/em>, run the <code>make_min_archive.sh<\/code> script to build a binary image which included all linked libraries, then copy the binary over to <code>scratch<\/code> where everything will run. You end up with a 44M image that runs <em>FreeSWITCH<\/em> in docker!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"2380\" height=\"182\" src=\"https:\/\/blog.voipxswitch.com\/wp-content\/uploads\/2019\/12\/image.png\" alt=\"\" class=\"wp-image-198\"\/><figcaption>The container listed &lt;none&gt; is the DinD container which uses Debian 10. The size of the FreeSWITCH container is significantly smaller.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"3294\" height=\"780\" src=\"https:\/\/blog.voipxswitch.com\/wp-content\/uploads\/2019\/12\/image-1.png\" alt=\"\" class=\"wp-image-200\"\/><figcaption>Dockerfile using DinD<\/figcaption><\/figure>\n\n\n\n<p>If you&#8217;re interested in trying this yourself, I&#8217;ve posted my work on github at <a href=\"https:\/\/github.com\/voipxswitch\/freeswitch-docker\">https:\/\/github.com\/voipxswitch\/freeswitch-docker<\/a>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, I&#8217;m going to demonstrate how to build a docker container from a scratch image that will run FreeSWITCH. I&#8217;ve always liked scratch because it&#8217;s the most minimal docker image available, and in my mind, that really meshes well with the entire concept of docker containers. But I&#8217;ll give a bit of my [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,20,25,15],"tags":[],"class_list":["post-161","post","type-post","status-publish","format-standard","hentry","category-docker","category-freeswitch","category-sip","category-voip"],"_links":{"self":[{"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=\/wp\/v2\/posts\/161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=161"}],"version-history":[{"count":55,"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=\/wp\/v2\/posts\/161\/revisions"}],"predecessor-version":[{"id":231,"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=\/wp\/v2\/posts\/161\/revisions\/231"}],"wp:attachment":[{"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.voipxswitch.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}