Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
1 contributor

Users who have contributed to this file

Docker and Deployment

In this lab you will be using Docker to deploy an API, initially to a local server and then to the cloud.

Resources:

  1. Lecture slides

1 Installation

Before you start this lab you need to make sure you have Docker CE (community edition) installed and running. There are detailed instructions for Ubuntu MacOS and Windows. There are also instructions for a number of other Linux distros.

The installation process will install three commands. Once you have completed the installation you can check that these are installed and the version you are using:

$ docker --version
  Docker version 18.06.1-ce, build e68fc7a
$ docker-compose --version
  docker-compose version 1.22.0, build f46880f
$ docker-machine --version
  docker-machine version 0.15.0, build b48dc28d

2 Dockerfiles

In this part of the lab you will be learning how to auto build and deploy a nodeJS app using a Dockerfile. Start by navigating to the exercises/07_docker/01_dockerfile/ directory. Notice that this is the standard todo web app. You will also see two extra files:

  1. the Dockerfile contains the build script. Study this carefully, noting the build steps.
  2. the .dockerignore file lists the files we don't want transferring to our docker container. In our instance we don't want to upload the contents of the node_modules/ directory.
$ docker build -t todo .
$ docker image ls -a
$ docker run --name todo-live -p 88:8080 -d todo
$ docker container ls -a
  CONTAINER ID  IMAGE  COMMAND      STATUS        PORTS                 NAMES
  6fd6a80fb4ae  todo   "npm start"  Up 4 seconds  0.0.0.0:88->8080/tcp  todo-live

you can now access the todo app on http://localhost:88

2.1 Redeploying a Container

When changes are made to your application we need to redeploy the entire container. Since each step in the build process created an interim image, the build can skip over any steps that have not changed. In this case, the first step that is changed is where we copy over the files (since these were edited). Once the build finds a changed step it has to rebuild from this point. This is why we copied over the manifest files and installed the dependencies before we copied over the rest of the files.

The process of building and redeploying the new container is:

  1. Stop the running container
  2. Delete this container
  3. Build the new container
  4. Deploy the container
  5. Remove (prune) any unused image files
$ docker container ls -a
$ docker stop todo-live
$ docker container ls -a
$ CONTAINER ID  IMAGE  COMMAND      STATUS      PORTS                 NAMES
  6fd6a80fb4ae  todo   "npm start"  Exited (0)  0.0.0.0:88->8080/tcp  todo-live
$ docker rm $(docker ps -a -q)
$ docker build -t todo .
$ docker run --name todo-live -p 88:8080 -d todo
$ docker image ls
$ docker image prune -f

Since this is such a common task you might want to write a shell script to automate the process or simply chain the commands together. There are a couple of steps we can remove so there are now only 4 steps:

$ docker build -t todo .
$ docker image prune -f
$ docker rm -f $(docker ps -a -q)
$ docker run --name todo-live -p 88:8080 -d todo

2.2 Interacting with Docker Containers

In this section you will be connecting to the running container. This will allow you to debug your code by displaying the information you would normally see in the terminal.

  1. Run the docker logs todo-live command to see the buffered terminal information.
  2. If we add the -f or --follow flag we can see the live data.
    1. Run the docker logs -f todo-live command.
    2. Try adding items to the list using the website.
    3. Notice what is displayed in the terminal window.
  3. The docker exec COMMAND command allows you to run a command in a live container. If you want to connect to the bash shell you need to provide some additional arguments:
    1. The -i or --interactive flag keeps stdin open.
    2. The -t or --tty flag allocates a pseudo terminal.
    3. If we want to run the bash shell we pass this as the command.
  4. So to log in and use the bash shell we run the docker exec -it todo-live /bin/bash command.
    1. To log out we run exit.

2.3 Test Your Understanding

  1. Improve the appearance of the web page by adding an external stylesheet.
  2. Redeploy the app to see the improvements.
  3. Live monitor the logs and try adding and removing items.

3 Deploying to the Cloud

Now we have the image runnign in a container on a local virtual machine (VM) we should be able to deploy it to the cloud. In this tutorial you will be deploying to Heroku which provides hosting for up to 5 docker containers for free. Make sure you have an account and are logged into the dashboard.

Deployment will make use of the Heroku CLI which should be downloaded and installed.

We atart by using this tool to log into Heroku. We can then containerise and push our Docker image to the cloud. For the application name include your username.

The first time it needs to upload all the docker images including the intermediate ones but for future updates it only needs to start uploading from the point where the image has changed. This makes it critical to design your Dockerfile in the optimal sequence with the parts that are likely to change towards the end of the script.

$ heroku login
  Enter your Heroku credentials:
  Email: johndoe@gmail.com
  Password: *********
  Logged in as johndoe@gmail.com
$ heroku create johndoe-docker
  Creating ⬢ johndoe-docker... done
  https://johndoe-docker.herokuapp.com/ | https://git.heroku.com/johndoe-docker.git
$ heroku auth:token
$ docker login --username=_ --password=e014b137-4166-4e1c-8714-047ba6954e4f registry.heroku.com
$ heroku container:login
$ docker build -t registry.heroku.com/marktyers-docker/web .
$ docker push registry.heroku.com/marktyers-docker/web
$ heroku container:release -a johndoe-docker web
  Releasing images web to johndoe-docker... done
$ heroku open -a johndoe-docker

If you experiece any issues you can SSH into a running container on Heroku using heroku run bash -a johndoe-docker, substituting your heroku app name. To close the SSH connection you use the exit command.

$ heroku run bash -a marktyers-docker
  Running bash on ⬢ johndoe-docker... up, run.4098 (Free)
~ $ exit
$

4 Deployment Using SFTP

sftp -i /path/to/private/keyfile user@remoteaddress

5 Deployment Using RSync

6 Deployment Using Git

When you create a new Heroku instance it automatically installs a headless version of git and configures the appropriate git hook (post-receive). Heroku provides the appropriate remote URL in the terminal so all you need to do is add this as a new remote and push.

The heroku open command opens the app in your default browser.

$ heroku create johndoe-git
$ git push heroku master
$ heroku open
$ heroku run bash

6.1 Deploying Directly From GitHub

There is an alternative approach which is to deploy directly from GitHub. This process can be triggered by pushing commits to your repository. There is a very easy to follow tutorial that covers this step by step.

7 Deploying Using the DPL Tool

The DPL tool was originally developed for use in the Travis CI tool but can be employed as a general purpose deployment tool and works well with Heroku.

The DPL tool is written in the Ruby programming language so you need to install a couple of ruby tools first and use these to install the dpl tool.

apt-get install -y ruby ruby-dev rubygems-integration
gem install dpl
dpl --provider=heroku --app=johndoe-dpl --api-key=95023c27-5a9d-4250-a3fd-d2e19e0dac02