<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tom Withers</title>
    <description>The latest articles on DEV Community by Tom Withers (@tomtucka).</description>
    <link>https://dev.to/tomtucka</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F50020%2F48e8b4ee-37bf-4c2c-91e3-7e7742d40a9c.jpg</url>
      <title>DEV Community: Tom Withers</title>
      <link>https://dev.to/tomtucka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tomtucka"/>
    <language>en</language>
    <item>
      <title>How to use multi-stage Docker builds</title>
      <dc:creator>Tom Withers</dc:creator>
      <pubDate>Mon, 19 Aug 2019 13:21:21 +0000</pubDate>
      <link>https://dev.to/tomtucka/how-to-use-multi-stage-docker-builds-1fde</link>
      <guid>https://dev.to/tomtucka/how-to-use-multi-stage-docker-builds-1fde</guid>
      <description>&lt;p&gt;This post was first published on the Ministry of Justice Digital &amp;amp; Technology &lt;a href="https://medium.com/just-tech"&gt;technical blog&lt;/a&gt; on July 26th 2019.&lt;/p&gt;

&lt;p&gt;Docker has revolutionized the way software engineers build applications, small maintainable pieces of software that can be easily scaled to meet demand. But with new technology, there are now more things to take into consideration. One such issue that arose with Docker is image size. Traditionally to get an efficient docker image you would use some complex shell commands within the Dockerfile to keep the layers as small as possible.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Docker 17.05&lt;/code&gt; multi-stage builds were introduced and this means we can now make docker images even smaller, below I'm going to go over an example of how to do this with a Symfony app and composer.&lt;/p&gt;

&lt;p&gt;With multi-stage builds, you can use multiple &lt;code&gt;FROM&lt;/code&gt; commands within a single &lt;code&gt;Dockerfile&lt;/code&gt;. Each &lt;code&gt;FROM&lt;/code&gt; command can use a different base and symbolises a new stage in the build. The most useful thing is that you can selectively copy artifacts from one stage to another leaving everything that you don't need behind.&lt;/p&gt;

&lt;p&gt;So let's create a new &lt;code&gt;Dockerfile&lt;/code&gt; and add our first &lt;code&gt;FROM&lt;/code&gt; command. This will be using composer as a base image so we can get all of our composer dependencies. We can also name the different stages within the build by adding &lt;code&gt;AS &amp;lt;NAME&amp;gt;&lt;/code&gt; to the &lt;code&gt;FROM&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM composer AS composer

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's copy over our &lt;code&gt;composer.json&lt;/code&gt;, &lt;code&gt;composer.lock&lt;/code&gt;. We're also going to add a &lt;code&gt;RUN&lt;/code&gt; command which will run a composer install.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM composer AS composer

COPY composer.json /app
COPY composer.lock /app

RUN composer install

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the first part of our multi-stage build is done, this will allow us to install our composer dependencies into the first image and then copy them across into the final image.&lt;/p&gt;

&lt;p&gt;Next, we need to build our final stage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM php:7-fpm-alpine

WORKDIR /var/www

COPY ./ /app
COPY --from=composer /app/vendor /app/vendor

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using &lt;code&gt;FROM php:7-fpm-alpine&lt;/code&gt; we start a new build using &lt;code&gt;php:7-fpm-alpine&lt;/code&gt; as the base image, we then use &lt;code&gt;COPY --from=composer&lt;/code&gt; to copy over the &lt;code&gt;vendor&lt;/code&gt; folder into our new image. We leave all the composer gubbins behind, and it's not saved into our final Image.&lt;/p&gt;

&lt;p&gt;Full &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM composer AS composer

COPY composer.json /app
COPY composer.lock /app

RUN composer install

FROM php:7-fpm-alpine

WORKDIR /var/www

COPY ./ /app
COPY --from=composer /app/vendor /app/vendor

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You only need a single Dockerfile. Just run &lt;code&gt;docker build&lt;/code&gt; and docker the build process will start.&lt;/p&gt;

&lt;p&gt;The end result of using multi-stage builds is a slim production-ready image without any complexity. I hope you can see the benefits of using multi-stage builds and I would definitely encourage you to try them out.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
      <category>images</category>
    </item>
    <item>
      <title>Python config file with YAML</title>
      <dc:creator>Tom Withers</dc:creator>
      <pubDate>Mon, 06 Aug 2018 08:23:21 +0000</pubDate>
      <link>https://dev.to/tomtucka/python-config-file-with-yaml-3e31</link>
      <guid>https://dev.to/tomtucka/python-config-file-with-yaml-3e31</guid>
      <description>&lt;p&gt;So I was googling for this myself about 4 weeks ago and couldn't find a straight answer, so I'm about to share an easy step by step solution with you.&lt;/p&gt;

&lt;p&gt;First off I'm going to assume that you already know some python and have a project setup ready to go inside a venv.&lt;/p&gt;

&lt;p&gt;First off lets import yaml,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import yaml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so now lets create a method called &lt;code&gt;load_config&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import yaml

def load_config(config_file):

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we are also passing in &lt;code&gt;config_file&lt;/code&gt;, Next, we are going to open our config file as a stream using &lt;code&gt;open&lt;/code&gt; which is built into python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import yaml

def load_config(config_file):
    with open(config_file, 'r') as stream:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using open, we can now open our config file and return a stream. So here we pass in our &lt;code&gt;config_file&lt;/code&gt; variable which we defined earlier, we also pass in another parameter which is a string of &lt;code&gt;r&lt;/code&gt; this basically tells &lt;code&gt;open&lt;/code&gt; which mode we want to open the file in. Now we can move on to loading our YAML file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def load_config(config_file):
    with open(config_file, 'r') as stream:
        try:
            return yaml.safe_load(stream)
        except yaml.YAMLError as exc:
            print(exc)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see above, we now load our YAML file using &lt;code&gt;safe_load&lt;/code&gt;. It's extremely important to use &lt;code&gt;safe_load&lt;/code&gt; here, &lt;code&gt;safe_load&lt;/code&gt; only resolves basic YAML tags, whereas &lt;code&gt;load&lt;/code&gt; does not. This is also wrapped in a &lt;code&gt;try except&lt;/code&gt; block so we can handle any errors.&lt;/p&gt;

&lt;p&gt;All that's left to do now is call our method to load the file, make sure you pass in the path to your config.yml file here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config = load_config('config.yml')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is my first ever blog post any feedback would be greatly appreciated! :)&lt;/p&gt;

</description>
      <category>python</category>
    </item>
  </channel>
</rss>
