python_web_app.rst 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. :title: Python Web app example
  2. :description: Building your own python web app using docker
  3. :keywords: docker, example, python, web app
  4. .. _python_web_app:
  5. Python Web App
  6. ==============
  7. .. include:: example_header.inc
  8. While using Dockerfiles is the preferred way to create maintainable
  9. and repeatable images, its useful to know how you can try things out
  10. and then commit your live changes to an image.
  11. The goal of this example is to show you how you can modify your own
  12. Docker images by making changes to a running
  13. container, and then saving the results as a new image. We will do
  14. that by making a simple 'hello world' Flask web application image.
  15. Download the initial image
  16. --------------------------
  17. Download the ``shykes/pybuilder`` Docker image from the ``http://index.docker.io``
  18. registry.
  19. This image contains a ``buildapp`` script to download the web app and then ``pip install``
  20. any required modules, and a ``runapp`` script that finds the ``app.py`` and runs it.
  21. .. _`shykes/pybuilder`: https://github.com/shykes/pybuilder
  22. .. code-block:: bash
  23. $ sudo docker pull shykes/pybuilder
  24. .. note:: This container was built with a very old version of docker
  25. (May 2013 - see `shykes/pybuilder`_ ), when the ``Dockerfile`` format was different,
  26. but the image can still be used now.
  27. Interactively make some modifications
  28. -------------------------------------
  29. We then start a new container running interactively using the image.
  30. First, we set a ``URL`` variable that points to a tarball of a simple
  31. helloflask web app, and then we run a command contained in the image called
  32. ``buildapp``, passing it the ``$URL`` variable. The container is
  33. given a name ``pybuilder_run`` which we will use in the next steps.
  34. While this example is simple, you could run any number of interactive commands,
  35. try things out, and then exit when you're done.
  36. .. code-block:: bash
  37. $ sudo docker run -i -t -name pybuilder_run shykes/pybuilder bash
  38. $$ URL=http://github.com/shykes/helloflask/archive/master.tar.gz
  39. $$ /usr/local/bin/buildapp $URL
  40. [...]
  41. $$ exit
  42. Commit the container to create a new image
  43. ------------------------------------------
  44. Save the changes we just made in the container to a new image called
  45. ``/builds/github.com/shykes/helloflask/master``. You now have 3 different
  46. ways to refer to the container: name ``pybuilder_run``, short-id ``c8b2e8228f11``, or
  47. long-id ``c8b2e8228f11b8b3e492cbf9a49923ae66496230056d61e07880dc74c5f495f9``.
  48. .. code-block:: bash
  49. $ sudo docker commit pybuilder_run /builds/github.com/shykes/helloflask/master
  50. c8b2e8228f11b8b3e492cbf9a49923ae66496230056d61e07880dc74c5f495f9
  51. Run the new image to start the web worker
  52. -----------------------------------------
  53. Use the new image to create a new container with
  54. network port 5000 mapped to a local port
  55. .. code-block:: bash
  56. $ sudo docker run -d -p 5000 --name web_worker /builds/github.com/shykes/helloflask/master /usr/local/bin/runapp
  57. - **"docker run -d "** run a command in a new container. We pass "-d"
  58. so it runs as a daemon.
  59. - **"-p 5000"** the web app is going to listen on this port, so it
  60. must be mapped from the container to the host system.
  61. - **/usr/local/bin/runapp** is the command which starts the web app.
  62. View the container logs
  63. -----------------------
  64. View the logs for the new ``web_worker`` container and
  65. if everything worked as planned you should see the line ``Running on
  66. http://0.0.0.0:5000/`` in the log output.
  67. To exit the view without stopping the container, hit Ctrl-C, or open another
  68. terminal and continue with the example while watching the result in the logs.
  69. .. code-block:: bash
  70. $ sudo docker logs -f web_worker
  71. * Running on http://0.0.0.0:5000/
  72. See the webapp output
  73. ---------------------
  74. Look up the public-facing port which is NAT-ed. Find the private port
  75. used by the container and store it inside of the ``WEB_PORT`` variable.
  76. Access the web app using the ``curl`` binary. If everything worked as planned you
  77. should see the line ``Hello world!`` inside of your console.
  78. .. code-block:: bash
  79. $ WEB_PORT=$(sudo docker port web_worker 5000 | awk -F: '{ print $2 }')
  80. # install curl if necessary, then ...
  81. $ curl http://127.0.0.1:$WEB_PORT
  82. Hello world!
  83. Clean up example containers and images
  84. --------------------------------------
  85. .. code-block:: bash
  86. $ sudo docker ps --all
  87. List ``--all`` the Docker containers. If this container had already finished
  88. running, it will still be listed here with a status of 'Exit 0'.
  89. .. code-block:: bash
  90. $ sudo docker stop web_worker
  91. $ sudo docker rm web_worker pybuilder_run
  92. $ sudo docker rmi /builds/github.com/shykes/helloflask/master shykes/pybuilder:latest
  93. And now stop the running web worker, and delete the containers, so that we can
  94. then delete the images that we used.