Как использовать Django, PostgreSQL и Docker

Spread the love

В этом уроке мы создадим новый проект Django, используя Docker и PostgreSQL. Django поставляется со встроенной поддержкой SQLite, но даже для локальной разработки лучше использовать «настоящую» базу данных, такую как PostgreSQL, которая соответствует производственной.

Можно запускать PostgreSQL локально, используя такой инструмент, как Postgres.app, однако сегодня среди многих разработчиков предпочтительным является использование Docker, инструмента для создания изолированных операционных систем. Проще всего представлять это как виртуальную среду, которая содержит все необходимое для нашего проекта Django: зависимости, базы данных, службы кэширования и любые другие необходимые инструменты.

Основная причина использования Docker заключается в том, что он полностью устраняет любые проблемы, связанные с локальной разработкой. Вместо того, чтобы беспокоиться о том, какие программные пакеты установлены или работают с локальной базой данных вместе с проектом, вы просто запускаете образ Docker всего проекта. Лучше всего то, что этим можно поделиться в группах и значительно упростить разработку команды.

Инсталяция Docker

Первым шагом является установка настольного приложения Docker для вашего локального компьютера:

Первоначальная загрузка Docker может занять некоторое время для загрузки.

После завершения установки Docker мы можем подтвердить, что запущена правильная версия. В вашем терминале запустите команду docker –version.

$ docker --version
Docker version 19.03.2, build 6a30dfc

Docker Compose – это дополнительный инструмент, который автоматически включается в загрузку Docker для Mac и Windows. Однако, если вы используете Linux, вам нужно будет добавить его вручную. Вы можете сделать это, выполнив команду sudo pip install docker-compose после завершения установки Docker.

Проект Django

Мы будем использовать приложение Message Board app из курса Django for Beginners. Он предоставляет код для приложения доски объявлений, использующего SQLite, который позже мы отредактируем.

Создайте новый каталог в рабочей папке и клонируйте репозиторий в него.

$ cd ~/Projects
$ git clone https://github.com/wsvincent/djangoforbeginners.git
$ cd djangoforbeginners
$ cd ch4-message-board-app

Затем установите пакеты, указанные в Pipenv, и запустите новую оболочку. Если вы видите (ch4-message-board-app), то вы знаете, что виртуальная среда активна.

$ pipenv install
$ pipenv shell
(ch4-message-board-app) $

Внимание: Ожидается что у вас по умолчанию установлен Python 3.6. Так как в pipenv используется django 2.2.0. Если это не так используйте ключ выбора версии python

$ pipenv install --python 3.6 
$ pipenv shell
(ch4-message-board-app) $

Обязательно мигрируйте вашу базу данных после этих изменений.

(ch4-message-board-app) $ python manage.py migrate

Если вы теперь используете команду python manage.py runserver, вы можете увидеть рабочую версию нашего приложения по адресу http://localhost: 8000.

Docker

Надеюсь, Docker завершил установку к этому моменту. Чтобы убедиться, что установка прошла успешно, закройте локальный сервер с помощью Control + c, а затем введите в командной строке docker run hello-world. Вы должны увидеть ответ вроде этого:

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest: sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image whi
ch runs the executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client,
which sent it to your terminal.

To try something more ambitious, you can run an Ubuntu container
with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Образы и контейнеры

В Docker есть две важные концепции: образы (images) и контейнеры (containers).

  • Image: список инструкций для всех программных пакетов в ваших проектах
  • Container: экземпляр образа во время выполнения

Другими словами, образ (image) описывает, что произойдет, а контейнер (container) – это то, что фактически выполняется.

Для настройки образов и контейнеров в Docker мы используем два файла: Dockerfile и docker-compose.yml.

Dockerfile содержит список инструкций для образа, иначе говоря, что на самом деле происходит в среде контейнера.

Создадим новый файл Dockerfile.

(ch4-message-board-app) $ touch Dockerfile

Затем добавьте следующий код в него.

# Dockerfile

# Pull base image
FROM python:3.7

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /code

# Install dependencies
RUN pip install pipenv
COPY Pipfile Pipfile.lock /code/
RUN pipenv install --system

# Copy project
COPY . /code/

В верхней строке мы используем официальный образ Docker для Python 3.7. Далее мы создаем две переменные окружения.

PYTHONUNBUFFERED гарантирует, что наш вывод консоли выглядит знакомым и не буферизируется Docker, что нам не нужно. PYTHONDONTWRITEBYTECODE означает, что Python не будет пытаться создавать файлы .pyc, которые мы также не желаем.

