In this lab you will be using Docker to deploy an API, initially to a local server and then to the cloud.
Resources:
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
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:
- the
Dockerfile
contains the build script. Study this carefully, noting the build steps. - 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 thenode_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
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:
- Stop the running container
- Delete this container
- Build the new container
- Deploy the container
- 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
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.
- Run the
docker logs todo-live
command to see the buffered terminal information. - If we add the
-f
or--follow
flag we can see the live data.- Run the
docker logs -f todo-live
command. - Try adding items to the list using the website.
- Notice what is displayed in the terminal window.
- Run the
- 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:- The
-i
or--interactive
flag keepsstdin
open. - The
-t
or--tty
flag allocates a pseudo terminal. - If we want to run the bash shell we pass this as the command.
- The
- So to log in and use the bash shell we run the
docker exec -it todo-live /bin/bash
command.- To log out we run
exit
.
- To log out we run
- Improve the appearance of the web page by adding an external stylesheet.
- Redeploy the app to see the improvements.
- Live monitor the logs and try adding and removing items.
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
$
sftp -i /path/to/private/keyfile user@remoteaddress
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
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.
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