|
| 1 | +## 3.0 Run a multi-container app with Docker Compose |
| 2 | +This portion of the tutorial will guide you through the creation and customization of a voting app. It's important that you follow the steps in order, and make sure to customize the portions that are customizable. |
| 3 | + |
| 4 | +**Important.** |
| 5 | +To complete the submission, you will need to have Docker and Docker Compose installed on your machine as mentioned in the [Setup](./setup.md) section. You'll also need to have a [Docker Id](https://hub.docker.com/register/). Once you do run login from the commandline: |
| 6 | + |
| 7 | +``` |
| 8 | +$ docker login |
| 9 | +``` |
| 10 | + |
| 11 | +And follow the login directions. Now you can push images to Docker Hub. |
| 12 | + |
| 13 | +> Note: If you encounter an error response from daemon while attempting to login, you may need to restart your machine by running `docker-machine restart <YOUR_DOCKER_MACHINE_NAME>`. |
| 14 | +
|
| 15 | + |
| 16 | +### 3.1 Get the voting-app |
| 17 | +You now know how to build your own Docker image, so let's take it to the next level and glue things together. For this app you have to run multiple containers and Docker Compose is the best way to do that. |
| 18 | + |
| 19 | +Start by quickly reading the documentation available [here](https://docs.docker.com/compose/overview/). |
| 20 | + |
| 21 | +Clone the voting-app repository already available at [Github Repo](https://github.com/docker/example-voting-app.git). |
| 22 | + |
| 23 | +``` |
| 24 | +git clone https://github.com/docker/example-voting-app.git |
| 25 | +``` |
| 26 | + |
| 27 | +### 3.2 Customize the app |
| 28 | + |
| 29 | +#### 3.2.1 Modify app.py |
| 30 | + |
| 31 | +In the folder ```example-voting-app/voting-app``` you need to edit the app.py and change the two options for the programming languages you chose. |
| 32 | + |
| 33 | +Edit the following lines: |
| 34 | + |
| 35 | +``` |
| 36 | +option_a = os.getenv('OPTION_A', "Java") |
| 37 | +option_b = os.getenv('OPTION_B', "Python") |
| 38 | +``` |
| 39 | + |
| 40 | +substituting two options of your choice. For instance: |
| 41 | + |
| 42 | +``` |
| 43 | +option_a = os.getenv('OPTION_A', "Cats") |
| 44 | +option_b = os.getenv('OPTION_B', "Dogs") |
| 45 | +``` |
| 46 | +#### 3.2.2 Running your app |
| 47 | +Now, run your application. To do that, we'll use [Docker Compose](https://docs.docker.com/compose). Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you define a `.yml` file that describes all the containers and volumes that you want, and the networks between them. In the example-voting-app directory, you'll see a `docker-compose.yml file`: |
| 48 | + |
| 49 | +```yml |
| 50 | +version: "2" |
| 51 | + |
| 52 | +services: |
| 53 | + voting-app: |
| 54 | + build: ./voting-app/. |
| 55 | + volumes: |
| 56 | + - ./voting-app:/app |
| 57 | + ports: |
| 58 | + - "5000:80" |
| 59 | + networks: |
| 60 | + - front-tier |
| 61 | + - back-tier |
| 62 | + |
| 63 | + result-app: |
| 64 | + build: ./result-app/. |
| 65 | + volumes: |
| 66 | + - ./result-app:/app |
| 67 | + ports: |
| 68 | + - "5001:80" |
| 69 | + networks: |
| 70 | + - front-tier |
| 71 | + - back-tier |
| 72 | + |
| 73 | + worker: |
| 74 | + image: manomarks/worker |
| 75 | + networks: |
| 76 | + - back-tier |
| 77 | + |
| 78 | + redis: |
| 79 | + image: redis:alpine |
| 80 | + container_name: redis |
| 81 | + ports: ["6379"] |
| 82 | + networks: |
| 83 | + - back-tier |
| 84 | + |
| 85 | + db: |
| 86 | + image: postgres:9.4 |
| 87 | + container_name: db |
| 88 | + volumes: |
| 89 | + - "db-data:/var/lib/postgresql/data" |
| 90 | + networks: |
| 91 | + - back-tier |
| 92 | + |
| 93 | +volumes: |
| 94 | + db-data: |
| 95 | + |
| 96 | +networks: |
| 97 | + front-tier: |
| 98 | + back-tier: |
| 99 | +``` |
| 100 | +
|
| 101 | +This Compose file defines |
| 102 | +
|
| 103 | +- A voting-app container based on a Python image |
| 104 | +- A result-app container based on a Node.js image |
| 105 | +- A redis container based on a redis image, to temporarily store the data. |
| 106 | +- A Java based worker app based on a Java image |
| 107 | +- A Postgres container based on a postgres image |
| 108 | +
|
| 109 | +Note that three of the containers are built from Dockerfiles, while the other two are images on Docker Hub. To learn more about how they're built, you can examine each of the Dockerfiles in the two directories: `voting-app`, `result-app`. We included the code for the Java worker in `worker` but pre-built the image to save on downloads. |
| 110 | + |
| 111 | +The Compose file also defines two networks, front-tier and back-tier. Each container is placed on one or two networks. Once on those networks, they can access other services on that network in code just by using the name of the service. To learn more about networking check out the [Networking with Compose documentation](https://docs.docker.com/compose/networking/). |
| 112 | + |
| 113 | +To launch your app navigate to the example-voting-app directory and run the following command: |
| 114 | + |
| 115 | +``` |
| 116 | +$ docker-compose up -d |
| 117 | +``` |
| 118 | + |
| 119 | +This tells Compose to start all the containers specified in the `docker-compose.yml` file. The `-d` tells it to run them in daemon mode, in the background. |
| 120 | + |
| 121 | +Last you'll need to figure out the ip address of your Docker host. If you're running Linux, it's just localhost, or 127.0.0.1. If you're using Docker Machine on Mac or Windows, you'll need to run: |
| 122 | + |
| 123 | +``` |
| 124 | +$ docker-machine ip default |
| 125 | +``` |
| 126 | + |
| 127 | +It'll return an IP address. If you only have one Docker Machine running, most likely, that's 192.168.99.100. We'll call that `<YOUR_IP_ADDRESS>`. Navigate to `http://<YOUR_IP_ADDRESS>:5000` in your browser, and you'll see the voting app, something like this: |
| 128 | + |
| 129 | +<img src="../images/vote.png" title="vote"> |
| 130 | + |
| 131 | +Click on one to vote. You can check the results at `http://<YOUR_IP_ADDRESS:5001>`. |
| 132 | + |
| 133 | +**NOTE**: If you are running this tutorial in a cloud environment like AWS, Azure, Digital Ocean, or GCE you will not have direct access to localhost or 127.0.0.1 via a browser. A work around for this is to leverage ssh port forwarding. Below is an example for Mac OS. Similarly this can be done for Windows and Putty users. |
| 134 | + |
| 135 | +``` |
| 136 | +$ ssh -L 5000:localhost:5000 <ssh-user>@<CLOUD_INSTANCE_IP_ADDRESS> |
| 137 | +``` |
| 138 | +
|
| 139 | +#### 3.2.3 Build and tag images |
| 140 | +
|
| 141 | +You are all set now. Navigate to each of the directories where you have a Dockerfile to build and tag your images that you want to submit. |
| 142 | +
|
| 143 | +In order to build the images, make sure to replace `<YOUR_DOCKER_ID>` with your *Docker Hub username* in the following commands: |
| 144 | +
|
| 145 | +``` |
| 146 | +$ docker build --no-cache -t <YOUR_DOCKER_ID>/votingapp_voting-app . |
| 147 | +... |
| 148 | +$ docker build --no-cache -t <YOUR_DOCKER_ID>/votingapp_result-app . |
| 149 | +... |
| 150 | +$ docker build --no-cache -t <YOUR_DOCKER_ID>/votingapp_worker . |
| 151 | +``` |
| 152 | +
|
| 153 | +#### 3.2.4 Push images to Docker Hub |
| 154 | +
|
| 155 | +Push the images to Docker hub. Remember, you must have run `docker login` before you can push. |
| 156 | +
|
| 157 | +``` |
| 158 | +$ docker push <YOUR_DOCKER_ID>/votingapp_voting-app |
| 159 | +... |
| 160 | +$ docker push <YOUR_DOCKER_ID>/votingapp_result-app |
| 161 | +... |
| 162 | +$ docker push <YOUR_DOCKER_ID>/votingapp_worker |
| 163 | +``` |
| 164 | +
|
| 165 | +Now you can access these images anywhere by running |
| 166 | +
|
| 167 | +``` |
| 168 | +$ docker pull <YOUR_DOCKER_ID>/votingapp_voting-app |
| 169 | +$ docker pull <YOUR_DOCKER_ID>/votingapp_result-app |
| 170 | +$ docker pull <YOUR_DOCKER_ID>/votingapp_worker |
| 171 | +``` |
| 172 | +
|
| 173 | +### 3.3 Next steps |
| 174 | +Now that you've built some images and pushed them to hub, and learned about Docker Compose, you can explore more of Docker by checking out [the documentation](https://docs.docker.com). And if you need any help, check out the [Docker Forums](forums.docker.com) or [StackOverflow](https://stackoverflow.com/tags/docker/). |
0 commit comments