October 14, 2022

Свой приватный Интернет-клуб (на платформе Vas3k.Club) #5

Всем привет! Вот и наступила кульминация нашего Клубастроительства! Здесь и сейчас мы с вами запустим Кастомизацию Vas3k клуба на продакшен сервере. Да и вообще сделаем тотальный CI/CD!

Предыдущие части клубостроительства:

  1. Делаем форк и поднимаем базовые сервисы
  2. Готовим конфигурационные файл и поднимаем клуб локально
  3. Кастомизируем Клуб под себя
  4. Настройка Клуба для публикации в продакшен

В этой части мы сделаем следующее:

  • Настроим обратный прокси (reverse proxy)
  • Запустим Клуб вручную на сервере
  • Создадим пользователя Администратора (т.е. себя)
  • Осуществим выкладку Клуба с помощью GitHub Actions

ПРЕДИСЛОВИЕ

На данный момент на сервере у нас должны работать сервисы обратного прокси, Pepic, ogimgd. Если все так, то нужно завершить все сервисы, в соответствующих директориях на сервере нужно выполнить команду:

docker-compose down

Клуб должен быть локально настроен:

  • Подготовлен конфигурационный файл .env.
  • Актуализирован файл settings.py
  • Настроена интеграция с сервисом Sentry
  • Настроена интеграция с Telegram

В репозитарии Клуба должны быть сделаны локальные доработки и включены все GitHub Action. Должны успешно проходить скрипты тестирования:

Action codeql-vulnerability-analysis.yml должен быть отключен

На сервере должен быть склонирован репозитарий Клуба, а в GitHub - настроен GitHub Action deploy.yml

Проверьте, что вы выполнили шаги части 4.

Reverse proxy (обратный прокси)

В этом разделе мы должны отредактировать конфигурационный файл docker-compose.yml для сервиса обратного прокси (см. первую часть)

Открываем файл docker-compose.yml для сервиса обратного прокси и дописываем в секцию volumes пути до директорий "frontend/static" и "gdpr/downloads". Выглядет должно следующим образом:

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

  • /home/pmi-admin/pmi.moscow.club/frontend/static:/home/club/frontend/static:ro
  • /home/pmi-admin/pmi.moscow.club/gdpr/downloads:/home/club/gdpr/downloads:delegated

Нужно изменить левую часть пути на что-то свое по шаблону: "${PWD}/<club_direcory>/...". Правая часть выражения (после ":") не должна меняться.

Создадим конфигурационные файлы обратного прокси NGINX для нашего Клуба.

Домен моего Клуба - "pmi.moscow" (https://pmi.moscow). Клуб доступен в т.ч. по адресу https://www.pmi.moscow Для настройки обратного прокси я создал файлы pmi.moscow, pmi.moscow_location и www.pmi.moscow в директории etc/nginx репозитария Клуба. Посмотрите их.

Напомню, что в качестве обратного прокси используется jwlider/nginx-proxy.

Создадим в директории etc/nginx три файла:

  • <Домен клуба без https/http>
  • <Домен клуба без https/http>_location
  • www.<домен клуба>

Настройки nginx Клуба

Актуализируем настройки NGINX для домена Клуба, откроем файл etc/nginx/<домен клуба без https/http>. У меня такой файл - pmi.moscow.

charset utf-8;
client_max_body_size 30M;
index index.html index.htm;
set_real_ip_from 172.17.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

rewrite ^/favicon.ico$ https://<домен клуба>/static/images/favicon/favicon.ico;
rewrite ^/favicon.png$ https://<домен клуба>/static/images/favicon/favicon-32x32.png;

location /static/ {
  root /home/club/frontend/;
  gzip_static on;
  expires max;
  add_header Cache-Control "public";
}

location /downloads/ {
  root /home/club/gdpr/;
  gzip_static off;
  expires max;
  add_header Cache-Control "public";
}

Замените <домен клуба> на ваш домен. Кстати, а вы ведь поменяли favicon? :)

Настройки nginx location Клуба

Внесем изменения в файл <домен клуба>_location. Пример: pmi.moscow_location

add_header "Access-Control-Allow-Origin" "*";
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS";
add_header "Access-Control-Allow-Headers" "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header "Access-Control-Expose-Headers" "Content-Length,Content-Range";
add_header "Strict-Transport-Security" "max-age=31536000;includeSubDomains";
add_header "X-Content-Type-Options" "nosniff";
add_header "Referrer-Policy" "strict-origin-when-cross-origin";
add_header "Permissions-Policy" "accelerometer=(),camera=(),geolocation=(self 'https://pmi.moscow'),gyroscope=(),magnetometer=(),microphone=(),payment=(),usb=()";

proxy_set_header "Host" $http_host;
proxy_set_header "X-Forwarded-For" $proxy_add_x_forwarded_for;
proxy_set_header "X-Forwarded-Proto" $scheme;
proxy_redirect off;
proxy_buffering off;

Нужны изменения в строке "Permissions-Policy".

www настройки nginx

Пропишем одну строку в файле www.<домен клуба>. Пример: www.pmi.moscow

rewrite ^(.*) https://<домен клуба>$1 permanent;
  •  Вместо <домен клуба> укажите ваше домен Клуба.

