<?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: Samuele Agostinelli</title>
    <description>The latest articles on DEV Community by Samuele Agostinelli (@samuelea).</description>
    <link>https://dev.to/samuelea</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%2F354387%2Fa4f5aee8-32b9-49bc-8b24-41fd4b2c10d6.png</url>
      <title>DEV Community: Samuele Agostinelli</title>
      <link>https://dev.to/samuelea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samuelea"/>
    <language>en</language>
    <item>
      <title>Automate your Builds on Docker Hub by Writing a Build Hook Script!</title>
      <dc:creator>Samuele Agostinelli</dc:creator>
      <pubDate>Mon, 06 Apr 2020 01:23:18 +0000</pubDate>
      <link>https://dev.to/samuelea/automate-your-builds-on-docker-hub-by-writing-a-build-hook-script-13fp</link>
      <guid>https://dev.to/samuelea/automate-your-builds-on-docker-hub-by-writing-a-build-hook-script-13fp</guid>
      <description>&lt;p&gt;Docker Hub is like Github for Docker images, making all our lives way easier.&lt;/p&gt;

&lt;p&gt;Yet, it can quickly become a nightmare to maintaining multiple docker images. We don’t want to build the images manually each time we make a change to the Dockerfile. Also, we might want to support multiple variations of the same Docker image. For example, to support multiple node versions.&lt;/p&gt;

&lt;p&gt;So good thing you’ve found this tutorial!&lt;/p&gt;

&lt;p&gt;In the next few minutes, we will see how we can automate our builds by connecting our Docker Hub repo to a Github repo for automated builds. Finally, we’ll go deeper on the subject by exploring advanced options such as writing a build script that will give us complete control on the building process.&lt;/p&gt;

&lt;p&gt;And you will then ascend to Docker Godhood!&lt;/p&gt;

&lt;h1&gt;
  
  
  Connecting a Github Repo to Docker Hub
&lt;/h1&gt;

&lt;p&gt;The simplest way to automate your builds is to connect a Github repo containing a Dockerfile to your Docker Hub repo.&lt;/p&gt;

&lt;p&gt;Here you can see I created a Github repo with a simple Dockerfile.&lt;br&gt;
&lt;a href="https://github.com/SamueleA/docker-hub-auto-build-tutorial"&gt;https://github.com/SamueleA/docker-hub-auto-build-tutorial&lt;/a&gt;&lt;br&gt;
(ignore the build folder for now I will explain soon)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HETBFWjT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d7s9kh4p1zc4gxdp1y79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HETBFWjT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d7s9kh4p1zc4gxdp1y79.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configuring automated builds is quick and easy&lt;/p&gt;

&lt;p&gt;Now, that you have a Github repo go to Docker Hub, click on your repo and, in the &lt;strong&gt;build&lt;/strong&gt; tab, click on &lt;strong&gt;Configure Automated Builds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then, select your repo, fill the form and…that’s it!&lt;/p&gt;

&lt;p&gt;When you will push a commit to your Github repo, Docker Hub will detect the commit and build a new image from your Dockerfile.&lt;/p&gt;

&lt;p&gt;But that is still limiting, isn’t it?&lt;/p&gt;

&lt;p&gt;What about the situation in which I have this Dockerfile that depends on a node version and maybe I want to support ALL the node versions, not just one. Maybe we could specify the node version in the docker tag. Do I then need to create multiple Dockfile? It would be so much easier if there was a way to only modify one Dockerfile and have that Dockerfile generate all the images for all the node versions…&lt;/p&gt;

&lt;p&gt;That’s where build hooks come in.&lt;/p&gt;
&lt;h1&gt;
  
  
  Hooks: Complete Control on the Build Process!
&lt;/h1&gt;

&lt;p&gt;So our goal is simple. We’ll have one Dockerfile and we will want to have it specify the node version through the docker tag, then Docker Hub will generate all the builds based on the tags.&lt;/p&gt;

&lt;p&gt;For instance, &lt;em&gt;my-image:node-10&lt;/em&gt; will use node 10, &lt;em&gt;my-image:node-11&lt;/em&gt; will use node 11 and &lt;em&gt;my-image:latest&lt;/em&gt; will use the latest version available.&lt;/p&gt;

&lt;p&gt;We will need a build hook for that. The build hook will replace Docker Hub’s build process with our own by running a bash script.&lt;/p&gt;

