Основи Python и Django. / Django з використанням Docker. / Використовуємо Docker із Django.
Використовуємо Docker з Django та PostgreSQL.
Після встановлення порожнього проекту джанго
django-admin startproject prj
створюємо Dockerfile з образом під пітон.
FROM python:3.6 AS python36
ENV PYTHONUNBUFFERED 1
RUN mkdir /app
WORKDIR /app
RUN apt update
RUN apt -y install libpq-dev netcat
COPY requirements.txt /app
RUN /usr/local/bin/python -m pip install --upgrade pip
RUN pip install -r requirements.txt
RUN mkdir /entry
COPY entrypoint.sh /entry
ENTRYPOINT ["/entry/entrypoint.sh"]
Створюємо файл entrypoint.sh для запуску міграції, коли буде доступне підключення до БД.
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python manage.py flush --no-input
python manage.py migrate
exec "$@"
nc -z $SQL_HOST $SQL_PORT - намагається з’єднатися (тут досить часто) по ІП та порту.
У entrypoint зазвичай кладуть те, що розробниками не змінюється.
Створимо файл .env.dev для визначення змінних оточення.
DEBUG=1
DATABASE=postgres
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
SQL_DATABASE=imaginary
SQL_USER=postgres
SQL_PASSWORD=123
SQL_HOST=db
SQL_PORT=5432
Їх ми потім “вштовхуватимемо” в налаштування проекту (settings.py) якось так:
import os
DEBUG = os.getenv('DEBUG', 'True')
DJANGO_ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '[*]')
DATABASE = os.getenv('DATABASE', 'sqlite3')
SQL_DATABASE = os.getenv('SQL_DATABASE', 'imaginary')
SQL_USER = os.getenv('SQL_USER', 'postgres')
SQL_PASSWORD = os.getenv('SQL_PASSWORD', '123')
SQL_PORT = os.getenv('SQL_PORT', '5432')
Створюємо збирач контейнерів у файлі docker-compose.yaml.
version: '3.5'
services:
django:
build: .
restart: always
ports:
- 8000:8000
working_dir: /app
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./prj:/app
depends_on:
- db
env_file:
- ./.env.dev
db:
restart: always
image: postgres:latest
volumes:
- ./pg_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=1q2w3e
- POSTGRES_DB=imaginary
Тут у нас поки що 2 контейнери під БД і джанго-дев-сервер.
Причому ми налаштували БД для зберігання даних усередині папки (pg_data) проекту, на випадок якщо ви “грохнете” контейнер або образ, то дані збережуться. Тому татку потрібно створити.
env_file - тут ми приєднуємо файл із змінними оточення.
Піднімаємо контейнер.
docker-compose up --build
Змінюємо settings.py.
import os
DEBUG = os.getenv('DEBUG', 'True')
DJANGO_ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '[*]')
DATABASE = os.getenv('DATABASE', 'sqlite3')
SQL_DATABASE = os.getenv('SQL_DATABASE', 'imaginary')
SQL_USER = os.getenv('SQL_USER', 'postgres')
SQL_PASSWORD = os.getenv('SQL_PASSWORD', '123')
SQL_HOST = os.getenv('SQL_HOST', 'db')
SQL_PORT = os.getenv('SQL_PORT', '5432')
if DATABASE == 'sqlite3':
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
elif DATABASE == 'postgres':
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': SQL_DATABASE,
'USER': SQL_USER,
'PASSWORD': SQL_PASSWORD,
'HOST': SQL_HOST,
'PORT': SQL_PORT,
},
}
Якщо отримуємо повідомлення про те, що база даних не існує, необхідно видалити і перезбирати контейнери.
docker-compose down -v
docker-compose up --build
Запуск контейнерів по одному.
Запускати контейнери по одному можна командою.
docker-compose run django
Можна створити файл, що виконується, і запустити кожен контейнер в окремому вікні термінального менеджера tmux.
Наприклад, створимо файл monitor.sh
#!/bin/bash
command -v tmux >/dev/null 2>&1 || { echo >&2 "I require tmux but it's not installed. Aborting."; exit 1; }
tmux new-session \; \
split-window -v \; \
select-pane -t 0 \; \
send-keys 'docker-compose run db' C-m \; \
select-pane -t 1 \; \
send-keys 'docker-compose run django' C-m \; \
select-pane -t 0 \;
Розбивати термінал можна і горизонталлю.
split-window -h\; select-pane -t 0\; \
Тепер зробимо його виконаним.
chmod +x monitor.sh
І запустимо.
./monitor.sh