docker.rst 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. Run Wagtail CRX with Docker
  2. ===========================
  3. Wagtail CRX runs well in Docker. When working with Docker, there are two
  4. different approaches. This guide will also work with any Wagtail site, or most
  5. types of Django sites.
  6. The first step is to `install Docker`_, on both your development environment
  7. (i.e. your computer) and on your server (hosting) environment.
  8. For the sake of this guide, we will assume your Django project is named
  9. ``myproject``.
  10. .. _install Docker: https://docs.Docker.com/engine/install/
  11. Step 1: Choose How to Use Docker
  12. --------------------------------
  13. The Versioned Image Approach
  14. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  15. The most common way of working with Docker is to create a static Docker image,
  16. containing all of your code, which is effectively versioned in tandem with your
  17. git repository. Each time you change your project code, you also create a new
  18. version of the image. Because this image is effectively static and mirrors
  19. version control, there is no way to store dynamic files such as a database or
  20. media files. In this setup, you would want to use 3rd party services such as AWS
  21. S3 for files, or AWS RDS for database. Nearly all cloud platforms provide
  22. similar services.
  23. Next, create a file in your main project folder named ``Dockerfile`` (no file
  24. extension). Copy the contents below into the file:
  25. .. code-block:: dockerfile
  26. FROM python:latest
  27. ENV PYTHONUNBUFFERED 1
  28. # Set the Django settings to use.
  29. ENV DJANGO_ENV "dev"
  30. ENV DJANGO_SETTINGS_MODULE "myproject.settings.dev"
  31. # Install a WSGI server into the container image.
  32. RUN pip install waitress
  33. # Code will end up living in /app/
  34. WORKDIR /app/
  35. # Copy and install the project requirements.
  36. COPY ./requirements.txt /app/requirements.txt
  37. RUN pip install -r /app/requirements.txt
  38. # Copy the entire project code.
  39. COPY . /app/
  40. # Prepare the app.
  41. RUN python manage.py migrate
  42. RUN python manage.py collectstatic --noinput
  43. # Create a "wagtailcrx" user account to run the app.
  44. RUN useradd wagtailcrx
  45. RUN chown -R wagtailcrx /app/
  46. USER wagtailcrx
  47. # Finally, run the app on port 8000.
  48. EXPOSE 8000
  49. CMD exec waitress serve --listen "*:8000" "myproject.wsgi:application"
  50. The "Image as Environment" Approach
  51. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  52. The second approach is to use the container as the runtime environment, but
  53. store your code and files outside the container. This way you only need to
  54. update the container when you want to change your python version, or apply other
  55. security updates. For those who like to use the filesystem, such as writing
  56. logs, media files, etc. "normally", this is the recommended way to use Docker, as
  57. it will fit within your existing workflow.
  58. First, create a script which will be used as the entry point, meaning it runs
  59. every time the container starts. The entry point will be used to set up the app
  60. each time. Copy the contents below into a filed named ``docker-entrypoint.sh``.
  61. .. code-block:: shell
  62. pip install -r requirements.txt
  63. python manage.py migrate
  64. python manage.py collectstatic --noinput
  65. Next, create a file in your main project folder named ``Dockerfile`` (no file
  66. extension). Copy the contents below into the file:
  67. .. code-block:: Dockerfile
  68. FROM python:latest
  69. ENV PYTHONUNBUFFERED 1
  70. # Set the Django settings to use.
  71. ENV DJANGO_ENV "dev"
  72. ENV DJANGO_SETTINGS_MODULE "myproject.settings.dev"
  73. # Install a WSGI server into the container image.
  74. RUN pip install waitress
  75. # Code will end up living in /app/
  76. WORKDIR /app/
  77. # Create a "wagtailcrx" user account to run the appp.
  78. RUN useradd wagtailcrx
  79. RUN chown -R wagtailcrx /app/
  80. USER wagtailcrx
  81. # Copy our entrypoint script.
  82. COPY ./docker-entrypoint.sh /usr/local/bin/
  83. RUN chmod +x /usr/local/bin/docker-entrypoint.sh
  84. # Finally, run the app on port 8000.
  85. EXPOSE 8000
  86. ENTRYPOINT ["docker-entrypoint.sh"]
  87. CMD exec waitress serve --listen "*:8000" "myproject.wsgi:application"
  88. Step 2: Build Your Image
  89. ------------------------
  90. Next, with Docker running on your machine, create an image by running the
  91. following from your command line, replacing ``/path/to/Dockerfile`` and
  92. ``/path/to/project/`` with the correct paths on your machine.
  93. .. code-block:: console
  94. $ docker build --pull -t myproject:v1 -f /path/to/Dockerfile /path/to/project/
  95. This will likely take a while, as Docker is going to download the ``FROM`` image
  96. (Python in this case) and then run all of those commands in your Dockerfile.
  97. Once complete, this will have created an image named ``myproject`` tagged with
  98. ``v1``. If you are using the "Versioned Image" approach, you would likely want
  99. to change this tag every time you build the image. Docker image tags work
  100. essentially like version control, as such many people choose to use their
  101. current git commit ID as the tag. If you are using the "Image as Environment"
  102. approach, then this tag would likely be your Python version, e.g. ``py3.8.1``
  103. Step 3: Run a Container Using the Image
  104. ---------------------------------------
  105. Now, create a container using the image. If using the "Versioned Image"
  106. approach:
  107. .. code-block:: console
  108. $ docker run --publish 8000:8000 --detach --name myproject-run myproject:v1
  109. If using the "Image as Environment" approach, you also need to map a local
  110. directory on your machine to a directory inside the container. This ensures that
  111. the files that get created or modified are shared between your machine and the
  112. container, and they will remain on your machine after the container is deleted.
  113. The command below runs the container, but before doing so mounts the local directory
  114. ``./`` into the container's ``/app/`` directory:
  115. .. code-block:: console
  116. $ docker run --publish 8000:8000 --detach --name myproject-run --mount type=bind,source=./,target=/app myproject:v1
  117. Either approach will run an instance of your image ``myproject:v1`` named
  118. ``myproject-run``, and map port 8000 on your machine to port 8000 of the
  119. container. Now going to http://localhost:8000 should serve up your app from the
  120. container.
  121. Read the official Docker guide and documentation at:
  122. https://docs.docker.com/get-started/.