&lt;p&gt;Let’s start by creating a folder called &lt;strong&gt;hooks&lt;/strong&gt; and a file called &lt;strong&gt;build&lt;/strong&gt; inside that folder, just like in my &lt;a href="https://github.com/SamueleA/docker-hub-auto-build-tutorial"&gt;example repo&lt;/a&gt;. Then copy the following code in the &lt;strong&gt;build&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

NODE_VERSION=$(echo $DOCKER_TAG | cut -d "-" -f2)

if [ $DOCKER_TAG == "latest" ]
then
  docker build . --build-arg NODE_VERSION=${DOCKER_TAG} -t ${IMAGE_NAME}
else
  docker build . --build-arg NODE_VERSION=${NODE_VERSION} -t ${IMAGE_NAME}
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build&lt;/strong&gt; is a script written in bash, hence the first line of code. It reads the environment variable DOCKER_TAG and figures out the node version specified (just like we said we would by formatting our Docker tag in the format my-image:node-VERSION).&lt;/p&gt;

&lt;p&gt;This DOCKER_TAG variable is set by Docker Hub itself. You can find a list of all the other environment variables made available by Docker Hub &lt;a href="https://docs.docker.com/docker-hub/builds/advanced"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, there’s an if statement. Basically, it’s to deal with the case when the docker tag is &lt;strong&gt;latest&lt;/strong&gt;. In that case, we’ll simply use the latest node version. In any case, depending on the docker tag, we are going to pass an argument to our build with the &lt;strong&gt;–build-arg&lt;/strong&gt; flag.&lt;/p&gt;

&lt;p&gt;Now, if you look at the Dockerfile in my Github repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARG NODE_VERSION

FROM node:$NODE_VERSION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are calling the variable NODE_VERSION which we’ve just set earlier with the docker build command inside our build script!&lt;/p&gt;

&lt;p&gt;Now, in the build settings on Docker Hub, all I’ll have to do is to set the name of the Docker tags according to our convention and all my images will build automatically! I can support pretty much any node version without the headache of maintaining multiple Dockerfile!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6CEiGteR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4gjx7w2u9f6ozpcsz92t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6CEiGteR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4gjx7w2u9f6ozpcsz92t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here is my Docker Hub repo, if you want to see the final builds: &lt;a href="https://hub.docker.com/repository/docker/samueleago/auto-build-tutorial"&gt;https://hub.docker.com/repository/docker/samueleago/auto-build-tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can imagine, the limit is your imagination at this point. You can have your build script do whatever you envision it to do! And if you are an amazing Bash scripter… knock yourself out with the amazing control it gives you!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automate Away!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hopefully, this tutorial was useful to you and you can now automate your Docker Images for your projects!&lt;/p&gt;

&lt;p&gt;Automate! Automate! Automate!&lt;/p&gt;

&lt;p&gt;PS:&lt;br&gt;
Consult the original article on my blog!&lt;br&gt;
&lt;a href="https://codeclimbing.com/automate-your-builds-on-docker-hub-by-writing-a-build-hook-script/"&gt;https://codeclimbing.com/automate-your-builds-on-docker-hub-by-writing-a-build-hook-script/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
    </item>
    <item>
      <title>Docker for Newbz: Create a Docker Image for Your App!</title>
      <dc:creator>Samuele Agostinelli</dc:creator>
      <pubDate>Mon, 30 Mar 2020 12:54:33 +0000</pubDate>
      <link>https://dev.to/samuelea/docker-for-newbz-create-a-docker-image-for-your-app-1f91</link>
      <guid>https://dev.to/samuelea/docker-for-newbz-create-a-docker-image-for-your-app-1f91</guid>
      <description>&lt;p&gt;NOTE: See the original article &lt;a href="https://codeclimbing.com/docker-for-newbz-create-a-docker-image-for-your-app/"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Every programmer dreads the phrase: “But it works on my machine!!!” Our poor developer now knows that he must now figure out what’s wrong among a bazillion things. “Okay, so what’s your OS? I hope there’s not a quirk with the OS. What about your node version? Maybe the app only works with this specific node version. Etc…”&lt;/p&gt;

&lt;p&gt;Just thinking about it wakes up my problem-solving PTSD developed from many wasted hours trying to figure out what’s wrong with a setup.&lt;/p&gt;

