<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Docker on Andrew Khoury</title><link>https://www.drewkhoury.com/tags/docker/</link><description>Recent content in Docker on Andrew Khoury</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright © 2021, Andrew Khoury; all rights reserved.</copyright><lastBuildDate>Thu, 11 Nov 2021 19:22:11 +0000</lastBuildDate><atom:link href="https://www.drewkhoury.com/tags/docker/index.xml" rel="self" type="application/rss+xml"/><item><title>How to implement Good Software Delivery in 30 seconds</title><link>https://www.drewkhoury.com/post/gsd/how-to-implement-good-software-delivery-in-30-seconds-72d13ad4a296/</link><pubDate>Thu, 11 Nov 2021 19:22:11 +0000</pubDate><guid>https://www.drewkhoury.com/post/gsd/how-to-implement-good-software-delivery-in-30-seconds-72d13ad4a296/</guid><description>
&lt;p>Good Software Delivery (GSD) is the term we use for the set of practices that help deliver, well, &lt;em>good&lt;/em> software. There’s a focus on short feedback loops, a consistent developer experience, with more time spent delivering and less time spent on chores like workstation setup and debug.&lt;/p>
&lt;p>For context, I’ve previously written the following blogs that explain a lot of the “why” you’d want to implement the app I’m about to demo:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://medium.com/@drew.khoury/how-cloud-transformation-at-scale-can-enable-good-software-delivery-4a6645d4c570">GSD&lt;/a> &amp;amp; &lt;a href="https://medium.com/@drew.khoury/good-software-delivery-trust-and-verify-ced74fa04b39">Trust and Verify&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/@drew.khoury/optimizing-for-dx-the-developer-experience-f37fe168642d">Developer Experience&lt;/a> &amp;amp; &lt;a href="https://medium.com/@drew.khoury/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2">3 Musketeers&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="assumptions">Assumptions&lt;/h3>
&lt;p>Before we dive in I want to share my assumptions and expectations. This blog/demo is &lt;strong>aimed at developers&lt;/strong>, who are also familiar with pipelines, local development environments, and tools like docker.&lt;/p>
&lt;p>While you can clone the repo and run the commands quickly (even with zero knowledge or experience in the underlying Golang app), it will take you longer than 30 seconds to read this blog, and even longer to look through the repo’s &lt;a href="https://github.com/contino/gsd-hello-world/blob/master/README.md">README.md&lt;/a> and code in the repo to see what’s happening when you type each command. I’ve tried to add as much detail and context for those that’d like to deep dive, both in this blog and in the repo itself.&lt;/p>
&lt;p>The purpose isn’t to copy and paste what you see here into production, but I do hope I’m able to demonstrate some ways of setting up your repo and local development environment in a way that could save you and your team time for your next product!&lt;/p>
&lt;h3 id="what-well-do-in-thisdemo">What we’ll do in this demo&lt;/h3>
&lt;p>In this post, I wanted to share a hands-on implementation of some of these concepts that you can try for yourself. We’ll be using a hello-world app written in Golang, and by the end of the demo I’m hoping:&lt;/p>
&lt;ul>
&lt;li>You’ll see how wrapping our pipeline in 3 Musketeers can greatly reduce the amount of toil spent getting a new project started (thus the 30 seconds claim for this simple app)&lt;/li>
&lt;li>You’ll see that you can adapt the concepts in this demo to just about any app (Java, .Net etc) — More complex apps may take longer to compile, but no extra effort should be required in terms of desktop setup (toil)&lt;/li>
&lt;li>You’ll be able to extend the logic for other pipeline tasks like testing or security&lt;/li>
&lt;/ul>
&lt;p>If this demo takes you longer than 30 seconds to run this demo, I suspect:&lt;/p>
&lt;ul>
&lt;li>We need to get you a better Internet connection (most of the 30 seconds for me is spent downloading the initial Golang image on an empty docker cache)&lt;/li>
&lt;li>We need to help you with the base requirements that this blog assumes you already have (&lt;code>make&lt;/code>,&lt;code>docker&lt;/code>and &lt;code>docker-compose&lt;/code>)&lt;/li>
&lt;/ul>
&lt;p>In any case, &lt;a href="https://www.linkedin.com/in/drewkhoury/">reach out&lt;/a> on LinkedIn if you have suggestions to improve this demo, or set up a &lt;a href="https://calendly.com/drew-khoury">virtual meeting with me&lt;/a> if you’d like a 1:1 workshop/chat!&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*Yh9siTLfQhrFtMsQoo-OHw.gif" alt="">&lt;/p>
&lt;h3 id="the-demo-build-and-run-a-go-app-in-30seconds">The demo (build and run a Go app in 30 seconds)&lt;/h3>
&lt;blockquote>
&lt;p>&lt;em>At a minimum, you’ll need&lt;/em> &lt;code>_make_&lt;/code>&lt;em>,&lt;/em> &lt;code>_docker_&lt;/code> &lt;em>and&lt;/em> &lt;code>_docker-compose_&lt;/code> &lt;em>on your workstation. See&lt;/em> &lt;a href="https://github.com/contino/gsd-hello-world#requirements">&lt;em>requirements&lt;/em>&lt;/a> &lt;em>for more info or continue on if you’ve already got these.&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;p>Not sure about running this demo on your computer? Never fear! You can use this online environment from the safety of your browser: &lt;a href="https://www.katacoda.com/drewkhoury/courses/good-software-delivery/hello-world-golang">GSD HelloWorld katacoda&lt;/a> (repo will already be cloned in this environment, with required software ready to go)&lt;/p>
&lt;script src="//katacoda.com/embed.js">&lt;/script>
&lt;div id="katacoda-scenario-1"
data-katacoda-id="drewkhoury/courses/good-software-delivery/hello-world-golang"
data-katacoda-color="004d7f"
style="height: 850px; padding-top: 0px;">&lt;/div>
&lt;p>You can see all of my Katacoda courses at &lt;a href="https://www.katacoda.com/drewkhoury/">https://www.katacoda.com/drewkhoury/&lt;/a>.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Clone the repo:&lt;/strong> Start by cloning the &lt;a href="https://github.com/contino/gsd-hello-world">GSD HelloWorld&lt;/a> repo:&lt;/li>
&lt;/ol>
&lt;p>&lt;code>git clone git@github.com:contino/gsd-hello-world.git &amp;amp;&amp;amp; cd gsd-hello-world&lt;/code>&lt;/p>
&lt;p>&lt;strong>2. Build the app:&lt;/strong> Once you have the codebase, build the app using:&lt;/p>
&lt;p>&lt;code>make build&lt;/code>&lt;/p>
&lt;p>This step will create a build artifact (in our case, a docker image) by doing the following:&lt;/p>
&lt;ul>
&lt;li>downloads the appropriate docker image onto your workstation&lt;/li>
&lt;li>copies the source for our app into the image&lt;/li>
&lt;li>builds the application in the image&lt;/li>
&lt;li>configures the port/cmd to be used at runtime&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*UdL5jdUgFWi7fn2UzbUhIQ.png" alt="">&lt;/p>
&lt;p>&lt;strong>3. Run the app:&lt;/strong> Now that you have your build artifact handy, you can run the application locally with:&lt;/p>
&lt;p>&lt;code>make run&lt;/code>&lt;/p>
&lt;p>This step will run/deploy the artifact on your workstation by doing the following:&lt;/p>
&lt;ul>
&lt;li>uses docker to create a container based on the image from the &lt;code>build&lt;/code> step&lt;/li>
&lt;li>exposes port 8080 locally&lt;/li>
&lt;li>the docker image runs the cmd &lt;code>./main&lt;/code> which starts the application for us&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/1200/1*aJcA5Mkd3nh8EFJJ2ZjMNw.png" alt="">&lt;/p>
&lt;p>That’s it, you’re running the GSD HelloWorld application written in Golang and containerized so that it can quickly be deployed in Docker.&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/1200/1*9ePbn1rS0h-RprW2M7s-Og.png" alt="">&lt;/p>
&lt;p>&lt;strong>Bonus:&lt;/strong> You can run &lt;code>make test&lt;/code> to execute the test suite (note this may legitimately fail if it doesn’t meet the testing threshold), and&lt;code>make down&lt;/code> to clean up once you’re done.&lt;/p>
&lt;p>The beauty of this model is in its simplicity. We’re using &lt;code>make&lt;/code> as the interface and we’re running all the tasks in containers to ensure consistency. It’s easy enough to peak under the hood to see what either of those tools is doing, and this runs just as easily on your workstation as it does on your CI tool of choice.&lt;/p>
&lt;h3 id="digging-into-thecode">Digging into the code&lt;/h3>
&lt;p>To keep this section brief I’m going to assume some prior knowledge around development, docker, and make.&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*-WosNzXumx9wbyGbgpcIlA.png" alt="">&lt;/p>
&lt;blockquote>
&lt;p>What if I want to make my own changes or do something similar in my own repo?&lt;/p>
&lt;/blockquote>
&lt;p>For the curious: Checkout the &lt;code>Makefile&lt;/code>, &lt;code>docker-compose.yml&lt;/code> and &lt;code>Dockerfile&lt;/code> in the repo. These drive our pipeline and app build etc, and while they abstract the complexity away from day-to-day usage, they’re intended to be developer-friendly in terms of understanding exactly what each step is doing.&lt;/p>
&lt;p>&lt;strong>Building the app:&lt;/strong> For example &lt;code>make build&lt;/code> is what builds our application, and in the &lt;code>Makefile&lt;/code> you’ll see it does the following:&lt;/p>
&lt;p>&lt;code>docker build -t ${FULL_TAG} .&lt;/code>&lt;/p>
&lt;p>&lt;strong>Replacing the app:&lt;/strong> If you wanted to replace our Golang application with your own Java application, you’d drop in your own &lt;code>Dockerfile&lt;/code> , replace the &lt;code>/src&lt;/code>, and leave everything else as-is. The beauty is that any developer using the repo still runs &lt;code>make build&lt;/code> and they don’t need to worry about Go vs Java dependencies (or in theory even know that you completely rewrote the application) — it just works™.&lt;/p>
&lt;blockquote>
&lt;p>Note: This repo is a testing ground for GSD practices — simple but powerful ways to supercharge your development.&lt;/p>
&lt;/blockquote>
&lt;p>If you’d like to see what else you can do, have a look at the rest of the &lt;a href="https://github.com/contino/gsd-hello-world">https://github.com/contino/gsd-hello-world&lt;/a> — we have plenty for you to explore.&lt;/p>
&lt;ul>
&lt;li>&lt;code>build&lt;/code>, &lt;code>test&lt;/code> and &lt;code>run&lt;/code> actions are driven by a simple &lt;code>Makefile&lt;/code> — with underlying execution via docker containers&lt;/li>
&lt;li>Build badge in &lt;a href="https://github.com/contino/gsd-hello-world/blob/master/README.md">README.md&lt;/a>&lt;/li>
&lt;li>Repo Visualization in &lt;a href="https://github.com/contino/gsd-hello-world/blob/master/README.md">README.md&lt;/a>&lt;/li>
&lt;li>Sonar quality, reliability, and security badges in &lt;a href="https://github.com/contino/gsd-hello-world/blob/master/README.md">README.md&lt;/a>&lt;/li>
&lt;li>Golang security in-pipeline&lt;/li>
&lt;li>Local tests via &lt;code>make test&lt;/code>&lt;/li>
&lt;li>Artifact storage via Github Packages&lt;/li>
&lt;li>Github Actions&lt;/li>
&lt;li>Deployment to k8s in GCP&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Further reading:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://medium.com/@drew.khoury/how-cloud-transformation-at-scale-can-enable-good-software-delivery-4a6645d4c570">GSD&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/@drew.khoury/good-software-delivery-trust-and-verify-ced74fa04b39">Trust and Verify&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/@drew.khoury/optimizing-for-dx-the-developer-experience-f37fe168642d">Developer Experience&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/@drew.khoury/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2">3 Musketeers&lt;/a> and &lt;a href="https://3musketeers.io/">https://3musketeers.io/&lt;/a>&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>May your software be good, and your delivery be continuous — drew&lt;/p>
&lt;/blockquote>
&lt;div class="notices info">
&lt;div class="label">Info&lt;/div>
&lt;p>Also posted on medium as &lt;a href="https://medium.com/@drew.khoury/how-to-implement-good-software-delivery-in-30-seconds-72d13ad4a296?source=friends_link&amp;amp;sk=bd2774e9b1cd9f5a4a293aa290cb657e">How to implement Good Software Delivery in 30 seconds&lt;/a>.&lt;/p>
&lt;/div></description></item><item><title>3 Musketeers for an epic Developer Experience</title><link>https://www.drewkhoury.com/post/gsd/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2/</link><pubDate>Sat, 28 Aug 2021 14:18:09 +0000</pubDate><guid>https://www.drewkhoury.com/post/gsd/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2/</guid><description>
&lt;p>We all want to reduce toil and improve the developer experience (when starting new applications or joining the team). Developers have had to invest significant time in creating production-ready pipelines when building new products and configuring their workstations when joining teams. Their workstations may not run all the same tests as their pipeline and thus they’re left with &lt;a href="https://www.linkedin.com/feed/hashtag/?keywords=slowfeedback&amp;amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6835918781475246080">#slowfeedback&lt;/a> and an inconsistent experience.&lt;/p>
&lt;p>The larger the organization (ie Enterprise with 10’s-100’s of teams and applications) the worse the problem gets.&lt;/p>
&lt;p>GSD is built on the principle of reusability through a pattern called &lt;a href="https://3musketeers.io/">3 Musketeers&lt;/a> (test, build, and deploy your apps from anywhere, the same way). It gives consistency, control, and confidence to development teams.&lt;/p>
&lt;p>Docker is a key part of this pattern, but the use of &lt;code>docker&lt;/code>, &lt;code>docker-compose&lt;/code> and &lt;code>make&lt;/code> together really unlock the powers of consistency, control and confidence in your application build, test and deploy steps. The &lt;a href="https://3musketeers.io/docs/">3musketeers Docs&lt;/a> have some great examples of these patterns.&lt;/p>
&lt;p>Here's what the most simple usage looks like:&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*O8UwDvze7KXEDKLKgqevcw.jpeg" alt="">&lt;/p>
&lt;p>While the pattern itself is simple, the power (and benefit) comes from the widespread usage across your organization. Here’s what usage might look like:&lt;/p>
&lt;ul>
&lt;li>Agree on a standard interface for all pipeline actions (much like API’s have an agreed interface, all pipelines in the org use the same interface, ie `make build`, `make test`, `make deploy`)&lt;/li>
&lt;li>Keep the interface simple (avoid custom pipeline logic, one simple Makefile calls Compose, the container handles all the logic)&lt;/li>
&lt;li>Create docker containers for each pipeline step, make them stateless, reuse them where it makes sense&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*hdKr28atovmEGFkBRaOIXA.jpeg" alt="">&lt;/p>
&lt;p>&lt;strong>Wins:&lt;/strong> Modern pipelines already support running steps in docker containers. This pattern extends portability across almost any pipeline tool or development workstation and runs the same way in every single environment. Pipeline steps can be tested independently and reused. This pattern makes it easy to go one step further and generate pipelines on-demand based on boilerplate starter templates. Oh yeah, and &lt;a href="https://www.linkedin.com/feed/hashtag/?keywords=fastfeedback&amp;amp;highlightedUpdateUrns=urn%3Ali%3Aactivity%3A6835918781475246080">#fastfeedback&lt;/a> (we’re talking pre-commit).&lt;/p>
&lt;div class="notices info">
&lt;div class="label">Info&lt;/div>
&lt;p>Also posted on medium as &lt;a href="https://medium.com/@drew.khoury/3-musketeers-for-an-epic-developer-experience-8676ddaf33b2">3 Musketeers for an epic Developer Experience&lt;/a>.&lt;/p>
&lt;/div>
&lt;p>_&lt;/p></description></item><item><title>Automating Google App Engine</title><link>https://www.drewkhoury.com/post/automating-google-app-engine-9599b51f0974/</link><pubDate>Mon, 14 Oct 2019 13:46:01 +0000</pubDate><guid>https://www.drewkhoury.com/post/automating-google-app-engine-9599b51f0974/</guid><description>
&lt;p>Google App Engine is &lt;a href="https://www.linkedin.com/pulse/how-do-devops-10-minutes-less-andrew-khoury/">a pretty amazing service&lt;/a>. You write code, and Google will make sure it runs, and scales well. This service was &lt;strong>available way back in 2008&lt;/strong>, well before everyone was getting excited over lambdas and serverless.&lt;/p>
&lt;p>In my opinion, AppEngine is one of the most underrated services I’ve seen. It’s beautifully simple, and it has planet-level scaling (Google words). You don’t have to configure load balancers, tweak an OS or install/configure a Runtime. The focus is on optimizing for the developer experience, and having your spend more time writing code.&lt;/p>
&lt;p>Even though Google makes it easy to get started with App Engine I wanted to reduce the steps even further. I’ve created a GAE demo that offers a local development and deployment environment via docker containers and simple to use commands.&lt;/p>
&lt;h3 id="google-app-enginedemo">Google App Engine Demo&lt;/h3>
&lt;p>&lt;strong>Local Development&lt;/strong>&lt;/p>
&lt;p>Creating a local development environment can be done with one command:&lt;/p>
&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="ln">1&lt;/span>~/code/gae-demo $ docker-compose up local
&lt;/code>&lt;/pre>&lt;/div>&lt;p>This is what the console output should look like:&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*3xPuZNa4CdEUxIPqDdYnGw.png" alt="">&lt;/p>
&lt;p>This is what the app looks running on your machine:&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*nWX-jfZeUS7f4ctvgo2HZw.png" alt="">&lt;/p>
&lt;p>The demo app comes with instructions and sample code that adds entries to a local datastore.&lt;/p>
&lt;p>One of the amazing features of Google App Engine is the local admin environment that offers similar functionality to the online admin console from Google. The demo comes with everything pre-configured and ready to use.&lt;/p>
&lt;p>&lt;em>Local Datastore Viewer:&lt;/em>&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*Hah8fDHL9W5LbpzgUG9MFw.png" alt="">&lt;/p>
&lt;p>&lt;em>Interactive Console:&lt;/em>&lt;/p>
&lt;p>&lt;img src="https://cdn-images-1.medium.com/max/800/1*Xd7M9eglzNFVjtEDQSN1IA.png" alt="">&lt;/p>
&lt;p>Not bad for one line of code!&lt;/p>
&lt;p>&lt;strong>Deploying&lt;/strong>&lt;/p>
&lt;p>Google has a wonderful feature called “ &lt;a href="https://cloud.google.com/resource-manager/docs/creating-managing-projects">Projects&lt;/a>” that allow you to group related resources to make them easier to manage. When you run the `new-deploy` command the demo will create a new project and related application, then deploy it for you.&lt;/p>
&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="ln">1&lt;/span>~/code/gae-demo $ docker-compose up new-deploy
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Deploying updates to your application is quick and easy too. First specify your project id from the previous step, then run &lt;code>re-deploy&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="ln">1&lt;/span>~/code/gae-demo $ export CLOUDSDK\_CORE\_PROJECT=devops-demo-xxx ~/code/gae-demo $ docker-compose up re-deploy
&lt;/code>&lt;/pre>&lt;/div>&lt;p>That’s it, why are you still here? You could be spending this time deploying your new application.&lt;/p>
&lt;p>You can find the full demo and instructions here: &lt;a href="https://github.com/drewkhoury/gae-demo">https://github.com/drewkhoury/gae-demo&lt;/a>&lt;/p>
&lt;div class="notices info">
&lt;div class="label">Info&lt;/div>
&lt;p>Also posted on medium as &lt;a href="https://medium.com/@drew.khoury/automating-google-app-engine-9599b51f0974">Automating Google App Engine&lt;/a>.&lt;/p>
&lt;/div></description></item></channel></rss>