Настройки обратного прокси

Теперь нужно закоммитить 3 файла в начале в ветку dev, а потом синхронизировать master с dev через pull request. За одно убедимся, что все тесты - зеленые.

После обновления master ветки логиньтесь на ваш сервер и в директории vhost.d сервиса обратного прокси любым удобным способом копируйте три файла.

ПЕРВЫЙ ЗАПУСК КЛУБА

В первой части статей настраивали файл .gitignore таким образом, чтобы конфигурационный файл .env с приватными настройками не пушился в GitHub. Поэтому, нужно его создать и отредактировать вручную.

На сервере перейдем в директорию club и создадим файл .env

 cd <директория клуба>/club # Пример: cd pmi.moscow.club/club/
 touch .env 

Скопируем содержимое локального файла .env, который создавали во второй части, в .env файл на сервере.

ЗАПУСКАЕМ

Последовательность запуска сервисов следующая:

  • Запускаем сервис обратного прокси, В директории обратного прокси выполняем команду:
docker-compose up -d
  • Запускаем Pepic. В директории Pepic выполняем команду:
docker-compose up -d
  • Запускаем oimgd. В директории Oimgd выполняем команду:
docker-compose up -d
  • [Опционально] Запускаем docker-mailserver, если используем его, и этот сервис по каким-то причинам не запущен. В директории почтового сервиса выполняем команду:
./bin/production.sh up -d
  • Запускаем Клуб. В директории Клуба выполняем команду:
docker-compose -f docker-compose.production.yml up -d

Ждем. Проверяем, что все сервисы успешно запущены (проверяем с помощью команды docker ps). Если что-то не запустилось, то анализируем логи с помощью docker logs <идентификатор сервиса>.

Если не все сервисы успешно запущены, то для остановки сервисов используем команду в директории соответствующего сервиса:

docker-compose down

Картинка должна быть похожа на следующую:

У меня еще поднять персональный блог на платформе Ghost, но об этом в следующий раз.

Создаем Администратора

Надеюсь, что вы справились с предыдущим пунктом. Если все хорошо, то ваш Клуб уже доступен для обращения в браузере!

Клуб работает!! Но в Клубе не зарегистрировано ни одного пользователя. Нет ни одного Модератора, который бы мог подтвердить нового пользователя.

Исправим это! Для этого выполним шаги в Docker контейнере, описанные в третьей части.

Создаем пользователя уровня GOD

  • В браузере переходим на страницу входа в Клуб (https://<домен клуба>/auth/login/):
    1. Вводим email адрес Администратора и нажимаем "Вход".
    2. Зайти в почту Администратора, получаем email с кодом, копируем его.
    3. Вводим полученный код в Клуб.
    4. Заполняем детальное Intro о себе.
    5. Отправить на модерацию.
  • На сервере получаем список запущенных docker-сервисов. Выполняем команду:
docker ps
  • Ищем идентификатор сервиса club_app:
0d8d87d382bf - идентификатор сервиса club_app
  • Выполняем команду в консоли:
docker exec -it <Идентификатор сервиса club_app> /bin/sh
  • Заходим в консоль Django. Выполнить команду:
python3 manage.py shell
  • Выполнить последовательность команд в Django Admin (построчно, кроме комментариев. Команды аналогичные тем, что использовались для Клуба, запущенного локально)
# Добавить модули:
from users.models.user import User
from datetime import datetime

# Получить первого пользователя:
user = User.objects.first()

# Установить статус, что пользователь прошел модерацию
user.moderation_status = User.MODERATION_STATUS_APPROVED
user.created_at = datetime.utcnow()

# Назначить роль GOD
user.roles.append(User.ROLE_GOD)

# Сохранить пользователя
user.save()

# Сделать интро Администратора видимым всем
from posts.models.post import Post
intro = Post.objects.filter(author=user, type=Post.TYPE_INTRO).first()
intro.is_approved_by_moderator = True
intro.is_visible = True
intro.last_activity_at = datetime.utcnow()
intro.save()

# Актуализировать SearchIndex
from search.models import SearchIndex
SearchIndex.update_user_index(user)

Для выхода нужно выполнить следующую последовательность команд:

# Выход из консоли Django
exit()

# Выход из консоли сервиса club_app
exit

ГОТОВО! Обновляем страницу Клуба:

Теперь вы являетесь Администратором. Можете назначать другим пользователям через админка права Модератора.

ПУБЛИКУЕМ КЛУБ

Первый раз мы запускали Клуб вручную. Настало время попробовать опубликовать новую версию Клуба через GitHub Actions. Настройку всего этого добра мы делали в четвертой части статей.

Для этого в GitHub сделаем Pull Request из ветки master в ветку deploy:

В разделе GitHub Actions:

РЕЗУЛЬТАТ

Заключение

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️

❤️ ПОЗДРАВЛЯЮ! Вы сделали ЭТО! ❤️ Это ТРИУМФ!

❤️Теперь вы умеет все, что нужно для запуска Клуба в Production!

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️

В следующей статье мы поговорим с Вами про бэкап Клуба :) А пока, наслаждайтесь!

❤️ Meow! ❤️