&lt;p&gt;And that’s where Docker comes in. Docker sets a common environment that never changes for us to run our app into. If it works on my machine with the Docker image… it will work on yours!&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll create a simple create-react-application and then we’ll run it in a Docker Container.&lt;/p&gt;

&lt;p&gt;Container? Image? Are you confused? You’re at the right place because this tutorial is for newbz with a z at the end.&lt;/p&gt;

&lt;p&gt;Let’s get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Image vs Docker Container
&lt;/h2&gt;

&lt;p&gt;Just to clarify this real quick. A docker container is an instance of a docker image. In the same manner that a built house (container) is an instance of the architect’s plans (image).&lt;/p&gt;

&lt;p&gt;Simple, right?&lt;/p&gt;

&lt;p&gt;NEXT!&lt;/p&gt;

&lt;h2&gt;
  
  
  Making our First Image
&lt;/h2&gt;

&lt;p&gt;I just want to say that in this tutorial I am assuming you have everything installed already. You should have Node.js, create-react-app and Docker. You’re a big boy. I know you can do that without me. Install all that and come back.&lt;/p&gt;

&lt;p&gt;So to start, we’ll create a simple React application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app my-app
cd my-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Cool now we got a React application. Our goal with this tutorial will be to run “npm run start” and then see our web page while it runs in the container.&lt;/p&gt;

&lt;p&gt;Now, we want to create a Docker Image. How do we do that? We must specify instructions to give to Docker on how to build the image. This is done in a Dockerfile.&lt;br&gt;
Create an empty file inside the React application and call it “Dockerfile”.&lt;/p&gt;

&lt;p&gt;Now, let’s fill that Dockerfile. The comment on top of the line will explain what it does&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# This is the base image. In this case, we are taking a Linux image with node 11. This image is pulled from Docker Hub. https://hub.docker.com/_/node/
FROM node:11

# This will be the directory in which commands such as COPY and RUN will be run.
WORKDIR /app

#This means we copy everything in the current folder (our React application) into the folder defined previously in WORKDIR
COPY . .

# RUN means we run commands in the command line during build time. In this case, we have npm, because it is included in the base docker image. If we didn't have it, we'd have to use RUN to run commands to install node.
RUN npm install

# CMD defines a run-time operation. In this case we want to start the webserver
CMD ["npm", "run", "start"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Did we make a mistake while creating our Dockerfile? Let’s try building our image!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build . -t my-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The command above builds the image from the content of the Dockerfile (since I am assuming the current directory is the one containing the app). The argument “-t my-app” means we want to give our image the tag “my-app”, which will let us refer to our image more easily. After letting the build run, the command line shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Successfully built 82322ef0e172
Successfully tagged my-app:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That means success! “82322ef0e172” is the image id and “my-app” is the tag we defined above in the build command.&lt;/p&gt;

&lt;p&gt;Remember the difference between IMAGE and CONTAINER describe above? Right now we have an image, not a container. We got the plans of the house, we just need to build it so our app can live in it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -dit -p 3000:3000 --name my-app --rm my-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s dissect the command above.&lt;br&gt;
-dit : This will run our container in detached mode running in the background after execution of the commands in the Dockerfile. Without -dit, the container wouldn’t still be running. It would stop as soon as all the commands are run.&lt;/p&gt;

&lt;p&gt;-p 3000: 3000 : This maps port 3000 on our local machine to port 3000 on our docker container. 3000 is the port that the create-react-app web server runs on by default.&lt;/p&gt;

&lt;p&gt;–name my-app: This is the name we want to give to our container&lt;/p&gt;

&lt;p&gt;–rm: This means we wants to delete the container once it has stopped running.&lt;/p&gt;

&lt;p&gt;my-app: The name of the image that will serve as basis for the container&lt;/p&gt;

&lt;p&gt;Now do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will list all the running containers. You should be able to see a container name my-app alongside other information such as the container id.&lt;/p&gt;

&lt;p&gt;The last step is to admire our final result. Go to &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; and you will see your app running!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wHz2oHyP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cxzml8heitbefjkb3tbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wHz2oHyP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cxzml8heitbefjkb3tbo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Have fun!
&lt;/h2&gt;

&lt;p&gt;Docker is an important technology to know about so I hope this was useful to you! Also, here is a github with the react app and dockerfile used in this tutorial: &lt;a href="https://github.com/SamueleA/docker-tutorial"&gt;https://github.com/SamueleA/docker-tutorial&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
