Docker-compose для микросервисного приложения
У меня есть веб-приложение, которое состоит из основного сервера и 5 микросервисов (везде Django). У меня также есть 2 базы данных (PostgreSQL) и redis, работающий в одном из микросервисов. Я также использую nginx для основного сервера.
Я настроил все на удаленном сервере и теперь сервисы запускаются через tmux
просто командами вроде этой:
gunicorn --bind 127.0.0.1:5050 --workers 5 --threads 5 some_service.wsgi
Теперь я думаю, что все приложение должно быть контейнерным, а я абсолютный новичок в Docker. Как я понимаю, мне нужно создать файл docker-compose.yml и задать в нем все сущности. Я создал Dockerfile для каждого микросервиса. Они выглядят так:
FROM python:3.8
RUN mkdir -p /usr/src/main_server
WORKDIR /usr/src/main_server
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY . /usr/src/main_server
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 5001
RUN chmod a+x ./run.sh
ENTRYPOINT ["./run.sh"]
и run.sh
выглядят как:
#!/bin/bash
python manage.py collectstatic --settings=main_server.settings.development --noinput
exec gunicorn --bind 127.0.0.1:5001 --workers 5 --threads 5 --timeout 15 main_server.wsgi
поэтому пока что я сделал такой файл docker-compose:
version: "3.8"
services:
user_db:
"????"
app_db:
"????"
redis:
"????"
main_server:
build:
context: .
dockerfile: main_server/main_server/Dockerfile
user_service:
build:
context: .
dockerfile: user_service/user_service/Dockerfile
session_service:
build:
context: .
dockerfile: session_service/session_service/Dockerfile
apartment_service:
build:
context: .
dockerfile: apartment_service/apartment_service/Dockerfile
bill_service:
build:
context: .
dockerfile: utility_bill/utility_bill_service/Dockerfile
mail_service:
build:
context: .
dockerfile: mail_service/mail_service/Dockerfile
Как я понял после docker-compose up
для каждого сервиса будет создан контейнер с настройками из Dockerfiles.
Но как я могу настроить контейнеры db и redis? В django мои настройки db выглядят следующим образом:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'users',
'USER': 'postgres',
'PASSWORD': 'XXXXXX',
'HOST': os.environ.get('POSTGRES_HOST', default='localhost'),
'PORT': '5432',
}
}
А мои настройки redis в микросервисе:
SESSION_REDIS = {
'host': 'localhost',
'port': 6379,
'db': 1,
'password': '41zipudu',
'prefix': 'session',
'socket_timeout': 1,
'retry_on_timeout': True
}
Итак, как я могу правильно установить все эти вещи?
Мне также нужно сделать контейнер nginx, но я не знаю, как установить контейнер с существующими конфигами. Итак, сейчас конфиг моего приложения находится в /etc/nginx/sites-available/main_server:
server {
listen 80;
server_name 134.111.111.22;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/holyskills/Desktop/SimpleBill/simplebill/main_server/main_server;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 45;
proxy_send_timeout 45;
proxy_read_timeout 45;
client_max_body_size 15m;
proxy_pass http://127.0.0.1:5001;
}
}
Вы можете установить переменные среды в docker compose для каждого микросервиса.
Например:
postgres:
....
redis:
....
main_server:
build:
context: .
dockerfile: main_server/main_server/Dockerfile
environment:
- POSTGRES_HOST: postgres
- REDIS_HOST: redis
Обратите внимание на переменные окружения, соответствующие именам контейнеров postgres и redis docker compose выше.
Затем в микросервисах обращайтесь к этим переменным среды там, где это необходимо. Например, в Python:
host = os.getenv(POSTGRES_HOST)
Адреса контейнеров в Docker Compose (если не определено иное) - это имена, заданные в docker-compose.yaml. Поэтому, например, вы можете пинговать "main_server" из другого контейнера в сети compose.