<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ermish</title>
    <description>An exciting place where code, tech talk, and life adventures all mix together into one wonderful blog!  If you're hunting for some new coding tips and tricks or you're just bored and want to read something interesting, then you've come to the right place!
</description>
    <link>http://www.philipermish.com/</link>
    <atom:link href="http://www.philipermish.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 11 Aug 2017 15:57:07 -0700</pubDate>
    <lastBuildDate>Fri, 11 Aug 2017 15:57:07 -0700</lastBuildDate>
    <generator>Jekyll v3.3.1</generator>
    
      <item>
        <title>Deploying Dotnet Core to Google Cloud</title>
        <description>&lt;p&gt;If you’re trying to setup .NET Core / ASP.NET 5 on Google Cloud, then this is the article for you! 
As a disclaimer, I’m building everything based on using a mac development environment.&lt;/p&gt;

&lt;h2 id=&quot;free-money&quot;&gt;Free Money!!!&lt;/h2&gt;

&lt;p&gt;As the time of writing this article, google is giving $300 to play around in the cloud and try out all the toys. Just &lt;a href=&quot;https://cloud.google.com/&quot;&gt;go here&lt;/a&gt;!&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;Free Money!&lt;/aside&gt;

&lt;h2 id=&quot;installing-the-google-cloud-cli&quot;&gt;Installing the Google cloud CLI&lt;/h2&gt;

&lt;p&gt;Now, we just need to setup the google cloud CLI. This is actually pretty nice and will be how you deploy your app.&lt;/p&gt;

&lt;p&gt;You can try to install the CLI here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://cloud.google.com/sdk/downloads&quot;&gt;https://cloud.google.com/sdk/downloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I, personally, was getting an error when trying to install gcloud CLI and ran this instead and it worked:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl https://dl.google.com/dl/cloudsdk/release/install_google_cloud_sdk.bash | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;setup-your-dotnetcore-app&quot;&gt;Setup your dotnetcore app&lt;/h2&gt;

&lt;p&gt;Assuming you have a basic dotnet core setup you can skip this step. If you don’t here’s a barebones setup.&lt;/p&gt;

&lt;p&gt;1) Install the dotnet core CLI&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.microsoft.com/net/core/preview#macos&quot;&gt;https://www.microsoft.com/net/core/preview#macos&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) Run these to create new kestrel web server&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dotnet new web
dotnet restore
dotnet publish -c Release
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will output a &lt;code class=&quot;highlighter-rouge&quot;&gt;bin&lt;/code&gt; folder which will be what is on the server.&lt;/p&gt;

&lt;h2 id=&quot;create-a-docker-file&quot;&gt;Create a docker file&lt;/h2&gt;

