Merge pull request #4145 from SvenDowideit/redo-python-example

touch up the examples
This commit is contained in:
Andy Rothfusz 2014-02-18 11:08:45 -08:00
commit c14c539c6c
3 changed files with 110 additions and 86 deletions

View file

@ -2,11 +2,6 @@
:description: A simple hello world example with Docker
:keywords: docker, example, hello world
.. _examples:
Hello World
-----------
.. _running_examples:
Check your Docker install
@ -18,7 +13,7 @@ your Docker install, run the following command:
.. code-block:: bash
# Check that you have a working install
docker info
$ sudo docker info
If you get ``docker: command not found`` or something like
``/var/lib/docker/repositories: permission denied`` you may have an incomplete
@ -30,27 +25,28 @@ Please refer to :ref:`installation_list` for installation instructions.
.. _hello_world:
Hello World
===========
-----------
.. include:: example_header.inc
This is the most basic example available for using Docker.
Download the base image which is named ``ubuntu``:
Download the small base image named ``busybox``:
.. code-block:: bash
# Download an ubuntu image
sudo docker pull ubuntu
# Download a busybox image
$ sudo docker pull busybox
Alternatively to the ``ubuntu`` image, you can select ``busybox``, a bare
minimal Linux system. The images are retrieved from the Docker
repository.
The ``busybox`` image is a minimal Linux system. You can do the same
with any number of other images, such as ``debian``, ``ubuntu`` or ``centos``.
The images can be found and retrieved using the `Docker index`_.
.. _Docker index: http://index.docker.io
.. code-block:: bash
sudo docker run ubuntu /bin/echo hello world
$ sudo docker run busybox /bin/echo hello world
This command will run a simple ``echo`` command, that will echo ``hello world`` back to the console over standard out.
@ -58,7 +54,7 @@ This command will run a simple ``echo`` command, that will echo ``hello world``
- **"sudo"** execute the following commands as user *root*
- **"docker run"** run a command in a new container
- **"ubuntu"** is the image we want to run the command inside of.
- **"busybox"** is the image we are running the command in.
- **"/bin/echo"** is the command we want to run in the container
- **"hello world"** is the input for the echo command
@ -73,8 +69,8 @@ See the example in action
<iframe width="560" height="400" frameborder="0"
sandbox="allow-same-origin allow-scripts"
srcdoc="<body><script type=&quot;text/javascript&quot;
src=&quot;https://asciinema.org/a/2603.js&quot;
id=&quot;asciicast-2603&quot; async></script></body>">
src=&quot;https://asciinema.org/a/7658.js&quot;
id=&quot;asciicast-7658&quot; async></script></body>">
</iframe>
----
@ -82,7 +78,7 @@ See the example in action
.. _hello_world_daemon:
Hello World Daemon
==================
------------------
.. include:: example_header.inc
@ -172,14 +168,14 @@ See the example in action
id=&quot;asciicast-2562&quot; async></script></body>">
</iframe>
The next example in the series is a :ref:`python_web_app` example, or
The next example in the series is a :ref:`nodejs_web_app` example, or
you could skip to any of the other examples:
* :ref:`python_web_app`
* :ref:`nodejs_web_app`
* :ref:`running_redis_service`
* :ref:`running_ssh_service`
* :ref:`running_couchdb_service`
* :ref:`postgresql_service`
* :ref:`mongodb_image`
* :ref:`python_web_app`

View file

@ -16,7 +16,6 @@ to more substantial services like those which you might find in production.
:maxdepth: 1
hello_world
python_web_app
nodejs_web_app
running_redis_service
running_ssh_service
@ -26,3 +25,4 @@ to more substantial services like those which you might find in production.
running_riak_service
using_supervisord
cfengine_process_management
python_web_app

View file