Следующая строка устанавливает WORKDIR в /code. Это означает, что рабочий каталог находится в /code, поэтому в будущем для запуска любых команд, таких как manage.py, мы можем просто использовать WORKDIR, а не вспоминать, где именно в Docker фактически находится наш код.

Затем мы установим наши зависимости, убедимся чтобы у нас последняя версия pip, устанавливаем pipenv, копируем наши локальные Pipfile и Pipfile.lock в образ Docker, и а затем запускаем его для установки наших зависимостей. Команда RUN позволяет нам запускать команды в Docker так же, как и в командной строке.

Мы не можем запустить Docker-контейнер, пока у нас не будет созданного образа, поэтому давайте сделаем это, создав его.

(ch4-message-board-app) $ docker build .

В случае успеха у вас должно быть что то типа такого.

Sending build context to Docker daemon  162.3kB
Step 1/8 : FROM python:3.7
3.7: Pulling from library/python
c7b7d16361e0: Pull complete 
b7a128769df1: Pull complete 
1128949d0793: Pull complete 
667692510b70: Pull complete 
bed4ecf88e6a: Pull complete 
8a8c75f3996a: Pull complete 
10b7379e5573: Pull complete 
ca1b6fe24628: Pull complete 
9a90211ec083: Pull complete 
Digest: sha256:fc0a398e1987fb1e58909053c11630e06adb3df265fe693391779020b9253f5e
Status: Downloaded newer image for python:3.7
 ---> 9fa56d0addae
Step 2/8 : ENV PYTHONDONTWRITEBYTECODE 1
 ---> Running in 5e7a7983814d
Removing intermediate container 5e7a7983814d
 ---> 3aff2533de96
Step 3/8 : ENV PYTHONUNBUFFERED 1
 ---> Running in e99df328f671
Removing intermediate container e99df328f671
 ---> f135da04005a
Step 4/8 : WORKDIR /code
 ---> Running in dc4ffef67e1a
Removing intermediate container dc4ffef67e1a
 ---> b8cfba900375
Step 5/8 : RUN pip install pipenv
 ---> Running in 99057a4ef5cd
Collecting pipenv
  Downloading https://files.pythonhosted.org/packages/13/b4/3ffa55f77161cff9a5220f162670f7c5eb00df52e00939e203f601b0f579/pipenv-2018.11.26-py3-none-any.whl (5.2MB)
Collecting virtualenv
  Downloading https://files.pythonhosted.org/packages/89/66/786e0d6f61bd0612f431e19b016d1ae46f1cb8d21a80352cc6774ec876e3/virtualenv-16.7.6-py2.py3-none-any.whl (3.4MB)
Collecting virtualenv-clone>=0.2.5
  Downloading https://files.pythonhosted.org/packages/ba/f8/50c2b7dbc99e05fce5e5b9d9a31f37c988c99acd4e8dedd720b7b8d4011d/virtualenv_clone-0.5.3-py2.py3-none-any.whl
Requirement already satisfied: pip>=9.0.1 in /usr/local/lib/python3.7/site-packages (from pipenv) (19.3)
Collecting certifi
  Downloading https://files.pythonhosted.org/packages/18/b0/8146a4f8dd402f60744fa380bc73ca47303cccf8b9190fd16a827281eac2/certifi-2019.9.11-py2.py3-none-any.whl (154kB)
Requirement already satisfied: setuptools>=36.2.1 in /usr/local/lib/python3.7/site-packages (from pipenv) (41.4.0)
Installing collected packages: virtualenv, virtualenv-clone, certifi, pipenv
Successfully installed certifi-2019.9.11 pipenv-2018.11.26 virtualenv-16.7.6 virtualenv-clone-0.5.3
Removing intermediate container 99057a4ef5cd
 ---> 7ea1413f4881
Step 6/8 : COPY Pipfile Pipfile.lock /code/
 ---> dd19784be956
Step 7/8 : RUN pipenv install --system
 ---> Running in e791708f149e
Installing dependencies from Pipfile.lock (ebdf7a)…
Removing intermediate container e791708f149e
 ---> 5730e14edb35
Step 8/8 : COPY . /code/
 ---> 98329412f14c
Successfully built 98329412f14c

Далее нам нужен новый файл docker-compose.yml. Он говорит Docker, как запустить наши Docker-контейнеры. У нас будут 2 контейнера. Один для базы, другой для приложения.

(ch4-message-board-app) $ touch docker-compose.yml