&lt;p&gt;You don’t need docker installed or anything for this. If you aren’t familiar, a dockerfile is essentially a server installation script. 
Just create a file named &lt;code class=&quot;highlighter-rouge&quot;&gt;dockerfile&lt;/code&gt; (no extension) and paste this in:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#FROM ermish/gcloud_dotnet_core
FROM gcr.io/google-appengine/aspnetcore
ADD ./yourpathtothebinfolder/bin/Release/netcoreapp2.0/publish/ /app
ENV ASPNETCORE_URLS=http://*:${PORT}                     
WORKDIR /app    
ENTRYPOINT [ &quot;dotnet&quot;, &quot;api.dll&quot; ]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Update &lt;code class=&quot;highlighter-rouge&quot;&gt;yourpathtothebinfolder&lt;/code&gt; with the appropriate path to the publish in the previous step. The path in this file means you don’t need to keep the dockerfile in the same &lt;code class=&quot;highlighter-rouge&quot;&gt;publish&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;NOTE: Here’s where Google’s basic tutorial went wrong. The docker image they have is old and didn’t support the latest dotnet core version. So I went ahead and built out a new docker image and threw it out there for everyone to use! If you deploy your app and are getting errors, just uncomment the line that points to the image I created (the line starting with &lt;code class=&quot;highlighter-rouge&quot;&gt;#&lt;/code&gt;) and remove the other &lt;code class=&quot;highlighter-rouge&quot;&gt;FROM&lt;/code&gt; line pointing to &lt;code class=&quot;highlighter-rouge&quot;&gt;gcr.io&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;create-a-google-app-engine-server-config&quot;&gt;Create a google app engine server config&lt;/h2&gt;

&lt;p&gt;This is a basic script that creates a google app engine based on a dockerfile. Just create a file name &lt;code class=&quot;highlighter-rouge&quot;&gt;app.yaml&lt;/code&gt; and paste this in:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;service: my-demo-app
env: flex
runtime: custom
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;deploy-the-app&quot;&gt;Deploy the app!&lt;/h2&gt;

&lt;p&gt;Just run this to deploy the app to google cloud!&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gcloud app deploy --version v1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can rerun this and change the version each time. It will version the app and shift traffic to the new deployment.&lt;/p&gt;

&lt;h2 id=&quot;thats-it&quot;&gt;That’s it!&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/thatsallfolks.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoyed the tutorial, and feel free to reach out with any questions!&lt;/p&gt;
</description>
        <pubDate>Tue, 08 Aug 2017 00:00:00 -0700</pubDate>
        <link>http://www.philipermish.com/blog/deploying-dotnet-core-to-google-cloud/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/deploying-dotnet-core-to-google-cloud/</guid>
        
        <category>dotnet</category>
        
        <category>core</category>
        
        <category>kestrel</category>
        
        <category>ssl</category>
        
        
        <category>dotnet</category>
        
        <category>core</category>
        
        <category>kestrel</category>
        
        <category>ssl</category>
        
      </item>
    
      <item>
        <title>.NET Core Kestrel with SSL</title>
        <description>&lt;p&gt;This is a quick tutorial for setting up your local .NET Core / Kestrel development environment to use SSL.&lt;/p&gt;

&lt;h3 id=&quot;machine-setup&quot;&gt;Machine setup&lt;/h3&gt;

&lt;p&gt;This article is based on .NET Core 2.0 using VS Code on a mac. No need for the full version of Visual Studio on Windows only!&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;.NET Core 2.0!&lt;/aside&gt;

&lt;h2 id=&quot;setting-up-kestrel&quot;&gt;Setting up Kestrel&lt;/h2&gt;

&lt;p&gt;In your &lt;code class=&quot;highlighter-rouge&quot;&gt;Startup.cs&lt;/code&gt; class, you should be importing an &lt;code class=&quot;highlighter-rouge&quot;&gt;appsettings.json&lt;/code&gt; file and a &lt;code class=&quot;highlighter-rouge&quot;&gt;appsettings.Development.json&lt;/code&gt; file. The development version is run when you set the environment variable &lt;code class=&quot;highlighter-rouge&quot;&gt;ASPNETCORE_ENVIRONMENT&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;Development&lt;/code&gt;. This is usually set by default in VS Code and Visaul Studio.
For this example, we will setup an ssl cert for localhost, so we will update the &lt;code class=&quot;highlighter-rouge&quot;&gt;appsettings.Development.json&lt;/code&gt; file.&lt;/p&gt;

&lt;h3 id=&quot;setting-up-the-url&quot;&gt;Setting up the URL&lt;/h3&gt;

&lt;p&gt;We can setup Kestrel to listen on any address/port by adding this section to the file:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &quot;Kestrel&quot;: {
    &quot;Endpoints&quot;: {
      &quot;localhostHttps&quot;: {
        &quot;Address&quot;: &quot;127.0.0.1&quot;,
        &quot;Port&quot;: &quot;9001&quot;,
        &quot;Certificate&quot;: &quot;HTTPS&quot;
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will use a certificate “HTTPS” which we will setup next.&lt;/p&gt;

&lt;h3 id=&quot;pointing-to-a-cert&quot;&gt;Pointing to a cert&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;Certificates&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;HTTPS&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;Source&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Store&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;StoreLocation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;CurrentUser&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;StoreName&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;Subject&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;CN=localhost&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;AllowInvalid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;creating-the-ssl-certificate&quot;&gt;Creating the SSL Certificate&lt;/h3&gt;

&lt;p&gt;Next, we create a self-signed certificate for HTTPS using &lt;a href=&quot;http://openssl.org/&quot;&gt;OpenSSL&lt;/a&gt;.
You want to run these commands in same folder as your code. This will create the certs in the current directory.&lt;/p&gt;

&lt;p&gt;Run this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl req -new -x509 -newkey rsa:2048 -keyout localhost.key -out localhost.cer -days 365 -subj /CN=localhost
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl pkcs12 -export -out certificate.pfx -inkey localhost.key -in localhost.cer
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;add-the-cert-to-the-macos-keychain&quot;&gt;Add the cert to the macOS keychain&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;security import certificate.pfx -k ~/Library/Keychains/login.keychain-db
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now trust the cert:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;security add-trusted-cert localhost.cer
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;thats-it&quot;&gt;That’s it!&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/thatsallfolks.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoyed the tutorial, and feel free to reach out with any questions!&lt;/p&gt;
</description>
        <pubDate>Sun, 23 Jul 2017 00:00:00 -0700</pubDate>
        <link>http://www.philipermish.com/blog/how-to-use-ssl-with-dotnet-core-and-kestrel/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/how-to-use-ssl-with-dotnet-core-and-kestrel/</guid>
        
        <category>dotnet</category>
        
        <category>core</category>
        
        <category>kestrel</category>
        
        <category>ssl</category>
        
        
        <category>dotnet</category>
        
        <category>core</category>
        
        <category>kestrel</category>
        
        <category>ssl</category>
        
      </item>
    
      <item>
        <title>Docker Example</title>
        <description>&lt;p&gt;In my &lt;a href=&quot;/blog/why-i-went-with-docker/&quot;&gt;last post&lt;/a&gt;, I talked about going with Docker hosted by &lt;a href=&quot;http://www.digitalocean.com/?refcode=802891764c4c&quot;&gt;DigitalOcean&lt;/a&gt;.
This post will walk through the setup and initial design of my Docker app. 
I wanted to go with something that would support future growth and scalability as I play around with multiple languages and technologies. 
I’ll be building this from the perspective of working on a Mac, but it should be almost the same for Windows/Linux. 
Also, I’ll be using VS Code as my IDE, because IT’S AWESOME.&lt;/p&gt;

&lt;h3 id=&quot;design&quot;&gt;Design&lt;/h3&gt;

&lt;p&gt;I’ll be using &lt;a href=&quot;http://www.docker.com/products/docker-compose&quot;&gt;Docker Compose&lt;/a&gt; for setting up the whole environment. 
This makes it really easy to setup all each application and keep track of everything running in your environment. 
Docker Compose is like a checklist of your environment!&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;Docker Compose is like a checklist of your environment!&lt;/aside&gt;

&lt;p&gt;Each app will be setup via a &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; and added to Docker Compose.&lt;/p&gt;

&lt;p&gt;&lt;b&gt; I’ll add a diagram here, soon.&lt;/b&gt;&lt;/p&gt;

&lt;h3 id=&quot;nginx&quot;&gt;Nginx&lt;/h3&gt;

&lt;p&gt;I’ll be using &lt;a href=&quot;http://www.nginx.com/&quot;&gt;Nginx&lt;/a&gt; (Pronounced “Engine-X”) as a Static Web Server, Reverse Proxy, Load Balancer, and for some basic security. 
If you’re not familiar, a reverse proxy is often used like a routing table. 
In this example, any &lt;code class=&quot;highlighter-rouge&quot;&gt;/api/&lt;/code&gt; requests will be sent to the &lt;code class=&quot;highlighter-rouge&quot;&gt;Node&lt;/code&gt; servers; all other requests will be sent to the static content directories. 
This makes it easy to add any other fun stuff like &lt;code class=&quot;highlighter-rouge&quot;&gt;.Net Core&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;Ruby&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;Python&lt;/code&gt; servers with some simple routing! 
The load balancing support is pretty amazing as well. You can set different weights for each , priortizing basic on load, connections, etc. all in Nginx. Piece of cake!&lt;/p&gt;

&lt;h3 id=&quot;nodejs&quot;&gt;NodeJs&lt;/h3&gt;

&lt;p&gt;Up next is &lt;a href=&quot;http://nodejs.org/en/&quot;&gt;NodeJs&lt;/a&gt;! Why?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/javascript.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 200px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this example, I’ll be setting up three different server nodes to distribute the load. 
(Note: this is just on one VPS, so the nodes will be sharing server resources.
 I may put up an example of how to setup multiple servers/droplets and load balance them. 
Also, for anyone curious, from some benchmarking, it does offer better performance with multiple nodes even though they are on the same VPS.)&lt;/p&gt;

&lt;h3 id=&quot;mongodb-and-redis&quot;&gt;MongoDB and Redis&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.mongodb.com/&quot;&gt;MongoDb&lt;/a&gt; will be the database of choice. NoSQL, baby! 
Personally, I come from a strong SQL background. If you’re also coming from a relational data background and grumble at these new ‘fads’, you should give it a chance. 
It’s not the perfect solution to every problem, but it’s definitely eye opening! 
There’s several other NoSQL options, but this one is pretty easy to use and will get the job done for this app.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://redis.io/&quot;&gt;Redis&lt;/a&gt; will be used for some basic caching. 
It’s really easy to use and ties in nicely with NodeJs. As a side note, for &lt;code class=&quot;highlighter-rouge&quot;&gt;.NET&lt;/code&gt; apps, it even has full &lt;code class=&quot;highlighter-rouge&quot;&gt;Linq-to-SQL&lt;/code&gt; support!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/easymode.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 200px;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;jekyll&quot;&gt;Jekyll&lt;/h3&gt;

&lt;p&gt;I’ll be building the static content/blog using &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;. 
It’s based on &lt;code class=&quot;highlighter-rouge&quot;&gt;Ruby&lt;/code&gt;, extremely fast, and very lightweight! There’s no database needed or dynamic content rendering.&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;100% static pages = blazing fast performance!&lt;/aside&gt;

&lt;p&gt;I’ve been playing around with some &lt;code class=&quot;highlighter-rouge&quot;&gt;Node&lt;/code&gt; based blogs such as &lt;a href=&quot;http://ghost.org/&quot;&gt;Ghost&lt;/a&gt; and &lt;a href=&quot;http://hexo.io/&quot;&gt;Hexo&lt;/a&gt;. 
Even though I’m more familiar with &lt;code class=&quot;highlighter-rouge&quot;&gt;Javascript&lt;/code&gt; over &lt;code class=&quot;highlighter-rouge&quot;&gt;Ruby&lt;/code&gt;, Jekyll seemed easier vs. 
Ghost which had a database backend and Hexo which is still growing.&lt;/p&gt;

&lt;h2 id=&quot;lets-get-started-docker-up&quot;&gt;Let’s get started. Docker up!&lt;/h2&gt;

&lt;p&gt;If you don’t have Docker setup yet, just go download the lovely &lt;a href=&quot;http://www.docker.com/products/docker#/mac&quot;&gt;client&lt;/a&gt; for your system. 
This will give you support for the &lt;code class=&quot;highlighter-rouge&quot;&gt;docker&lt;/code&gt; commands and will startup your local environment. 
Next, let’s create a new app directory. On the mac, you can navigate to where you want to create the directory. 
Personally, I’m going to create mine under &lt;code class=&quot;highlighter-rouge&quot;&gt;~/code/&lt;/code&gt;. Just pop open terminal and type:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir dockerdemo
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now, let’s start up a basic &lt;code class=&quot;highlighter-rouge&quot;&gt;Compose&lt;/code&gt; file. To create a new docker compose file, type:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;touch docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Ok, let’s run it! Type:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Congratulations! You build a docker app that does absolutely nothing! 
For future reference, this is the only command really needed to startup our whole environment.&lt;/p&gt;

&lt;h2 id=&quot;developers-start-your-nginxs&quot;&gt;Developers, start your Nginx’s!&lt;/h2&gt;

&lt;p&gt;For starters, let’s put all of the apps in a new sub-folder called:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir docker-images
cd docker-images
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is the point where I open the folder with VS Code and create any new folder/files in the IDE (I’m personally too lazy to use the Terminal), but I’ll type out the commands so you can be lazy too. 
Now create another folder under &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-images&lt;/code&gt; called &lt;code class=&quot;highlighter-rouge&quot;&gt;nginx&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir nginx
cd nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;At this point, we will create a &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;. This is essentially a script with commands to build and setup a docker image.
&lt;b&gt; Important! there’s no extension. It’s just a file named &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;. &lt;/b&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;touch Dockerfile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now, let’s build out the &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;! Just paste this into the file:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Set nginx base image
FROM nginx:latest

# File Author / Maintainer
MAINTAINER Ermish

# Delete the default configuration
RUN rm -v /etc/nginx/nginx.conf

# Copy custom configuration file from the current directory
COPY nginx.conf /etc/nginx/nginx.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can change the maintainer to your name, username, or your favorite superhero. 
Alright, let’s break this down. 
The &lt;code class=&quot;highlighter-rouge&quot;&gt;FROM&lt;/code&gt; command will pull from &lt;a href=&quot;http://hub.docker.com/&quot;&gt;Docker Hub&lt;/a&gt; by default which is where most public images are located. 
These images are pre-setup on a Linux distro and often configured as good as you could do or better. 
The &lt;code class=&quot;highlighter-rouge&quot;&gt;:latest&lt;/code&gt; tag makes it easy to control the version of the image you want to use and makes it super easy to update your app since someone else did the configuration and compatibility work for you! 
Thanks, bro!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/thanksbro.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 200px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;RUN&lt;/code&gt; Command is used to remove the default Nginx configuration file. 
Finally, the &lt;code class=&quot;highlighter-rouge&quot;&gt;COPY&lt;/code&gt; command is used to copy over our server configuration (hang on, it’s next…). 
If you’re curious why the config settings aren’t in the &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;, this is how we can separate different environment configurations without having to change our docker image.&lt;/p&gt;

&lt;p&gt;Here’s the config file for nginx:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;worker_processes 4;

events { worker_connections 1024; }

http {
        include  /etc/nginx/mime.types;

         upstream nodeapp {
               least_conn;
               server node1:8080 weight=10 max_fails=3 fail_timeout=5s;
               server node2:8080 weight=10 max_fails=3 fail_timeout=5s;
               server node3:8080 weight=10 max_fails=3 fail_timeout=5s;
         }
         
        server {
              listen 80;

              #root /src/static;
              root /data/jekyll_demo;

              location = /favicon.ico { access_log off; log_not_found off; }
              location = /robots.txt  { access_log off; log_not_found off; }
              location = /sitemap.xml { access_log off; log_not_found off; }

             # location ~* \.(png|jpg|jpeg|gif|ico|woff|ttf|svg|eot|otf)$ {
             #     add_header &quot;Access-Control-Allow-Origin&quot; &quot;*&quot;;
             #     expires 1M;
             #     access_log off;
             #     add_header Cache-Control &quot;public&quot;;
             # }

              location ~* /assets/ {
                  add_header &quot;Access-Control-Allow-Origin&quot; &quot;*&quot;;
                  expires 1M;
                  access_log off;
                  add_header Cache-Control &quot;public&quot;;
              }

               location /api/ {
                 proxy_pass http://nodedemo;
                 proxy_http_version 1.1;
                 proxy_set_header Upgrade $http_upgrade;
                 proxy_set_header Connection 'upgrade';
                 proxy_set_header Host $host;
                 proxy_cache_bypass $http_upgrade;
               }

              location ~* / {
                    try_files $uri $uri.html $uri/ =404;
              }
        }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This file allows us to do some serious magic! 
This will allow us to load balance between the three node servers which we will spin up later.
All requests will point to the static files unless the url contains &lt;code class=&quot;highlighter-rouge&quot;&gt;/api/&lt;/code&gt; in which case will be redirected to the node servers. 
At this point there’s no security and everything is public for the static jekyll content. 
For the api/data requests, additional security can be placed within the nodejs api.&lt;/p&gt;

&lt;h2 id=&quot;mongo-and-redis-youre-up&quot;&gt;Mongo and Redis, you’re up!&lt;/h2&gt;

&lt;p&gt;It’s time to make some more folders and Dockerfiles!&lt;/p&gt;

&lt;p&gt;Let’s start with Redis and make another folder and Dockerfile under the &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-images&lt;/code&gt; folder:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ..
mkdir redis
cd redis
touch Dockerfile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now, let’s build out this &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Set the base image to Ubuntu
FROM        ubuntu

# File Author / Maintainer
MAINTAINER Ermish

# Update the repository and install Redis Server
RUN         apt-get update &amp;amp;&amp;amp; apt-get install -y redis-server

# Expose Redis port 6379
EXPOSE      6379

# Run Redis Server
ENTRYPOINT  [&quot;/usr/bin/redis-server&quot;]

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

&lt;p&gt;Hokay so, this is about as default as you can get. We’ll run Redis under the default port &lt;code class=&quot;highlighter-rouge&quot;&gt;6379&lt;/code&gt; and use the default config.
If you need to make custom settings, just copy over a &lt;code class=&quot;highlighter-rouge&quot;&gt;redis.conf&lt;/code&gt; into &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/bin/redis-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Alright, so thing for MongoDB:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ..
mkdir mongodb
cd mongodb
touch Dockerfile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here’s the &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Set the base image to Ubuntu
FROM        ubuntu

# File Author / Maintainer
MAINTAINER Ermish

# Update the repository and install Redis Server
RUN         apt-get update &amp;amp;&amp;amp; apt-get install -y redis-server

# Expose Redis port 6379
EXPOSE      6379

# Run Redis Server
ENTRYPOINT  [&quot;/usr/bin/redis-server&quot;]

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

&lt;p&gt;talk about configuration here&lt;/p&gt;

&lt;h2 id=&quot;node-nodes-time-to-setup-a-nodejs-cluster&quot;&gt;Node Nodes! Time to setup a NodeJs cluster.&lt;/h2&gt;

&lt;p&gt;Same old, same old:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ..
mkdir node
cd node
touch Dockerfile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here’s the &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# latest official node image
FROM node:latest

MAINTAINER Ermish

# Install nodemon
RUN npm install -g nodemon 

# Expose port
EXPOSE  8080

WORKDIR /data/app_node/

# Run app using nodemon
CMD [&quot;nodemon&quot;, &quot;server.js&quot;]

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

&lt;p&gt;So let’s break this dockerfile down:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Pull the latest Node image. This essentially installs npm.&lt;/li&gt;
  &lt;li&gt;Expose our node server port.&lt;/li&gt;
  &lt;li&gt;Point to our code and spin up our Nodemon server! (If you’re wondering what to do with your source code, don’t worry, it’s coming up.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;wait-a-minutewhats-nodemon&quot;&gt;Wait a minute…what’s Nodemon?&lt;/h3&gt;

&lt;p&gt;Nodemon is a node wrapper that is similar to, but can also compliment &lt;a href=&quot;http://www.github.com/foreverjs/forever&quot;&gt;forever&lt;/a&gt;. 
They both essentially serve the purpose of keeping your node server alive. 
The main differences I’ve seen are that Nodemon can watch your files and rebuild the server when you make any changes. 
This is top-notch when you’re doing development! It will also ensure your app doesn’t spin down for any reason, including exceptions getting thrown. 
If the app crashes for any reason, it will retry starting it up to a certain fail count.&lt;/p&gt;

&lt;p&gt;Forever, on the other hand, I think is closer to a production node server wrapper. 
It does almost everything the same minus the file watching/rebuilding.&lt;/p&gt;

&lt;h2 id=&quot;lets-make-a-data-container-together-baby&quot;&gt;Let’s make a data container together, baby!&lt;/h2&gt;

&lt;p&gt;Data containers can be used several different ways. 
Deciding how to setup and use data containers has probably been the toughest decision throughout this setup. 
In this example, I’m using them as containers that hold source code that is compiled outside of the container and checked into souce control already compiled. 
This is the way I can ensure I have the same consistent compiled code base throughout all environments. 
Environment variables, such as connections strings, can be passed into the container without having to change any code.&lt;/p&gt;

&lt;p&gt;Another common data container design is to have the data container be the actual build server. 
It can have a Github hook and compile the code each time a checkin is made.
Having a build server container is awesome, but I think the actual files should still be in a separate container from the build server and rebuilt each time.
I’ll skip the build server in this example.&lt;/p&gt;

&lt;p&gt;There are two common ways to build the data container. One is to create a dockerfile that simply copies the files and creates a docker volume from them.
The other option is to create them directly in the docker compose file which is the method I will be going with.
Some people say that the dockerfile is a good separation of concerns, but since these data containers are only built for this app, I think skipping the dockerfile simplifies things.&lt;/p&gt;

&lt;h2 id=&quot;lets-do-some-composing&quot;&gt;Let’s do some composing&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/composing.jpeg&quot; alt=&quot;Drawing&quot; style=&quot;width: 300px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Remember that command that we ran in the beginning? It looked like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;touch docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Well, it’s time to make that file actually do something! Here’s the file completely built out:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;version: &quot;2&quot;

services:
  node_demo:
    image: busybox:latest
    command: [&quot;true&quot;]
    volumes:
        - ../node_demo/dist:/data/node_demo #for node

  jekyll_demo:
    image: busybox:latest
    command: [&quot;true&quot;]
    volumes:
        - ../jekyll_demo/dist:/data/jekyll_demo #for jekyll

  nginx:
    build: ./images/nginx
    image: dockerdemo_nginx
    env_file: docker_env.env
    ports:
        - 5000:80
    links:
        - node:node1
        - node2:node2
        - node3:node3
    volumes_from:
        - node_demo
        - jekyll_demo

  mongodb:
    build: ./images/mongodb
    image: dockerdemo_mongodb
    env_file: docker_env.env
    ports:
        - 27017:27017
    volumes_from:
        - node_demo
        - jekyll_demo

  redis:
    build: ./images/redis
    image: dockerdemo_redis
    env_file: docker_env.env
    ports:
        - 6379:6379
    volumes_from:
        - node_demo
        - jekyll_demo

  node:
    build: ./images/node
    image: dockerdemo_node
    env_file: docker_env.env
    # ports:
    #      - 5060:8080
    links:
        - mongodb
        - redis
    volumes_from:
        - node_demo
        - jekyll_demo
  node2:
    build: ./images/node
    env_file: docker_env.env
    # ports:
    #      - 5061:8080
    links:
        - mongodb
        - redis
    volumes_from:
        - node_demo
        - jekyll_demo
  node3:
    build: ./images/node
    env_file: docker_env.env
    # ports:
    #      - 5062:8080
    links:
        - mongodb
        - redis
    volumes_from:
        - node_demo
        - jekyll_demo

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

&lt;p&gt;So let’s break this compose file down:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Each of the dockerfiles that we have setup will now be built into an &lt;code class=&quot;highlighter-rouge&quot;&gt;Image&lt;/code&gt; and hosted in a &lt;code class=&quot;highlighter-rouge&quot;&gt;Service&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Let’s talk about those data containers some more. &lt;code class=&quot;highlighter-rouge&quot;&gt;node_demo&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;jekyll_demo&lt;/code&gt; do not have dockerfiles, so essentially we use the same commands here to build an &lt;code class=&quot;highlighter-rouge&quot;&gt;Image&lt;/code&gt;.
    &lt;ul&gt;
      &lt;li&gt;First we build from an image.&lt;/li&gt;
      &lt;li&gt;Docker requires us to run either a &lt;code class=&quot;highlighter-rouge&quot;&gt;Run&lt;/code&gt; command or have an &lt;code class=&quot;highlighter-rouge&quot;&gt;ENTRYPOINT&lt;/code&gt;. So here, we just pass in true for it to do nothing.&lt;/li&gt;
      &lt;li&gt;Then we will create a docker &lt;code class=&quot;highlighter-rouge&quot;&gt;Volume&lt;/code&gt;. I think the easiest way to explain this is to image a volume being a “network drive” for the &lt;code class=&quot;highlighter-rouge&quot;&gt;services&lt;/code&gt;. 
All of the other &lt;code class=&quot;highlighter-rouge&quot;&gt;services&lt;/code&gt; can read/write data from this volume. The way volumes handle data can be tricky and is better explained &lt;a href=&quot;https://docs.docker.com/engine/tutorials/dockervolumes/&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Up next, are the rest of the services. These will use the dockerfiles that we built out earlier. I’ll explain these commands:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Build&lt;/code&gt; builds the dockerfiles we’ve been setting up.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;env_file&lt;/code&gt; passes in any environmental variables you have. (connection strings, localization, etc.)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ports&lt;/code&gt; allows you to forward a port to listen on. 
Important! In this example &lt;code class=&quot;highlighter-rouge&quot;&gt;port 5062:8080&lt;/code&gt;, the right variable points inside the dockerfile. the left variable is the new value in the compose file.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;links&lt;/code&gt; allows one app/dockerfile to be aware of the other. In this example, we want the node servers to have access to the redis server&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;volumes_from&lt;/code&gt; allows access to volumes created by other services/dockerfiles.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ermergerd-it-works&quot;&gt;Ermergerd, it works!&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/ermahgerd.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 200px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That will achieve the same thing as using the docker cli to individually build and setup each service manually/one at a time.
Instead, the docker compose file allows us to “script” out all of these steps in one easy to read file.&lt;/p&gt;

&lt;p&gt;To actually run the compose file do this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will run the services, but soon you will run into issues with cached images and volumes being invalid. 
 As a result, I have a few small shell scripts I run instead that will delete an containers, images, and volumes that exist. 
 Be careful as this essentially wipes anything docker related running on the server! However, this is my favorite part of docker!
 I treat the docker compose file as the exact image of what will be on the server. 
 If I want to spin up any additional servers, I can just run the same compose file again and KNOW it will be identical.&lt;/p&gt;

&lt;p&gt;Here’s the scripts:&lt;/p&gt;

&lt;h3 id=&quot;docker-rebuildsh&quot;&gt;docker-rebuild.sh&lt;/h3&gt;

&lt;p&gt;This script essentially deletes everything, but does not start the server.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# # Delete all containers
docker rm $(docker ps -a -q) --force
# Delete all images
docker rmi $(docker images -q) --force

# #Remove images not in compose file
docker rmi $(docker images -f &quot;dangling=true&quot; -q) 

docker-compose pull
docker-compose build
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;docker-startsh&quot;&gt;docker-start.sh&lt;/h3&gt;

&lt;p&gt;This script just starts the server and builds any images.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker-compose build
docker-compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;docker-stopsh&quot;&gt;docker-stop.sh&lt;/h3&gt;

&lt;p&gt;This script stops the server.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#stop containers
docker stop $(docker ps -a -q)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;awesome-what-about-ci-continuous-integration&quot;&gt;Awesome! What about CI? (continuous integration)&lt;/h2&gt;

&lt;p&gt;There are so many ways to achieve CI with docker. The way I ended up going was to use &lt;a href=&quot;https://hub.docker.com/&quot;&gt;Docker Hub&lt;/a&gt;.
They give you a free private repository! 
Since I had several different containers I wanted to use, I ended up using tags as a way to store different images in the same repository.
Essentially, my CI ended up looking like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Run the docker-rebuild.sh script&lt;/li&gt;
  &lt;li&gt;Tag the images&lt;/li&gt;
  &lt;li&gt;Push these images into my docker hub repository&lt;/li&gt;
  &lt;li&gt;Have docker hub run a script on my server to:
    &lt;ul&gt;
      &lt;li&gt;stop the containers&lt;/li&gt;
      &lt;li&gt;pull down the newly tagged images in my repository&lt;/li&gt;
      &lt;li&gt;rebuild the server&lt;/li&gt;
      &lt;li&gt;start the services again&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the file for pushing the images to docker hub:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker tag mydemoapp_node_demo ermish/mydemoapp:mydemoapp_node_demo
docker tag mydemoapp_jekyll_demo ermish/mydemoapp:mydemoapp_jekyll_demo
docker tag mydemoapp_redis ermish/mydemoapp:mydemoapp_redis
docker tag mydemoapp_node ermish/mydemoapp:mydemoapp_node
docker tag mydemoapp_nginx ermish/mydemoapp:mydemoapp_nginx

docker push ermish/mydemoapp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;thats-all-folks&quot;&gt;That’s all folks!&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;http://www.philipermish.com/assets/thatsallfolks.jpg&quot; alt=&quot;Drawing&quot; style=&quot;width: 500px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoyed the tutorial, and feel free to reach out with any questions!&lt;/p&gt;

</description>
        <pubDate>Sat, 23 Jul 2016 00:00:00 -0700</pubDate>
        <link>http://www.philipermish.com/blog/docker-example-with-nginx-node-redis-mongodb-and-jekyll/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/docker-example-with-nginx-node-redis-mongodb-and-jekyll/</guid>
        
        <category>docker</category>
        
        <category>nginx</category>
        
        <category>node</category>
        
        <category>redis</category>
        
        <category>jekyll</category>
        
        
        <category>docker</category>
        
        <category>nginx</category>
        
        <category>node</category>
        
        <category>redis</category>
        
        <category>jekyll</category>
        
      </item>
    
      <item>
        <title>Why I went with Docker</title>
        <description>&lt;h3 id=&quot;im-a-windows-guy-why-do-i-need-a-linux-server&quot;&gt;I’m a windows guy. Why do I need a Linux server?&lt;/h3&gt;

&lt;p&gt;I love to Windows! I can navigate around pretty well and love having the convenience of a GUI as you’ve probably read &lt;a href=&quot;/blog/commandline-needs-intellisense/&quot;&gt;in my last post&lt;/a&gt;.
Somewhere along the way, I purchased up a Mac and have been stuck in a world between macOs and Windows running in Parallels and on my desktop. Okay, I think I’m getting the hang of this.&lt;/p&gt;

&lt;p&gt;Recently, I’ve been playing a lot with NodeJs and .NET Core. I decided it’s time to change up my hosted web technologies. 
Previously, I was using HostGator for PHP websites (I built my own MVC framework) and it was great for what I was doing at the time.
So taking a look at what would support some of these new toys that I wanted to play with, I’ve realized a VPS sounds like what I wanted but they’re typically expensive.
I stumbled across this place called &lt;a href=&quot;http://www.digitalocean.com/?refcode=802891764c4c&quot;&gt;DigitalOcean&lt;/a&gt;! They can give you an SSD based VPS for $5/month! 
Ok, this sounds great, but there’s a catch. All you start with is a Linux box with a bash terminal. That’s it. No CPanel. No GUI. Nuthin.&lt;/p&gt;

&lt;h3 id=&quot;ive-decided-its-time-to-learn-how-to-setup-a-linux-server&quot;&gt;I’ve decided it’s time to learn how to setup a Linux server!&lt;/h3&gt;

&lt;p&gt;Honestly, I’m not completely new to the Linux game. I’ve been playing with Raspberry Pi’s since they came out, 
but most of the time it’s just been downloading an image or copy/pasting commands without completely knowing what they’re doing.
I’ve decided to look into how to setup a Linux server. I’m used to Windows servers, so how hard can it be?&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;I'm used to Windows servers, so how hard can it be?&lt;/aside&gt;

&lt;p&gt;At first, I had to refresh on some Linux magix. If you’re starting from scratch with Linux, here’s some things I found useful to learn:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Terminal on Mac.
    &lt;ul&gt;
      &lt;li&gt;I was coming from Windows and CommandPrompt, okay?&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Linux distros.
    &lt;ul&gt;
      &lt;li&gt;(Ubuntu, FreeBSD, Fedore, Debian, CoreOS, CentOS, etc.) I personally like Ubuntu for a full environment and CoreOs for more minimalistic setups.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://curl.haxx.se/&quot;&gt;Curl&lt;/a&gt;.
    &lt;ul&gt;
      &lt;li&gt;Basically used for HTTP requests. Personally, I find it useful for pinging sites. (Like ping on Windows)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.debian.org/Apt&quot;&gt;apt&lt;/a&gt;.
    &lt;ul&gt;
      &lt;li&gt;(Similary to NPM, NuGet, Bower, etc, but for linux apps.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s a whole lot of other things to learn, but these are just some of the basics.&lt;/p&gt;

&lt;h3 id=&quot;why-i-went-with-docker&quot;&gt;Why I went with Docker!&lt;/h3&gt;

&lt;p&gt;, I did some research to see how I should setup my server. My options as I saw them were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Setup everything from scratch on a new Linux distro and install all my apps on a single image.&lt;/li&gt;
  &lt;li&gt;Use virtual machines for managing/distributing each of my different apps to run.&lt;/li&gt;
  &lt;li&gt;Use Docker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Long story short, I went with &lt;a href=&quot;htttp://www.docker.com&quot;&gt;Docker&lt;/a&gt;!
My thinking was that, since I don’t know how to perfectly setup everything in Linux, I’m going to make mistakes. 
If it’s all on the same image, I might break something adding each new service and have to start all over. 
I’m quite familiar with VM’s, and I know the performance cost and complexity it brings with it.
This is where Docker seemed to fit the bill!&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;This is where Docker seemed to fit the bill!&lt;/aside&gt;

&lt;p&gt;If I setup each app in a different container, I can get each app working without affecting the others. 
Also, I found some good articles on the &lt;a href=&quot;http://stackoverflow.com/a/26149994/3417143&quot;&gt;performance of Docker vs. VM’s&lt;/a&gt;. 
Also, if you’re using &lt;a href=&quot;http://www.digitalocean.com/?refcode=802891764c4c&quot;&gt;DigitalOcean&lt;/a&gt;, it integrates nicely with Docker and even has an image pre-built for it! Nice!
Sounded good enough for me to try, so I went for it! 
Let me know what experience you’ve had and your thoughts on Docker vs. Virtual Machines. 
If you’re interested in trying out Digital Ocean or you want to support me, click this &lt;a href=&quot;http://www.digitalocean.com/?refcode=802891764c4c&quot;&gt;link&lt;/a&gt;, sign up, and you’ll get $10! That’s two free months!&lt;/p&gt;

</description>
        <pubDate>Tue, 19 Jul 2016 00:00:00 -0700</pubDate>
        <link>http://www.philipermish.com/blog/why-i-went-with-docker/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/why-i-went-with-docker/</guid>
        
        <category>linux</category>
        
        <category>digitalocean</category>
        
        <category>docker</category>
        
        
        <category>linux</category>
        
        <category>digitalocean</category>
        
        <category>docker</category>
        
      </item>
    
      <item>
        <title>Who Am I?</title>
        <description>&lt;h1 id=&quot;hey-internet&quot;&gt;Hey, Internet!&lt;/h1&gt;

&lt;p&gt;My name is Philip Ermish. I earn my keep by making some pretty cool apps and software. 
I’m fortunate that I have a job I absolutely love, and am passionate about. Outside of work, I’m a man of adventure! 
    While some weekends I enjoy a healthy dose of gaming, others, I’m planning my next trip to travel the world. 
    The world is full of adventure and someone (me) needs to explore it!&lt;/p&gt;

&lt;p&gt;If you haven’t notice yet, I’m a pretty positive person! 
The world is often a rough place and many days are difficult, but I believe positivity is a choice. 
It’s all about perspective. I try to find the positive things in whatever situation I encounter. 
You can’t always change your situation, but you can change how you respond to it.&lt;/p&gt;

&lt;p&gt;If I sound like your new best friend, then hit me up on some social media! (Links below) If you’re not a fan, click &lt;a href=&quot;http://www.youtube.com/watch?v=dQw4w9WgXcQ&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;specifically-software&quot;&gt;Specifically software&lt;/h3&gt;

&lt;p&gt;As far as software goes, I’m a full stack developer and love working with C# and all things Javascript. 
If you love open source software, then we’ve got something in common!&lt;/p&gt;

&lt;aside class=&quot;pullquote&quot;&gt;There's power in Simplicity!&lt;/aside&gt;

&lt;p&gt;On the front end, I enjoy building a solid UI and the user experience is extremely important to me. This is where there’s power in simplicity! 
On the flip side of the coin, architecting and building out solid APIs/Services bring a satisfaction in their own way. 
Code maintainability and performance are critical points in my book.&lt;/p&gt;
</description>
        <pubDate>Tue, 19 Jul 2016 00:00:00 -0700</pubDate>
        <link>http://www.philipermish.com/blog/who-am-i/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/who-am-i/</guid>
        
        <category>life</category>
        
        
        <category>life</category>
        
      </item>
    
      <item>
        <title>Command Line Needs Intellisense</title>
        <description>&lt;p&gt;I’ll be one of the first people to say I’d rather click pretty GUI buttons to configure things instead of using a command line such as Command Prompt, Terminal, Bash, etc. 
I get that it’s powerful and a lot easier to manage, but there’s still something to be said about the convenience of clicking with a mouse vs typing a bunch of stuff. 
Have you ever found yourself forgetting a command? What about remembering all the different flags? I know I do. 
I You can easily look them up, but it’s so much easier to find a checkbox.&lt;/p&gt;

&lt;h3 id=&quot;but-it-doesright&quot;&gt;But it does….right?&lt;/h3&gt;

&lt;p&gt;Sure, most command lines have &lt;code class=&quot;highlighter-rouge&quot;&gt;tab + tab&lt;/code&gt; functionality to complete stuff. You can also usually type &lt;code class=&quot;highlighter-rouge&quot;&gt;-help&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;-h&lt;/code&gt; for some hints as well.
This is cool but not exactly what I’m talking about. 
I’m thinking of something similar to your IDE where you get a dropdown with options and a short helpful description of the option and parameters.&lt;/p&gt;

&lt;h3 id=&quot;intellisense-to-the-rescue&quot;&gt;Intellisense to the rescue!&lt;/h3&gt;

&lt;p&gt;How many times have you copied a command from an online source vs. remembering it all and power typing it out?
Commands like &lt;code class=&quot;highlighter-rouge&quot;&gt;sed '/./=' myFile.txt | sed 'N; s/\n/ /'&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;find . -type f -name &quot;*.gz&quot; -exec zgrep 'GET /foo' {} \;&lt;/code&gt; make my eyes water.
Imagine popping up terminal and hitting &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl + Space&lt;/code&gt;, and window pops up with &lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt; as options in it. 
Then when you type &lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt;, the next set of options and would show up. Perhaps, typing &lt;code class=&quot;highlighter-rouge&quot;&gt;-&lt;/code&gt; would show all the flags available.
All of this might be the perfect middle ground between the command line and nice GUIs!&lt;/p&gt;

&lt;h3 id=&quot;cool-concept-but-how-would-you-develop-against-it&quot;&gt;Cool concept, but how would you develop against it?&lt;/h3&gt;

&lt;p&gt;Easy! 
Let’s pretend like we just invented Docker. There would be some &lt;code class=&quot;highlighter-rouge&quot;&gt;.json&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;.yml&lt;/code&gt; configs that the command line would read from. When someone install Docker, it would add a set of command options to this config.
So something like,&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'docker':{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'ps':{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'flags':{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;`a`:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;description:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'This&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;does&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;stuff'&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'run':&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;'build':&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

       &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;its-probably-already-out-there&quot;&gt;It’s probably already out there!&lt;/h3&gt;

&lt;p&gt;If this exists, or it’s being developed, shout it out in the comments below! 
I’ve looked at &lt;a href=&quot;https://www.iterm2.com/&quot;&gt;iTerm&lt;/a&gt; and something other options, but nothing looks exactly like this concept.&lt;/p&gt;
</description>
        <pubDate>Tue, 12 Jul 2016 20:21:22 -0700</pubDate>
        <link>http://www.philipermish.com/blog/commandline-needs-intellisense/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/commandline-needs-intellisense/</guid>
        
        <category>codethoughts</category>
        
        <category>bash</category>
        
        <category>linux</category>
        
        <category>commandline</category>
        
        
        <category>codethoughts</category>
        
        <category>bash</category>
        
        <category>linux</category>
        
        <category>commandline</category>
        
      </item>
    
      <item>
        <title>Hello World</title>
        <description>&lt;p&gt;In honor of the classic developer tradition, this seemed to be appropriate for the first post!&lt;/p&gt;
</description>
        <pubDate>Sun, 10 Jul 2016 20:21:22 -0700</pubDate>
        <link>http://www.philipermish.com/blog/hello-world/</link>
        <guid isPermaLink="true">http://www.philipermish.com/blog/hello-world/</guid>
        
        <category>codethoughts</category>
        
        
        <category>codethoughts</category>
        
      </item>
    
  </channel>
</rss>
