Browsing:

Tag: Devops

Docker for impatient newbies part 1: Getting started

If you are one of the few that have not yet taken the plunge into Docker don’t feel ashamed. I haven’t either. I’ve been too busy doing other stuff lately. But yesterday I actually started using Docker because I had a real life use case. I have a Node application that I wanted to ship in a Docker container. And I wanted it quickly.

So here is what you need to package a Node application in a Docker container.

Docker for Mac and Docker for Windows

Step 1 is to install the Docker engine for Mac or Windows. Head over to https://docs.docker.com/engine/installation/mac/ and install Docker for Mac or Docker for Windows.

What happens? You just transformed your machine into a Docker engine. With this Docker engine you can host containers, from images containing your applications.
This is how you get started and start developing. Production environments are better installed in another Docker Engine, somewhere in the cloud or in a datacenter.

Docker on Linux

The Docker Engine on Linux is in its natural habitat and installing it (on Ubuntu Xenial) is as easy as:

sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update
apt-cache policy docker-engine
sudo apt-get install -y docker-engine

sudo usermod -aG docker $USER

First steps

First, check the installation:

docker version

1.12 is the latest version:

Let’s go ahead and create our first image for a Node Express app.

Package a Node.js Express app

Cd into a Node application you want to package, or clone mine. If you clone mine, install Node.js on your platform if you haven’t already. and check if it runs.

git clone https://github.com/jacqinthebox/node-express-starter
cd node-express-starter
npm install
gulp serve

If all is well you will be presented with a static website. The theme is from Black Tie.

First step is to create a Dockerfile.
Assuming you are still in the node-express-starter dir, run:

touch Dockerfile

This will be the folder structure from node-express-starter:

.
├── Dockerfile
├── app
├── bower.json
├── gulpfile.js
├── main.js
├── node_modules
└── package.json

This is how the Dockerfile should look like:

FROM mhart/alpine-node:6.3.0

MAINTAINER Jacqueline

# copy all the files from the Node app to /var/www in the container:
COPY  . /var/www

#set it as workdir
WORKDIR /var/www

#install dependencies from package.json
RUN npm install

# Expose port 3000 from the container to the host
EXPOSE 3000

ENTRYPOINT ["node","app.js"]

