Merge branch 'feature/docker' into 'develop'

Feature/docker

See merge request 2020-2021/online/s101/group-02/access_controller!50
This commit is contained in:
Кравченко Артем 2021-04-19 17:20:13 +00:00
commit c7048f8ca6
16 changed files with 221 additions and 100 deletions

29
.dockerignore Normal file
View File

@ -0,0 +1,29 @@
*.pyc
*.pyo
*.mo
*.db
*.css.map
*.egg-info
*.sql.gz
*.sqlite3
.cache
.env
.project
.idea
.pydevproject
.idea/workspace.xml
.DS_Store
.git/
.sass-cache
.vagrant/
__pycache__
dist
docs
env
logs
src/{{ project_name }}/settings/local.py
src/node_modules
web/media
web/static/CACHE
stats
Dockerfile

25
.env.example Normal file
View File

@ -0,0 +1,25 @@
ACTRL_DEBUG=1
ACTRL_SECRET_KEY="v1i_fb\$_jf2#1v_lcsbu&eon4u-os0^px=s^iycegdycqy&5)6"
ACTRL_HOST="actrl.example.com"
ACTRL_EMAIL_HOST="smtp.mail.ru"
ACTRL_EMAIL_PORT=2525
ACTRL_EMAIL_TLS=1
ACTRL_EMAIL_HOST_USER="djgr.02@mail.ru"
ACTRL_EMAIL_HOST_PASSWORD="djangogroup02"
ACTRL_FROM_EMAIL="djgr.02@mail.ru"
ACTRL_SERVER_EMAIL="djgr.02@mail.ru"
ENG_CROLE_ID=360005209000
LA_CROLE_ID=360005208980
EMPL_GROUP="Поддержка"
BUF_GROUP="Сменная группа"
ST_EMAIL="d.krikov@ngenix.net"
LICENSE_NO=3
SHIFTH=12
ACTRL_ZENDESK_SUBDOMAIN="ngenix1612197338"
ACTRL_API_EMAIL="email@example.com"
ACTRL_API_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ACTRL_API_PASSWORD=""

1
.gitignore vendored
View File

@ -11,6 +11,7 @@ __pycache__/
local_settings.py local_settings.py
db.sqlite3 db.sqlite3
db.sqlite3-journal db.sqlite3-journal
db/
media/ media/
logs/ logs/

10
Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM python:3.6
COPY ./ /access_controller
WORKDIR /access_controller/
RUN pip install -r requirements/prod.txt
RUN python manage.py makemigrations
EXPOSE 8000
COPY start.sh /var/
CMD bash /var/start.sh

127
README.md
View File

