From b08c014fd85a9c4d495adaa947cd8539b5614fb0 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Tue, 22 Nov 2016 16:30:15 +0000 Subject: [PATCH] Updates to Compose getting started guide - Some wording and formatting tweaks - Use Python 3.4, because it's 2016 - Use Alpine-based images for faster downloads and less disk space usage - Use the list form of `CMD` in the Dockerfile, so it's not wrapped in sh - Remove the `depends_on` from `docker-compose.yml`, as it's not really needed - the web app connects to Redis when it's visited, not on startup - Add a section on updating the app and seeing the changes, because that's the point of mounting the code in! - Add a note about `docker-compose down` Signed-off-by: Aanand Prasad --- compose/gettingstarted.md | 155 +++++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 71 deletions(-) diff --git a/compose/gettingstarted.md b/compose/gettingstarted.md index 9f1e12855b..78e03aba2c 100644 --- a/compose/gettingstarted.md +++ b/compose/gettingstarted.md @@ -4,26 +4,25 @@ keywords: documentation, docs, docker, compose, orchestration, containers title: Get started with Docker Compose --- -On this page you build a simple Python web application running on Docker Compose. The -application uses the Flask framework and increments a value in Redis. While the -sample uses Python, the concepts demonstrated here should be understandable even -if you're not familiar with it. +On this page you build a simple Python web application running on Docker +Compose. The application uses the Flask framework and maintains a hit counter in +Redis. While the sample uses Python, the concepts demonstrated here should be +understandable even if you're not familiar with it. ## Prerequisites -Make sure you have already -[installed both Docker Engine and Docker Compose](install.md). You -don't need to install Python, it is provided by a Docker image. +Make sure you have already [installed both Docker Engine and Docker +Compose](install.md). You don't need to install Python or Redis, as both are +provided by Docker images. ## Step 1: Setup -1. Create a directory for the project: +1. Create a directory for the project: $ mkdir composetest $ cd composetest -2. With your favorite text editor create a file called `app.py` in your project - directory. +2. Create a file called `app.py` in your project directory and paste this in: from flask import Flask from redis import Redis @@ -33,82 +32,74 @@ don't need to install Python, it is provided by a Docker image. @app.route('/') def hello(): - redis.incr('hits') - return 'Hello World! I have been seen %s times.' % redis.get('hits') + count = redis.incr('hits') + return 'Hello World! I have been seen {} times.\n'.format(count) if __name__ == "__main__": app.run(host="0.0.0.0", debug=True) -3. Create another file called `requirements.txt` in your project directory and - add the following: +3. Create another file called `requirements.txt` in your project directory and + paste this in: flask redis - These define the applications dependencies. - -## Step 2: Create a Docker image - -In this step, you build a new Docker image. The image contains all the -dependencies the Python application requires, including Python itself. - -1. In your project directory create a file named `Dockerfile` and add the - following: - - FROM python:2.7 - ADD . /code - WORKDIR /code - RUN pip install -r requirements.txt - CMD python app.py - - This tells Docker to: - - * Build an image starting with the Python 2.7 image. - * Add the current directory `.` into the path `/code` in the image. - * Set the working directory to `/code`. - * Install the Python dependencies. - * Set the default command for the container to `python app.py` -
- For more information on how to write Dockerfiles, see the [Docker user guide](/engine/tutorials/dockerimages.md#building-an-image-from-a-dockerfile) and the [Dockerfile reference](/engine/reference/builder.md). -
-2. Build the image. - - $ docker build -t web . - - This command builds an image named `web` from the contents of the current - directory. The command automatically locates the `Dockerfile`, `app.py`, and - `requirements.txt` files. + These define the application's dependencies. -## Step 3: Define services +## Step 2: Create a Dockerfile -Define a set of services using `docker-compose.yml`: +In this step, you write a Dockerfile that builds a Docker image. The image +contains all the dependencies the Python application requires, including Python +itself. -Create a file called docker-compose.yml in your project directory and add - the following: +In your project directory, create a file named `Dockerfile` and paste the +following: + + FROM python:3.4-alpine + ADD . /code + WORKDIR /code + RUN pip install -r requirements.txt + CMD ["python", "app.py"] + +This tells Docker to: + +* Build an image starting with the Python 3.4 image. +* Add the current directory `.` into the path `/code` in the image. +* Set the working directory to `/code`. +* Install the Python dependencies. +* Set the default command for the container to `python app.py` + +For more information on how to write Dockerfiles, see the [Docker user +guide](/engine/tutorials/dockerimages.md#building-an-image-from-a-dockerfile) +and the [Dockerfile reference](/engine/reference/builder.md). - version: '2' - services: - web: - build: . - ports: - - "5000:5000" - volumes: - - .:/code - depends_on: - - redis - redis: - image: redis +## Step 3: Define services in a Compose file + +Create a file called `docker-compose.yml` in your project directory and paste +the following: + + version: '2' + services: + web: + build: . + ports: + - "5000:5000" + volumes: + - .:/code + redis: + image: "redis:alpine" This Compose file defines two services, `web` and `redis`. The web service: -* Builds from the `Dockerfile` in the current directory. -* Forwards the exposed port 5000 on the container to port 5000 on the host machine. -* Mounts the project directory on the host to `/code` inside the container allowing you to modify the code without having to rebuild the image. -* Links the web service to the Redis service. +* Uses an image that's built from the `Dockerfile` in the current directory. +* Forwards the exposed port 5000 on the container to port 5000 on the host + machine. +* Mounts the project directory on the host to `/code` inside the container, + allowing you to modify the code without having to rebuild the image. -The `redis` service uses the latest public +The `redis` service uses a public [Redis](https://registry.hub.docker.com/_/redis/) image pulled from the Docker Hub registry. @@ -160,7 +151,22 @@ containers](../engine/tutorials/dockervolumes.md). The number should increment. -## Step 5: Experiment with some other commands + +## Step 5: Update the application + +Because the application code is mounted into the container using a volume, you +can make changes to its code and see the changes instantly, without having to +rebuild the image. + +1. Change the greeting in `app.py` and save it. For example: + + return 'Hello from Docker! I have been seen {} times.\n'.format(count) + +2. Refresh the app in your browser. The greeting should be updated, and the + counter should still be incrementing. + + +## Step 6: Experiment with some other commands If you want to run your services in the background, you can pass the `-d` flag (for "detached" mode) to `docker-compose up` and use `docker-compose ps` to @@ -169,6 +175,7 @@ see what is currently running: $ docker-compose up -d Starting composetest_redis_1... Starting composetest_web_1... + $ docker-compose ps Name Command State Ports ------------------------------------------------------------------- @@ -179,14 +186,20 @@ The `docker-compose run` command allows you to run one-off commands for your services. For example, to see what environment variables are available to the `web` service: - docker-compose run web env + $ docker-compose run web env See `docker-compose --help` to see other available commands. You can also install [command completion](completion.md) for the bash and zsh shell, which will also show you available commands. If you started Compose with `docker-compose up -d`, you'll probably want to stop your services once you've finished with them: - docker-compose stop + $ docker-compose stop + +You can bring everything down, removing the containers entirely, with the `down` +command. Pass `--volumes` to also remove the data volume used by the Redis +container: + + $ docker-compose down --volumes At this point, you have seen the basics of how Compose works.