What does this mean?

  • FROM: here we need to put the base image for our image. Lots of these images yoy can find on the [Docker Hub](https://hub.docker.com/explore/). I want the image to be as small as possible. So that’s why I’m using an [Alpine](https://github.com/mhart/alpine-node) based image.
  • COPY: I copy all the files from my node project to the /var/www folder on my Docker image
  • WORKDIR: /var/www is the workdir (pwd)
  • RUN: while in /var/www, the npm install is run to install all dependencies of the Node app.
  • EXPOSE: here you can set the port for communication with the outside world. My Node app runs on port 3000
  • ENTRYPOINT: the command ‘node app.js’ will run upon starting the container (not when creating the image of course)

Now create the container image. You should still be in the node-express-starter dir. Run the following command (don’t forget the dot):

docker build -t jacqueline/impatient .

This has created a Docker image with the tag (-t) ‘jacqueline/impatient’.

Now run it

docker run -d -p 8080:3000 jacqueline/impatient

With -d the container instance is ran as a daemon and the -p is the port redirection (3000 we exposed in our image will be forwarded to port 8080)

Now head over to http://localhost :8080 and you should be presented with the Node web application:

Recap:

  • We installed the Docker Engine on our computer
  • We created a Docker image containing our Node app
  • We started an instance of this image

container

Stopping and cleaning up

If you work with containers, lots of harddrive space will be consumed. This is how you clean up stuff.

First, check which containers are currently running with ‘docker ps’:

docker ps

Obviously, the one we just ran is active:
docker
Notice the container ID. You can stop this instance with:

docker stop 45

Next, delete the container. First list all the containers:

docker ps -a

Again, notice the ID:

docker rm 45

Now that the container is deleted, we can go ahead and remove the image. First check which images are present:

docker images

There are 2. I’m only going to remove my own image, not the Alpine one.

docker rmi 78

In the screenshot above notice how I forgot to delete the container, but I could still delete the image with the -f flag.

The End. But will be continued.

Of course now that we took the Docker plunge, we now want to host our container in the cloud. At Digital Ocean, AWS or even Azure. This will be covered in part 2.


Vagrant, Parallels and Windows guests

For all of you running a Mac, this is how to create a Windows guest with Vagrant and Packer.

packer
Packer

Vagrant supports Parallels 8 and higher, but please be aware that Vagrant only supports the Pro version of Parallels 11.

First install the plugin:

vagrant plugin install vagrant-parallels

Second, get the Parallels virtualization SDK here

Third, get Packer and unzip it in your Vagrant dir.

Fourth, clone packer-windows from Github.

git clone https://github.com/joefitzgerald/packer-windows

Now make sure the packer and the packer-windows executables are in the same folder. This makes the command easier because you don’t need to think hard to make sure the paths to all the files and commands are right.

Fifth, download the Windows server iso upfront. I usually download the Windows Server iso first from here so that I don’t have to wait for the download to finish during the packer build process.

Sixth, get this json config file for Parallels. You see that I put the iso from the fifth step on the desktop and reference it in the file.

Seventh, start building and grab coffee

./packer build -var iso_url=~/Desktop/9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_EVAL_EN-US-IRM_SSS_X64FREE_EN-US_DV5.ISO windows_2012_r2_parallels.json 

And another coffee..

Screen Shot 2015-10-07 at 07.02.50

Step eight: add the template to vagrant

vagrant box add --name windows_2012_r2 windows_2012_r2_parallels.box

Step nine: create a Vagrant file

Create a folder named lab01 and put a Vagrantfile in it:

Vagrant.require_version ">= 1.6.2"

$root_provision_script = <<'ROOT_PROVISION_SCRIPT'
& $env:windir\system32\tzutil /s "W. Europe Standard Time"

ROOT_PROVISION_SCRIPT

Vagrant.configure("2") do |config|
    config.vm.define "lab01"
    config.vm.box = "windows_2012_r2"
    config.vm.hostname = "lab01" 
    config.vm.provider :virtualbox do |v, override|
        v.gui = false
        #v.customize ["modifyvm", :id, "--memory", 2048]
        #v.customize ["modifyvm", :id, "--cpus", 2]
    end


    config.vm.network :forwarded_port, guest: 3389, host: 3391, id: "rdp", auto_correct: true
    config.vm.network :forwarded_port, guest: 22, host: 2223, id: "ssh", auto_correct: true
    #config.vm.network "private_network", ip: "192.168.56.11"
    config.vm.provision "shell", inline: $root_provision_script
    #config.vm.provision "shell", path: "sysprep.ps1"
    

end

Then issue a ‘vagrant up’ and we’re done.


Create a lab on Azure with Vagrant and Powershell

If you want to spin up a lab quickly to test things in a Windows environment, you can use an Azure trial account. It is possible to create trial accounts indefinitely so it will cost you nothing. So, let’s go.

For this scenario, I am assuming you are on Windows. By the way, I did the same on a Macbook but instead of Powershell I used the Azure CLI for Mac (runs on Node.js). Check this.

Step 1. Create an Azure trial account

Create a trial account on Azure here.
You will need to supply your credit card info and you should use an mail address that has not been used before for a trial. I am on Google Apps, so I can create mail addresses as much as I like.

Step 2. Install Azure Powershell

You’ll need Azure Powershell to query the available images.
Install the Azure Powershell with the msi (or Web Platform Installer).
I’ve been trying to install the SDK with OneGet, but it seems to be not available.

This gives you a brand new shell.
2015-08-12_09-47-21
 
 
 
 
Not happy with it because it doen’t have a cursor. Let’s fix that:

[Console]::CursorSize = 25

Step 3. Add your Azure credentials

Type

add-AzureAccount

and enter your credentials

add-azure

Next, get the publishsettings.

Get-AzurePublishSettingsFile

add-azure4.

Save your publishsettings (e.g. on c:\temp) and import them:

Import-AzurePublishSettingsFile c:\temp\%your trial account%-credentials.publishsettings

Step 4. Generate certificates

I would advise to use Cmder with msysgit integration, if you don’t already. Cmder is my go to terminal emulator. I use it for Powershell, Git Bash and ordinary DOS. So install Cmder with Chocolatey.

  • First create a pem certificate which is conveniently valid for 10 years. This contains a public key and private key.
  • Then create a pfx certicate based on this pem certifcate.
  • From the pfx, generate a cer to upload to Azure.

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout azurecert.pem -out azurecert.pem

openssl pkcs12 -export -out azurecert.pfx -in azurecert.pem -name "Vagrant Azure Cert"

openssl x509 -inform pem -in azurecert.pem -outform der -out azurecert.cer

Thanks to this article.

Step 5. Upload the cer file to Azure

I can’t figure out how this works with Powershell, so log on to your subscription and add the .cer file:

2015-08-13_06-49-41

First go to settings, then to Management Certificates and upload your .cer file.

cert-blur-bla

Step 6. Install the Vagrant Plugin for Azure

https://github.com/MSOpenTech/vagrant-azure

vagrant plugin install vagrant-azure
vagrant box add azure https://github.com/msopentech/vagrant-azure/raw/master/dummy.box

Now take a look at the Vagrant file for this box. It is located here: C:\Users\yourname\.vagrant.d\boxes\azure\0\azure\Vagrantfile.
In this file you can define some constants that will be applied to every Azure box you create. I’ve changed ‘azure.vm.size’ from ‘Small’ to ‘Medium’ and added ‘azure.vm.location’ = West Europe.

#
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = '2'

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # All Vagrant configuration is done here. The most common configuration
  # options are documented and commented below. For a complete reference,
  # please see the online documentation at vagrantup.com.

  config.vm.provider :azure do |azure|
    azure.vm_size = 'Medium'
    azure.vm_location = 'West Europe' # e.g., West US
  end
end

Step 7. Create a new Vagrant file for your Azure box

Now it’s time to create the Azure Vagrant box. Without much further ado, this is my Vagrantfile:

# --
Vagrant.configure('2') do |config|
    config.vm.box = 'azure'

    config.vm.provider :azure do |azure, override|
        azure.mgmt_certificate = 'insert path to you pem certifcate'
        azure.mgmt_endpoint = 'https://management.core.windows.net'
        azure.subscription_id = 'insert your Azure subscription ID'
        azure.vm_image = 'a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-20150726-en.us-127GB.vhd'
        azure.vm_name = 'box01' # max 15 characters. contains letters, number and hyphens. can start with letters and can end with letters and numbers

        azure.vm_password = 'Vagrant!' # min 8 characters. should contain a lower case letter, an uppercase letter, a number and a special character

        azure.storage_acct_name = 'azureboxesstorage2015' # optional. A new one will be generated if not provided.
        azure.cloud_service_name = 'azureboxes' # same as vm_name. leave blank to auto-generate
        azure.vm_location = 'West Europe' # e.g., West US

    azure.tcp_endpoints = '3389:53390' # opens the Remote Desktop internal port that listens on public port 53389. Without this, you cannot RDP to a Windows VM.
    end
end

The Vagrantfile is of based on the Vagrantfile supplied by https://github.com/MSOpenTech/vagrant-azure.

You can get a list of available Azure VM images by logging on to your Azure subscription with Powershell and issue the following command:


Get-AzureVMImage | where-object { $_.Label -like "Windows Server 2012 R2 *" }| select imagename,imagefamily

Step 8. Vagrant up

Now it’s time to issue a Vagrant up.

This is will generate some error messages because the vm needs to initialize (I assume).

azure-2015-fout

Just issue an vagrant up again until it says: The machine is already created.

Then you can go ahead and RDP into your new VM:

vagrant-rdp-werkt

So there you go, now you are all set to deploy Azure images until the cloud bursts.