@ -42,34 +42,47 @@
```bash ```bash
sudo apt install make sudo apt install make
pip install --upgrade pip pip install --upgrade pip
pip install -r requirements.txt pip install -r requirements/dev.txt
./manage.py migrate ./manage.py migrate
./manage.py loaddata data.json ./manage.py loaddata data.json
./manage.py runserver ./manage.py runserver
``` ```
##ZenDesk Access Controller instruction for eng ## ZenDesk Access Controller instruction for eng
##Перед запуском для тестирования: ## Перед запуском для тестирования:
Убедитесь, что вы зарегистрированы в песочнице ZenDesk, у вас назначена организация (SYSTEM) Убедитесь, что вы зарегистрированы в песочнице ZenDesk, у вас назначена организация `SYSTEM`
Для админов ZenDesk дополнительно - создайте токен доступа в ZenDesk Для админов ZenDesk дополнительно - создайте токен доступа в ZenDesk
При запуске в Docker убедитесь что папка, которая будет служить хранилищем для БД, открыта на запись и чтение При запуске в Docker убедитесь что папка, которая будет служить хранилищем для БД, открыта на запись и чтение
##Запуск на локальной машине: ## Запуск на локальной машине:
- Скопировать репозиторий на локальную машину
скопировать репозиторий на локальную машину - Перейти в папку приложения
перейти в папку приложения - Активировать виртуальное окружение
активировать вирутальное окружение - Выполнить команду `pip install -r requirements/dev.txt`
выполнить команду pip install -r requirements.txt - В виртуальное окружение добавить следующие переменные:
в вирутальное окружение добавить следующие переменные :
ACCESS_CONTROLLER_API_EMAIL={EMAIL} - почта админа в ZenDesk ```
ACCESS_CONTROLLER_API_PASSWORD={PASSWORD} - пароль админа ZenDesk ACTRL_DEBUG={0/1} - включить режим дебага
ACCESS_CONTROLLER_API_TOKEN={API_TOKEN} - API токен зендеск ACTRL_HOST={HOSTNAME} - при запуске без дебага, надо указать домен на котором будет работать приложение
ZD_DOMAIN={DOMAIN} - домен ZenDesk ACTRL_SECRET_KEY={DJANGO_SECRET_KEY} - секретный ключ сгенерированый Django
ACTRL_EMAIL_HOST={SMTP_HOST} - домен почтового сервера через который приложение будет отправлять письма, например "smtp.gmail.com"
ACTRL_EMAIL_PORT={SMTP_PORT} - порт для почтового сервера, например 587, 465 , 2525
ACTRL_EMAIL_TLS={USE_TLS} - использовать TLS для подключения к почтовому серверу, 0 или 1
ACTRL_EMAIL_HOST_USER={USERNAME} - логин с которым приложение входит на почтовый сервер
ACTRL_EMAIL_HOST_PASSWORD={PASSWORD} - пароль/ключ с которым приложение входит на почтовый сервер
ACTRL_FROM_EMAIL={EMAIL} - адрес с которого приложение отправляет письма
ACTRL_SERVER_EMAIL={EMAIL} - адрес на который отвечают пользователя
ACTRL_API_EMAIL={EMAIL} - почта админа в ZenDesk
ACTRL_API_PASSWORD={PASSWORD} - пароль админа ZenDesk
ACTRL_API_TOKEN={API_TOKEN} - API токен зендеск
ACTRL_ZENDESK_SUBDOMAIN={DOMAIN} - домен ZenDesk
ENG_CROLE_ID={ENGINEER_CUSTOM_ROLE_ID} - id роли инженера( custom_role_id сотрдника смены) ENG_CROLE_ID={ENGINEER_CUSTOM_ROLE_ID} - id роли инженера( custom_role_id сотрдника смены)
LA_CROLE_ID={LIGHT_AGENT_CUSTOM_ROLE_ID} - id роли легкого агента (custom_role_id роли -легкий агент) LA_CROLE_ID={LIGHT_AGENT_CUSTOM_ROLE_ID} - id роли легкого агента (custom_role_id роли -легкий агент)
EMPL_GROUP={EMPLOYEE_GROUP_NAME} - имя группы которой принадлежат сотрудники ССКС EMPL_GROUP={EMPLOYEE_GROUP_NAME} - имя группы которой принадлежат сотрудники ССКС
@ -77,48 +90,62 @@ BUF_GROUP={BUFFER_GROUP_NAME} - имя буферной группы для пе
ST_EMAIL={SOLVED_TICKETS_EMAIL} - почта на которую будут переназначятся закрытые тикеты ST_EMAIL={SOLVED_TICKETS_EMAIL} - почта на которую будут переназначятся закрытые тикеты
LICENSE_NO={LICENSE_NO} - количество лицензий, отображаемых как доступные в приложении LICENSE_NO={LICENSE_NO} - количество лицензий, отображаемых как доступные в приложении
SHIFTH={SHIFT_HOURS} - количество часов в рабочей смене (нужно для статистики, пока не реализовано но требует указания значения) SHIFTH={SHIFT_HOURS} - количество часов в рабочей смене (нужно для статистики, пока не реализовано но требует указания значения)
```
- Выполнить команду `python manage.py migrate`
- Запустить приложение командой `python manage.py runserver` (можно указать в параметрах для файла manage.py)
- Перейти по ссылке в консоли (вероятнее всего откроется по адресу http://127.0.0.1:8000/)
выполнить команду python manage.py makemigrations ## Запуск в Docker:
выполнить команду python manage.py migrate Требуется установленный и настроенный Docker
запустить приложение командой python manage.py runserver (можно указать в параметрах для файла manage.py)
перейти по ссылке в консоли (вероятнее всего откроется по адресу http://127.0.0.1:8000/) - Скопировать репозиторий на локальную машину
- В командной строке перейти в папку проекта
- Выполнить команду `docker build --tag access_controller:latest .`
- Выполнить команду
```bash
docker run -d -p 8000:8000 \
ACTRL_DEBUG={0/1} \
ACTRL_HOST={HOSTNAME} \
ACTRL_SECRET_KEY={DJANGO_SECRET_KEY} \
ACTRL_EMAIL_HOST={SMTP_HOST} \
ACTRL_EMAIL_PORT={SMTP_PORT} \
ACTRL_EMAIL_TLS={USE_TLS} \
ACTRL_EMAIL_HOST_USER={USERNAME} \
ACTRL_EMAIL_HOST_PASSWORD={PASSWORD} \
ACTRL_FROM_EMAIL={EMAIL} \
ACTRL_SERVER_EMAIL={EMAIL} \
ACTRL_API_EMAIL={EMAIL} \
ACTRL_API_PASSWORD={PASSWORD} \
ACTRL_API_TOKEN={API_TOKEN} \
ACTRL_ZENDESK_SUBDOMAIN={DOMAIN} \
ENG_CROLE_ID={ENGINEER_CUSTOM_ROLE_ID} \
LA_CROLE_ID={LIGHT_AGENT_CUSTOM_ROLE_ID} \
EMPL_GROUP={EMPLOYEE_GROUP_NAME} \
BUF_GROUP={BUFFER_GROUP_NAME} \
ST_EMAIL={SOLVED_TICKETS_EMAIL} \
LICENSE_NO={LICENSE_NO} \
SHIFTH={SHIFT_HOURS} \
-v {ABSOLUTE_PATH_TO_DB}:/zendesk-access-controller/db \
access_controller:latest
```
- открываем запущеный контейнер в браузере (можно перейти по ссылке http://localhost:8000/)
##Запуск в Docker: ## Запуск с тестовыми юзерами:
Требуется установленный и настроеный Docker На локальной машине - перед запуском команды `python manage.py runserver` выполнить команду `python manage.py loaddata data.json`
Это создаст тестового админа и тестового пользователя в приложении для песочницы ZenDesk.
скопировать репозиторий на локальную машину - Админ - `admin@gmail.com` / `zendeskadmin`
в командной строке перейти в папку проекта - Пользователь - `123@test.ru` / `zendeskuser`
выполнить команду docker build .
выполнить команду docker images (нам нужен id созданного образа) Не сработает если домен песочницы отличается от `ngenix1612197338` (на другом домене нужно будет создать сначала пользователей в песочнице с правами админа и легкого агента
выполнить команду docker run -d -p 8000:8000 -e ACCESS_CONTROLLER_API_EMAIL={EMAIL} -e ACCESS_CONTROLLER_API_PASSWORD={PASSWORD} с этими же почтами, назначить им организацию `SYSTEM`)
...(перечисляем все параметры виртуального окружени разделяя их -e) -v {абсолютный путь к папке, в которой будет размещена база}:/zendesk-access-controller/db {id образа докера}
открываем запущеный контейнер в браузере (можно перейти по ссылке http://localhost:8000/)
##Запуск с тестовыми юзерами: ## Параметры тестовой песочницы:
Пример полной конфигурации можно найти в [.env.example](.env.example). Почту и токен админа ZenDesk взять у руководителя (если вы не админ).
На локальной машине - перед запуском команды python manage.py runserver выполнить команду python manage.py loaddata data.json
Это создаст тестового админа и тестового пользователя в приложении для песочницы ZenDesk. Админ - admin@gmail.com / zendeskadmin , пользователь - 123@test.ru / zendeskuser .
Не сработает если домен песочницы отличается от ngenix1612197338 (на другом домене нужно будет создать сначала пользователей в песочнице с правами админа и легкого агента
с этими же почтами, назначить им организацию (SYSTEM))
##Параметры тестовой песочницы:
ACCESS_CONTROLLER_API_EMAIL={EMAIL} - почта админа в ZenDesk - взять у роководителя(если вы не админ)
ACCESS_CONTROLLER_API_PASSWORD={PASSWORD} - пароль админа ZenDesk - взять у роководителя(если вы не админ)
ACCESS_CONTROLLER_API_TOKEN={API_TOKEN} - API токен зендеск - взять у роководителя(если вы не админ)
ZD_DOMAIN=ngenix1612197338
ENG_CROLE_ID=360005209000
LA_CROLE_ID=360005208980
EMPL_GROUP=Поддержка
BUF_GROUP=Сменная группа
ST_EMAIL=d.krikov@ngenix.net
LICENSE_NO=3
SHIFTH=12
## Read more ## Read more

View File

@ -19,12 +19,16 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'v1i_fb$_jf2#1v_lcsbu&eon4u-os0^px=s^iycegdycqy&5)6' SECRET_KEY = os.getenv('ACTRL_SECRET_KEY','empty')
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = bool(int(os.getenv('ACTRL_DEBUG',1)))
ALLOWED_HOSTS = ['127.0.0.1'] ALLOWED_HOSTS = [
'127.0.0.1',
'localhost',
os.getenv('ACTRL_HOST'),
]
# Application definition # Application definition
@ -53,13 +57,13 @@ MIDDLEWARE = [
ROOT_URLCONF = 'access_controller.urls' ROOT_URLCONF = 'access_controller.urls'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST = os.getenv('ACTRL_EMAIL_HOST','smtp.gmail.com')
EMAIL_PORT = 587 EMAIL_PORT = int(os.getenv('ACTRL_EMAIL_PORT',587))
EMAIL_USE_TLS = True EMAIL_USE_TLS = bool(int(os.getenv('ACTRL_EMAIL_TLS',1)))
EMAIL_HOST_USER = 'group02django@gmail.com' EMAIL_HOST_USER = os.getenv('ACTRL_EMAIL_HOST_USER','group02django@gmail.com')
EMAIL_HOST_PASSWORD = 'djangogroup02' EMAIL_HOST_PASSWORD = os.getenv('ACTRL_EMAIL_HOST_PASSWORD','djangogroup02')
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER DEFAULT_FROM_EMAIL = os.getenv('ACTRL_FROM_EMAIL',EMAIL_HOST_USER)
SERVER_EMAIL = EMAIL_HOST_USER SERVER_EMAIL = os.getenv('ACTRL_SERVER_EMAIL',EMAIL_HOST_USER)
TEMPLATES = [ TEMPLATES = [
{ {
@ -87,7 +91,7 @@ WSGI_APPLICATION = 'access_controller.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3', 'NAME': BASE_DIR / 'db' / 'zd_db.sqlite3'
} }
} }
@ -146,18 +150,18 @@ AUTHENTICATION_BACKENDS = [
ZENDESK_ROLES = { ZENDESK_ROLES = {
'engineer': 360005209000, 'engineer': int(os.getenv('ENG_CROLE_ID',0)),
'light_agent': 360005208980, 'light_agent': int(os.getenv('LA_CROLE_ID',0)),
} }
ZENDESK_GROUPS = { ZENDESK_GROUPS = {
'employees': 'Поддержка', 'employees': os.getenv('EMPL_GROUP'),
'buffer': 'Сменная группа', 'buffer': os.getenv('BUF_GROUP'),
} }
SOLVED_TICKETS_EMAIL = 'd.krikov@ngenix.net' SOLVED_TICKETS_EMAIL = os.getenv('ST_EMAIL')
ZENDESK_MAX_AGENTS = 3 ZENDESK_MAX_AGENTS = int(os.getenv('LICENSE_NO',0))
REST_FRAMEWORK = { REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions, # Use Django's standard `django.contrib.auth` permissions,
@ -167,4 +171,9 @@ REST_FRAMEWORK = {
] ]
} }
ONE_DAY = 12 # Количество часов в 1 рабочем дне ONE_DAY = int(os.getenv('SHIFTH',0)) # Количество часов в 1 рабочем дне
ACTRL_ZENDESK_SUBDOMAIN = os.getenv('ACTRL_ZENDESK_SUBDOMAIN') or os.getenv('ZD_DOMAIN')
ACTRL_API_EMAIL = os.getenv('ACTRL_API_EMAIL') or os.getenv('ACCESS_CONTROLLER_API_EMAIL')
ACTRL_API_TOKEN = os.getenv('ACTRL_API_TOKEN') or os.getenv('ACCESS_CONTROLLER_API_TOKEN')
ACTRL_API_PASSWORD = os.getenv('ACTRL_API_PASSWORD') or os.getenv('ACCESS_CONTROLLER_API_PASSWORD')

View File

@ -1,7 +1,7 @@
[ [
{ {
"model": "auth.user", "model": "auth.user",
"pk": 3, "pk": 1,
"fields": { "fields": {
"password": "pbkdf2_sha256$216000$gHBBCr1jBELf$ZkEDW3IEd8Wij7u8vkv+0Eze32CS01bcaYWhcD9OIC4=", "password": "pbkdf2_sha256$216000$gHBBCr1jBELf$ZkEDW3IEd8Wij7u8vkv+0Eze32CS01bcaYWhcD9OIC4=",
"last_login": null, "last_login": null,
@ -19,16 +19,16 @@
}, },
{ {
"model": "main.userprofile", "model": "main.userprofile",
"pk": 3, "pk": 1,
"fields": { "fields": {
"name": "ZendeskAdmin", "name": "ZendeskAdmin",
"user": 3, "user": 1,
"role": "admin" "role": "admin"
} }
}, },
{ {
"model": "auth.user", "model": "auth.user",
"pk": 4, "pk": 2,
"fields": { "fields": {
"password": "pbkdf2_sha256$216000$5qLJgrm2Quq9$KDBNNymVZXkUx0HKBPFst2m83kLe0egPBnkW7KnkORU=", "password": "pbkdf2_sha256$216000$5qLJgrm2Quq9$KDBNNymVZXkUx0HKBPFst2m83kLe0egPBnkW7KnkORU=",
"last_login": null, "last_login": null,
@ -46,10 +46,10 @@
}, },
{ {
"model": "main.userprofile", "model": "main.userprofile",
"pk": 4, "pk": 2,
"fields": { "fields": {
"name": "UserForAccessTest", "name": "UserForAccessTest",
"user": 4, "user": 2,
"role": "agent", "role": "agent",
"custom_role_id": "360005209000" "custom_role_id": "360005209000"
} }

0
db/.gitkeep Normal file
View File

View File

@ -3,6 +3,8 @@ import os
from zenpy import Zenpy from zenpy import Zenpy
from zenpy.lib.api_objects import User as ZenpyUser from zenpy.lib.api_objects import User as ZenpyUser
from access_controller.settings import ACTRL_ZENDESK_SUBDOMAIN, ACTRL_API_EMAIL, ACTRL_API_TOKEN, ACTRL_API_PASSWORD
def api_auth() -> dict: def api_auth() -> dict:
""" """
@ -15,15 +17,15 @@ def api_auth() -> dict:
:return: данные пользователя :return: данные пользователя
""" """
credentials = { credentials = {
'subdomain': 'ngenix1612197338' 'subdomain': ACTRL_ZENDESK_SUBDOMAIN
} }
email = os.getenv('ACCESS_CONTROLLER_API_EMAIL') email = ACTRL_API_EMAIL
token = os.getenv('ACCESS_CONTROLLER_API_TOKEN') token = ACTRL_API_TOKEN
password = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') password = ACTRL_API_PASSWORD
if email is None: if email is None:
raise ValueError('access_controller email not in env') raise ValueError('access_controller email not in env')
credentials['email'] = os.getenv('ACCESS_CONTROLLER_API_EMAIL') credentials['email'] = email
# prefer token, use password if token not provided # prefer token, use password if token not provided
if token: if token:

View File

@ -9,7 +9,8 @@ from zenpy import Zenpy
from zenpy.lib.exception import APIException from zenpy.lib.exception import APIException
from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS, SOLVED_TICKETS_EMAIL from access_controller.settings import ZENDESK_ROLES as ROLES, ONE_DAY, ZENDESK_GROUPS, SOLVED_TICKETS_EMAIL, \
ACTRL_API_EMAIL, ACTRL_API_TOKEN, ACTRL_API_PASSWORD, ACTRL_ZENDESK_SUBDOMAIN
from main.models import UserProfile, RoleChangeLogs, UnassignedTicket, UnassignedTicketStatus from main.models import UserProfile, RoleChangeLogs, UnassignedTicket, UnassignedTicketStatus
@ -28,11 +29,11 @@ class ZendeskAdmin:
""" """
credentials: dict = { credentials: dict = {
'subdomain': 'ngenix1612197338' 'subdomain': ACTRL_ZENDESK_SUBDOMAIN
} }
email: str = os.getenv('ACCESS_CONTROLLER_API_EMAIL') email: str = ACTRL_API_EMAIL
token: str = os.getenv('ACCESS_CONTROLLER_API_TOKEN') token: str = ACTRL_API_TOKEN
password: str = os.getenv('ACCESS_CONTROLLER_API_PASSWORD') password: str = ACTRL_API_PASSWORD
def __init__(self): def __init__(self):
self.create_admin() self.create_admin()
@ -253,7 +254,7 @@ def check_user_auth(email: str, password: str) -> bool:
creds = { creds = {
'email': email, 'email': email,
'password': password, 'password': password,
'subdomain': 'ngenix1612197338', 'subdomain': ACTRL_ZENDESK_SUBDOMAIN,
} }
try: try:
user = Zenpy(**creds) user = Zenpy(**creds)

View File

@ -81,3 +81,4 @@ class UnassignedTicket(models.Model):
assignee = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='tickets', help_text='Пользователь, с которого снят тикет') assignee = models.ForeignKey(to=User, on_delete=models.CASCADE, related_name='tickets', help_text='Пользователь, с которого снят тикет')
ticket_id = models.IntegerField(help_text='Номер тикера, для которого сняли ответственного') ticket_id = models.IntegerField(help_text='Номер тикера, для которого сняли ответственного')
status = models.IntegerField(choices=UnassignedTicketStatus.choices, default=UnassignedTicketStatus.UNASSIGNED, help_text='Статус тикета') status = models.IntegerField(choices=UnassignedTicketStatus.choices, default=UnassignedTicketStatus.UNASSIGNED, help_text='Статус тикета')

View File

@ -1,15 +1 @@
# Engine -r requirements/dev.txt
Django==3.1.6
Pillow==8.1.0
zenpy~=2.0.24
django_registration==3.1.1
djangorestframework==3.12.2
daphne==3.0.1
# Documentation
Sphinx==3.4.3
sphinx-rtd-theme==0.5.1
sphinx-autodoc-typehints==1.11.1
pyenchant==3.2.0
sphinxcontrib-spelling==7.1.0

16
requirements/common.txt Normal file
View File

@ -0,0 +1,16 @@
# Contains requirements common to all environments
# Engine
Django==3.1.6
Pillow==8.1.0
zenpy~=2.0.24
django_registration==3.1.1
djangorestframework==3.12.2
# Documentation
Sphinx==3.4.3
sphinx-rtd-theme==0.5.1
sphinx-autodoc-typehints==1.11.1
pyenchant==3.2.0
sphinxcontrib-spelling==7.1.0

3
requirements/dev.txt Normal file
View File

@ -0,0 +1,3 @@
# Development specific dependencies
-r common.txt

5
requirements/prod.txt Normal file
View File

@ -0,0 +1,5 @@
# Production specific dependencies
-r common.txt
daphne==3.0.1
Twisted[tls,http2]==21.2.0

6
start.sh Normal file
View File

@ -0,0 +1,6 @@
cd /access_controller/
python manage.py migrate
python manage.py collectstatic --noinput
daphne -b 0.0.0.0 access_controller.asgi:application