Добавьте в него следующее:

version: '3.7'

services:
  db:
    image: postgres:10.1-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db

volumes:
  postgres_data:

В верхней строке мы указываем что мы используем самую последнюю версию Compose – 3.7.

В db мы указываем что используем образ Docker для Postgres 10.1 и используем volumes, чтобы указать, где должен находиться контейнер в нашем контейнере Docker.

В web мы указываем, как будет работать веб-сервис. Сначала необходимо создать образ из текущего каталога и запустить сервер в 0.0.0.0:8000. Мы используем volumes, чтобы указать где будем хранить код в нашем контейнере Docker по адресу /code/. Элемент ports позволяет нам сопоставить наш собственный порт 8000 с портом 8000 в контейнере Docker. Это порт Django по умолчанию. И, наконец, depends_on говорит, что мы должны сначала запустить db, прежде чем запускать наши веб-службы.

Последний раздел volumes объясняется тем, что в Compose существует правило, согласно которому вы должны перечислить именованные тома в ключе volumes верхнего уровня.

Докер настроен!

Обновление до PostgreSQL

Нам нужно настроить наше приложение Message Board, чтобы использовать PostgreSQL вместо SQLite. Сначала установите psycopg2 для привязки нашей базы данных к PostgreSQL.

(ch4-message-board-app) $ pipenv install psycopg2-binary

Затем обновите файл settings.py, чтобы указать, что мы будем использовать PostgreSQL, а не SQLite.

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db', # set in docker-compose.yml
        'PORT': 5432 # default postgres port
    }
}

На этом этапе мы должны мигрировать нашу базу данных в Docker.

(ch4-message-board-app) $ docker-compose run web python /code/manage.py migrate --noinput

Кроме того, поскольку приложение Message Board требует использования администратора, создайте суперпользователя в Docker. Выполните следующую команду ниже.

(ch4-message-board-app) $ docker-compose run web python /code/manage.py createsuperuser

Запуск Docker

Наконец-то мы готовы запустить Docker! Первое выполнение команды может занять некоторое время, так как Docker должен загрузить весь необходимый контент. Но он закеширует этот процесс, поэтому будущие запуски будут намного быстрее.

Введите следующую команду:

(ch4-message-board-app) $ docker-compose up -d --build

Мы можем проверить, что все работает, поэтому перейдите по адресу http://127.0.0.1:8000/, где вы должны увидеть ту же домашнюю страницу, что и раньше.

Теперь перейдите на http://127.0.0.1:8000/admin и залогинтесь. Вы можете добавить новые сообщения и затем отобразить их на главной странице, как описано в Django for Beginners.

Небольшой список команд Docker

Когда вы закончите, не забудьте закрыть контейнер Docker.

(ch4-message-board-app) $ docker-compose down

Просто остановить контейнер

docker stop CONTAINER ID 

Запустить ранее остановленный контейнер

docker start CONTAINER ID

Перегрузка контейнера

docker restart CONTAINER ID

Что бы посмотреть работающие контейнеры

docker ps

Что бы посмотреть вообще все контейнеры

docker ps -a

Посмотреть список всех образов

docker images

Удалить образ

docker rmi CONTAINER ID
или
docker rmi -f CONTAINER ID

Иногда может понадобиться зайти в работающий контейнер. Для этого нужно запустить команду запуска интерактивной оболочкой bash

docker exec -it CONTAINER ID bash

Быстрый обзор

Вот краткая версия терминов и понятий, которые мы рассмотрели в этом посте:

  • Image: «определение» вашего проекта
  • Container: это то что ваш проект на самом деле работает (экземпляр образа)
  • Dockerfile: определяет, как выглядит ваш образ
  • docker-compose.yml: YAML-файл, который задает как должны работать Docker образы

Мы используем Dockerfile, чтобы сообщить Docker, как создать наш образ. Затем мы запускаем наш реальный проект в контейнере. Файл docker-compose.yml предоставляет дополнительную информацию о том, как наш контейнер Docker должен вести себя.

Следующие шаги

Если вы хотите больше узнать об использовании Django и Docker вместе, я написал целую книгу на эту тему, Django for Professionals.

И если вы хотите углубиться в Docker, то фантастический ресурс, который я использовал сам, а теперь рекомендую другим, – это видеокурс  Dive into Docker.

Оригинальная статья: William VincentHow to use Django, PostgreSQL, and Docker

Была ли вам полезна эта статья?
[0 / 0]

Spread the love

Добавить комментарий

Ваш e-mail не будет опубликован.