|
| 1 | +# Quickstart: Compose and Django |
| 2 | + |
| 3 | +This quick-start guide demonstrates how to use Docker Compose to set up and run a simple Django/PostgreSQL app. Before starting, |
| 4 | +[install Compose](https://docs.docker.com/compose/install/). |
| 5 | + |
| 6 | +## Define the project components |
| 7 | + |
| 8 | +For this project, you need to create a Dockerfile, a Python dependencies file, |
| 9 | +and a `docker-compose.yml` file. (You can use either a `.yml` or `.yaml` extension for this file.) |
| 10 | + |
| 11 | +1. Create an empty project directory. |
| 12 | + |
| 13 | + You can name the directory something easy for you to remember. This directory is the context for your application image. The directory should only contain resources to build that image. |
| 14 | + |
| 15 | +2. Create a new file called `Dockerfile` in your project directory. |
| 16 | + |
| 17 | + The Dockerfile defines an application's image content via one or more build |
| 18 | + commands that configure that image. Once built, you can run the image in a |
| 19 | + container. For more information on `Dockerfile`, see the [Docker user guide](https://docs.docker.com/get-started/) |
| 20 | + and the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/). |
| 21 | + |
| 22 | +3. Add the following content to the `Dockerfile`. |
| 23 | + |
| 24 | + ```dockerfile |
| 25 | + # syntax=docker/dockerfile:1 |
| 26 | + FROM python:3 |
| 27 | + ENV PYTHONDONTWRITEBYTECODE=1 |
| 28 | + ENV PYTHONUNBUFFERED=1 |
| 29 | + WORKDIR /code |
| 30 | + COPY requirements.txt /code/ |
| 31 | + RUN pip install -r requirements.txt |
| 32 | + COPY . /code/ |
| 33 | + ``` |
| 34 | + |
| 35 | + This `Dockerfile` starts with a [Python 3 parent image](https://hub.docker.com/r/library/python/tags/3/). |
| 36 | + The parent image is modified by adding a new `code` directory. The parent image is further modified |
| 37 | + by installing the Python requirements defined in the `requirements.txt` file. |
| 38 | + |
| 39 | +4. Save and close the `Dockerfile`. |
| 40 | + |
| 41 | +5. Create a `requirements.txt` in your project directory. |
| 42 | + |
| 43 | + This file is used by the `RUN pip install -r requirements.txt` command in your `Dockerfile`. |
| 44 | + |
| 45 | +6. Add the required software in the file. |
| 46 | + |
| 47 | + ```python |
| 48 | + Django>=3.0,<4.0 |
| 49 | + psycopg2>=2.8 |
| 50 | + ``` |
| 51 | + |
| 52 | +7. Save and close the `requirements.txt` file. |
| 53 | + |
| 54 | +8. Create a file called `docker-compose.yml` in your project directory. |
| 55 | + |
| 56 | + The `docker-compose.yml` file describes the services that make your app. In |
| 57 | + this example those services are a web server and database. The compose file |
| 58 | + also describes which Docker images these services use, how they link |
| 59 | + together, any volumes they might need to be mounted inside the containers. |
| 60 | + Finally, the `docker-compose.yml` file describes which ports these services |
| 61 | + expose. See the [`docker-compose.yml` reference](https://docs.docker.com/compose/compose-file/) for more |
| 62 | + information on how this file works. |
| 63 | + |
| 64 | +9. Add the following configuration to the file. |
| 65 | + |
| 66 | + ```yaml |
| 67 | + services: |
| 68 | + db: |
| 69 | + image: postgres |
| 70 | + volumes: |
| 71 | + - ./data/db:/var/lib/postgresql/data |
| 72 | + environment: |
| 73 | + - POSTGRES_DB=postgres |
| 74 | + - POSTGRES_USER=postgres |
| 75 | + - POSTGRES_PASSWORD=postgres |
| 76 | + web: |
| 77 | + build: . |
| 78 | + command: python manage.py runserver 0.0.0.0:8000 |
| 79 | + volumes: |
| 80 | + - .:/code |
| 81 | + ports: |
| 82 | + - "8000:8000" |
| 83 | + environment: |
| 84 | + - POSTGRES_NAME=postgres |
| 85 | + - POSTGRES_USER=postgres |
| 86 | + - POSTGRES_PASSWORD=postgres |
| 87 | + depends_on: |
| 88 | + - db |
| 89 | + ``` |
| 90 | + |
| 91 | + This file defines two services: The `db` service and the `web` service. |
| 92 | + |
| 93 | + > Note: |
| 94 | + > |
| 95 | + > This uses the build in development server to run your application |
| 96 | + > on port 8000. Do not use this in a production environment. For more |
| 97 | + > information, see [Django documentation](https://docs.djangoproject.com/en/3.1/intro/tutorial01/#the-development-server){: target="_blank" rel="noopener" class="_”}. |
| 98 | + |
| 99 | +10. Save and close the `docker-compose.yml` file. |
| 100 | + |
| 101 | +## Create a Django project |
| 102 | + |
| 103 | +In this step, you create a Django starter project by building the image from the build context defined in the previous procedure. |
| 104 | + |
| 105 | +1. Change to the root of your project directory. |
| 106 | + |
| 107 | +2. Create the Django project by running the [docker compose run](https://docs.docker.com/engine/reference/commandline/compose_run/) |
| 108 | + command as follows. |
| 109 | + |
| 110 | + ```console |
| 111 | + sudo docker compose run web django-admin startproject composeexample . |
| 112 | + ``` |
| 113 | + |
| 114 | + This instructs Compose to run `django-admin startproject composeexample` |
| 115 | + in a container, using the `web` service's image and configuration. Because |
| 116 | + the `web` image doesn't exist yet, Compose builds it from the current |
| 117 | + directory, as specified by the `build: .` line in `docker-compose.yml`. |
| 118 | + |
| 119 | + Once the `web` service image is built, Compose runs it and executes the |
| 120 | + `django-admin startproject` command in the container. This command |
| 121 | + instructs Django to create a set of files and directories representing a |
| 122 | + Django project. |
| 123 | + |
| 124 | +3. After the `docker compose` command completes, list the contents of your project. |
| 125 | + |
| 126 | + ```console |
| 127 | + $ ls -l |
| 128 | + |
| 129 | + drwxr-xr-x 2 root root composeexample |
| 130 | + drwxr-xr-x 3 root root data |
| 131 | + -rw-rw-r-- 1 user user docker-compose.yml |
| 132 | + -rw-rw-r-- 1 user user Dockerfile |
| 133 | + -rwxr-xr-x 1 root root manage.py |
| 134 | + -rw-rw-r-- 1 user user requirements.txt |
| 135 | + ``` |
| 136 | + |
| 137 | + If you are running Docker on Linux, the files `django-admin` created are |
| 138 | + owned by root. This happens because the container runs as the root user. |
| 139 | + Change the ownership of the new files. |
| 140 | + |
| 141 | + Do not change the permission of the data folder where Postgres has its file, otherwise Postgres will not be able to start due to permission issues. |
| 142 | + |
| 143 | + ```console |
| 144 | + sudo chown -R $USER:$USER composeexample manage.py |
| 145 | + ``` |
| 146 | + |
| 147 | + If you are running Docker on Mac or Windows, you should already |
| 148 | + have ownership of all files, including those generated by |
| 149 | + `django-admin`. List the files just to verify this. |
| 150 | + |
| 151 | + ```console |
| 152 | + $ ls -l |
| 153 | + |
| 154 | + total 32 |
| 155 | + -rw-r--r-- 1 user staff 145 Feb 13 23:00 Dockerfile |
| 156 | + drwxr-xr-x 6 user staff 204 Feb 13 23:07 composeexample |
| 157 | + -rw-r--r-- 1 user staff 159 Feb 13 23:02 docker-compose.yml |
| 158 | + -rwxr-xr-x 1 user staff 257 Feb 13 23:07 manage.py |
| 159 | + -rw-r--r-- 1 user staff 16 Feb 13 23:01 requirements.txt |
| 160 | + ``` |
| 161 | + |
| 162 | +### Connect the database |
| 163 | + |
| 164 | +In this section, you set up the database connection for Django. |
| 165 | + |
| 166 | +1. In your project directory, edit the `composeexample/settings.py` file. |
| 167 | + |
| 168 | +2. Replace the `DATABASES = ...` with the following: |
| 169 | + |
| 170 | + ```python |
| 171 | + # settings.py |
| 172 | + |
| 173 | + import os |
| 174 | + |
| 175 | + [...] |
| 176 | + |
| 177 | + DATABASES = { |
| 178 | + 'default': { |
| 179 | + 'ENGINE': 'django.db.backends.postgresql', |
| 180 | + 'NAME': os.environ.get('POSTGRES_NAME'), |
| 181 | + 'USER': os.environ.get('POSTGRES_USER'), |
| 182 | + 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'), |
| 183 | + 'HOST': 'db', |
| 184 | + 'PORT': 5432, |
| 185 | + } |
| 186 | + } |
| 187 | + ``` |
| 188 | + |
| 189 | + These settings are determined by the |
| 190 | + [postgres](https://hub.docker.com/_/postgres) Docker image |
| 191 | + specified in `docker-compose.yml`. |
| 192 | + |
| 193 | +3. Save and close the file. |
| 194 | + |
| 195 | +4. Run the [docker compose up](https://docs.docker.com/engine/reference/commandline/compose_up/) command from the top level directory for your project. |
| 196 | + |
| 197 | + ```console |
| 198 | + $ docker compose up |
| 199 | + |
| 200 | + djangosample_db_1 is up-to-date |
| 201 | + Creating djangosample_web_1 ... |
| 202 | + Creating djangosample_web_1 ... done |
| 203 | + Attaching to djangosample_db_1, djangosample_web_1 |
| 204 | + db_1 | The files belonging to this database system will be owned by user "postgres". |
| 205 | + db_1 | This user must also own the server process. |
| 206 | + db_1 | |
| 207 | + db_1 | The database cluster will be initialized with locale "en_US.utf8". |
| 208 | + db_1 | The default database encoding has accordingly been set to "UTF8". |
| 209 | + db_1 | The default text search configuration will be set to "english". |
| 210 | + |
| 211 | + <...> |
| 212 | + |
| 213 | + web_1 | July 30, 2020 - 18:35:38 |
| 214 | + web_1 | Django version 3.0.8, using settings 'composeexample.settings' |
| 215 | + web_1 | Starting development server at http://0.0.0.0:8000/ |
| 216 | + web_1 | Quit the server with CONTROL-C. |
| 217 | + ``` |
| 218 | + |
| 219 | + At this point, your Django app should be running at port `8000` on |
| 220 | + your Docker host. On Docker Desktop for Mac and Docker Desktop for Windows, go |
| 221 | + to `http://localhost:8000` on a web browser to see the Django |
| 222 | + welcome page. |
| 223 | + |
| 224 | +  |
| 225 | + |
| 226 | + > Note: |
| 227 | + > |
| 228 | + > On certain platforms (Windows 10), you might need to edit `ALLOWED_HOSTS` |
| 229 | + > inside `settings.py` and add your Docker host name or IP address to the list. |
| 230 | + > For demo purposes, you can set the value to: |
| 231 | + > |
| 232 | + > ```python |
| 233 | + > ALLOWED_HOSTS = ['*'] |
| 234 | + > ``` |
| 235 | + > |
| 236 | + > This value is **not** safe for production usage. Refer to the |
| 237 | + > [Django documentation](https://docs.djangoproject.com/en/1.11/ref/settings/#allowed-hosts) for more information. |
| 238 | + |
| 239 | +5. List running containers. |
| 240 | + |
| 241 | + In another terminal window, list the running Docker processes with the `docker ps` or `docker container ls` command. |
| 242 | + |
| 243 | + ```console |
| 244 | + $ docker ps |
| 245 | + |
| 246 | + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| 247 | + def85eff5f51 django_web "python3 manage.py..." 10 minutes ago Up 9 minutes 0.0.0.0:8000->8000/tcp django_web_1 |
| 248 | + 678ce61c79cc postgres "docker-entrypoint..." 20 minutes ago Up 9 minutes 5432/tcp django_db_1 |
| 249 | + ``` |
| 250 | + |
| 251 | +6. Shut down services and clean up by using either of these methods: |
| 252 | + |
| 253 | + * Stop the application by typing `Ctrl-C` in the same shell in where you |
| 254 | + started it: |
| 255 | + |
| 256 | + ```console |
| 257 | + Gracefully stopping... (press Ctrl+C again to force) |
| 258 | + Killing test_web_1 ... done |
| 259 | + Killing test_db_1 ... done |
| 260 | + ``` |
| 261 | + |
| 262 | + * Or, for a more elegant shutdown, switch to a different shell, and run |
| 263 | + [docker compose down](https://docs.docker.com/engine/reference/commandline/compose_down/) from the top level of your |
| 264 | + Django sample project directory. |
| 265 | + |
| 266 | + ```console |
| 267 | + $ docker compose down |
| 268 | + |
| 269 | + Stopping django_web_1 ... done |
| 270 | + Stopping django_db_1 ... done |
| 271 | + Removing django_web_1 ... done |
| 272 | + Removing django_web_run_1 ... done |
| 273 | + Removing django_db_1 ... done |
| 274 | + Removing network django_default |
| 275 | + ``` |
| 276 | + |
| 277 | + Once you've shut down the app, you can safely remove the Django project directory (for example, `rm -rf django`). |
| 278 | + |
| 279 | +## More Compose documentation |
| 280 | + |
| 281 | +* [Docker Compose overview](https://docs.docker.com/compose/) |
| 282 | +* [Install Docker Compose](https://docs.docker.com/compose/install/) |
| 283 | +* [Getting Started with Docker Compose](https://docs.docker.com/compose/gettingstarted/) |
| 284 | +* [Docker Compose Command line reference](https://docs.docker.com/compose/reference/) |
| 285 | +* [Compose file reference](https://docs.docker.com/compose/compose-file/) |
| 286 | +* [Awesome Compose Django sample application](../../django/README.md) |
0 commit comments