@ -9,109 +9,137 @@ Python Web App
.. include:: example_header.inc
The goal of this example is to show you how you can author your own
Docker images using a parent image, making changes to it, and then
saving the results as a new image. We will do that by making a simple
hello Flask web application image.
While using Dockerfiles is the preferred way to create maintainable
and repeatable images, its useful to know how you can try things out
and then commit your live changes to an image.
**Steps:**
The goal of this example is to show you how you can modify your own
Docker images by making changes to a running
container, and then saving the results as a new image. We will do
that by making a simple 'hello world' Flask web application image.
Download the initial image
--------------------------
Download the ``shykes/pybuilder`` Docker image from the ``http://index.docker.io``
registry.
This image contains a ``buildapp`` script to download the web app and then ``pip install``
any required modules, and a ``runapp`` script that finds the ``app.py`` and runs it.
.. _`shykes/pybuilder`: https://github.com/shykes/pybuilder
.. code-block:: bash
sudo docker pull shykes/pybuilder
$ sudo docker pull shykes/pybuilder
We are downloading the ``shykes/pybuilder`` Docker image
.. note:: This container was built with a very old version of docker
(May 2013 - see `shykes/pybuilder`_ ), when the ``Dockerfile`` format was different,
but the image can still be used now.
Interactively make some modifications
-------------------------------------
We then start a new container running interactively using the image.
First, we set a ``URL`` variable that points to a tarball of a simple
helloflask web app, and then we run a command contained in the image called
``buildapp``, passing it the ``$URL`` variable. The container is
given a name ``pybuilder_run`` which we will use in the next steps.
While this example is simple, you could run any number of interactive commands,
try things out, and then exit when you're done.
.. code-block:: bash
URL=http://github.com/shykes/helloflask/archive/master.tar.gz
$ sudo docker run -i -t -name pybuilder_run shykes/pybuilder bash
We set a ``URL`` variable that points to a tarball of a simple helloflask web app
.. code-block:: bash
BUILD_JOB=$(sudo docker run -d -t shykes/pybuilder:latest /usr/local/bin/buildapp $URL)
Inside of the ``shykes/pybuilder`` image there is a command called
``buildapp``, we are running that command and passing the ``$URL`` variable
from step 2 to it, and running the whole thing inside of a new
container. The ``BUILD_JOB`` environment variable will be set with the new container ID.
.. code-block:: bash
sudo docker attach -sig-proxy=false $BUILD_JOB
$$ URL=http://github.com/shykes/helloflask/archive/master.tar.gz
$$ /usr/local/bin/buildapp $URL
[...]
$$ exit
While this container is running, we can attach to the new container to
see what is going on. The flag ``--sig-proxy`` set as ``false`` allows you to connect and
disconnect (Ctrl-C) to it without stopping the container.
.. code-block:: bash
sudo docker ps -a
List all Docker containers. If this container has already finished
running, it will still be listed here.
.. code-block:: bash
BUILD_IMG=$(sudo docker commit $BUILD_JOB _/builds/github.com/shykes/helloflask/master)
Commit the container to create a new image
------------------------------------------
Save the changes we just made in the container to a new image called
``_/builds/github.com/hykes/helloflask/master`` and save the image ID in
the ``BUILD_IMG`` variable name.
``/builds/github.com/shykes/helloflask/master``. You now have 3 different
ways to refer to the container: name ``pybuilder_run``, short-id ``c8b2e8228f11``, or
long-id ``c8b2e8228f11b8b3e492cbf9a49923ae66496230056d61e07880dc74c5f495f9``.
.. code-block:: bash
WEB_WORKER=$(sudo docker run -d -p 5000 $BUILD_IMG /usr/local/bin/runapp)
$ sudo docker commit pybuilder_run /builds/github.com/shykes/helloflask/master
c8b2e8228f11b8b3e492cbf9a49923ae66496230056d61e07880dc74c5f495f9
Run the new image to start the web worker
-----------------------------------------
Use the new image to create a new container with
network port 5000 mapped to a local port
.. code-block:: bash
$ sudo docker run -d -p 5000 --name web_worker /builds/github.com/shykes/helloflask/master /usr/local/bin/runapp
- **"docker run -d "** run a command in a new container. We pass "-d"
so it runs as a daemon.
- **"-p 5000"** the web app is going to listen on this port, so it
must be mapped from the container to the host system.
- **"$BUILD_IMG"** is the image we want to run the command inside of.
- **/usr/local/bin/runapp** is the command which starts the web app.
Use the new image we just created and create a new container with
network port 5000, and return the container ID and store in the
``WEB_WORKER`` variable.
.. code-block:: bash
View the container logs
-----------------------
sudo docker logs $WEB_WORKER
* Running on http://0.0.0.0:5000/
View the logs for the new container using the ``WEB_WORKER`` variable, and
View the logs for the new ``web_worker`` container and
if everything worked as planned you should see the line ``Running on
http://0.0.0.0:5000/`` in the log output.
To exit the view without stopping the container, hit Ctrl-C, or open another
terminal and continue with the example while watching the result in the logs.
.. code-block:: bash
WEB_PORT=$(sudo docker port $WEB_WORKER 5000 | awk -F: '{ print $2 }')
$ sudo docker logs -f web_worker
* Running on http://0.0.0.0:5000/
See the webapp output
---------------------
Look up the public-facing port which is NAT-ed. Find the private port
used by the container and store it inside of the ``WEB_PORT`` variable.
.. code-block:: bash
# install curl if necessary, then ...
curl http://127.0.0.1:$WEB_PORT
Hello world!
Access the web app using the ``curl`` binary. If everything worked as planned you
should see the line ``Hello world!`` inside of your console.
**Video:**
.. code-block:: bash
See the example in action
$ WEB_PORT=$(sudo docker port web_worker 5000 | awk -F: '{ print $2 }')
.. raw:: html
# install curl if necessary, then ...
$ curl http://127.0.0.1:$WEB_PORT
Hello world!
<iframe width="720" height="400" frameborder="0"
sandbox="allow-same-origin allow-scripts"
srcdoc="<body><script type=&quot;text/javascript&quot;
src=&quot;https://asciinema.org/a/2573.js&quot;
id=&quot;asciicast-2573&quot; async></script></body>">
</iframe>
Continue to :ref:`running_ssh_service`.
Clean up example containers and images
--------------------------------------
.. code-block:: bash
$ sudo docker ps --all
List ``--all`` the Docker containers. If this container had already finished
running, it will still be listed here with a status of 'Exit 0'.
.. code-block:: bash
$ sudo docker stop web_worker
$ sudo docker rm web_worker pybuilder_run
$ sudo docker rmi /builds/github.com/shykes/helloflask/master shykes/pybuilder:latest
And now stop the running web worker, and delete the containers, so that we can
then delete the images that we used.