Skip to content
Permalink
12b6a7d5ae
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

172 lines (126 sloc) 8.1 KB
# 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](https://drive.google.com/open?id=1FMZmpSx_GyIZ-os_A0eixXd-_dMybXlqY-sAWK05KiQ)
## 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](https://docs.docker.com/install/linux/docker-ce/ubuntu/) [MacOS](https://docs.docker.com/docker-for-mac/install/) and [Windows](https://docs.docker.com/docker-for-windows/install/). 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:
```shell
$ 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.
```shell
$ 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
```shell
$ 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:
```shell
$ 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](https://heroku.com) 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](https://devcenter.heroku.com/articles/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.
```shell
$ 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.
```shell
$ heroku run bash -a marktyers-docker
Running bash on ⬢ johndoe-docker... up, run.4098 (Free)
~ $ exit
$
```
## 4 Deployment Using SFTP
```shell
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.
```shell
$ 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](https://medium.freecodecamp.org/how-to-deploy-a-nodejs-app-to-heroku-from-github-without-installing-heroku-on-your-machine-433bec770efe) that covers this step by step.
## 7 Deploying Using the DPL Tool
The [DPL tool](https://github.com/travis-ci/dpl) was originally developed for use in the [Travis](https://travis-ci.org) 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](https://www.ruby-lang.org/en/) programming language so you need to install a couple of ruby tools first and use these to install the `dpl` tool.
```shell
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
```