ืกื“ื ืช RHEL 8 Beta: ื‘ื ื™ื™ืช ื™ื™ืฉื•ืžื™ ืื™ื ื˜ืจื ื˜ ืขื•ื‘ื“ื™ื

RHEL 8 Beta ืžืฆื™ืข ืœืžืคืชื—ื™ื ืชื›ื•ื ื•ืช ื—ื“ืฉื•ืช ืจื‘ื•ืช, ืฉื”ืจืฉื™ืžื” ืฉืœื”ืŸ ืขืฉื•ื™ื” ืœืงื—ืช ื“ืคื™ื, ืขื ื–ืืช, ืœืžื™ื“ื” ืฉืœ ื“ื‘ืจื™ื ื—ื“ืฉื™ื ื”ื™ื ืชืžื™ื“ ื˜ื•ื‘ื” ื™ื•ืชืจ ื‘ืคื•ืขืœ, ืื– ืœื”ืœืŸ ืื ื• ืžืฆื™ืขื™ื ืกื“ื ื” ืœื™ืฆื™ืจืช ืชืฉืชื™ืช ืืคืœื™ืงืฆื™ื” ื”ืžื‘ื•ืกืกืช ืขืœ Red Hat Enterprise Linux 8 Beta.

ืกื“ื ืช RHEL 8 Beta: ื‘ื ื™ื™ืช ื™ื™ืฉื•ืžื™ ืื™ื ื˜ืจื ื˜ ืขื•ื‘ื“ื™ื

ื‘ื•ืื• ื ื™ืงื— ืืช Python, ืฉืคืช ืชื›ื ื•ืช ืคื•ืคื•ืœืจื™ืช ื‘ืงืจื‘ ืžืคืชื—ื™ื, ื›ื‘ืกื™ืก, ืฉื™ืœื•ื‘ ืฉืœ Django ื•-PostgreSQL, ืฉื™ืœื•ื‘ ื ืคื•ืฅ ืœืžื“ื™ ืœื™ืฆื™ืจืช ืืคืœื™ืงืฆื™ื•ืช, ื•ื ืงื‘ืข ืืช RHEL 8 Beta ืœืขื‘ื•ื“ ืื™ืชื. ืœืื—ืจ ืžื›ืŸ ื ื•ืกื™ืฃ ืขื•ื“ ื›ืžื” ืžืจื›ื™ื‘ื™ื (ืœื ืžืกื•ื•ื’ื™ื).

ืกื‘ื™ื‘ืช ื”ื‘ื“ื™ืงื” ืชืฉืชื ื”, ื›ื™ ืžืขื ื™ื™ืŸ ืœื—ืงื•ืจ ืืช ื”ืืคืฉืจื•ื™ื•ืช ืฉืœ ืื•ื˜ื•ืžืฆื™ื”, ืขื‘ื•ื“ื” ืขื ืงื•ื ื˜ื™ื™ื ืจื™ื ื•ื ื™ืกื™ื•ืŸ ืฉืœ ืกื‘ื™ื‘ื•ืช ืขื ืžืกืคืจ ืฉืจืชื™ื. ื›ื“ื™ ืœื”ืชื—ื™ืœ ืขื ืคืจื•ื™ืงื˜ ื—ื“ืฉ, ืืชื” ื™ื›ื•ืœ ืœื”ืชื—ื™ืœ ื‘ื™ืฆื™ืจืช ืื‘ ื˜ื™ืคื•ืก ืงื˜ืŸ ื•ืคืฉื•ื˜ ื‘ื™ื“ ื›ื“ื™ ืฉืชื•ื›ืœ ืœืจืื•ืช ื‘ื“ื™ื•ืง ืžื” ืฆืจื™ืš ืœืงืจื•ืช ื•ืื™ืš ื”ื•ื ืžืงื™ื™ื ืื™ื ื˜ืจืืงืฆื™ื”, ื•ืœืื—ืจ ืžื›ืŸ ืœืขื‘ื•ืจ ืœืื•ื˜ื•ืžืฆื™ื” ื•ืœื™ืฆื•ืจ ืชืฆื•ืจื•ืช ืžื•ืจื›ื‘ื•ืช ื™ื•ืชืจ. ื”ื™ื•ื ืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ื™ืฆื™ืจืช ืื‘ ื˜ื™ืคื•ืก ื›ื–ื”.

ื ืชื—ื™ืœ ื‘ืคืจื™ืกืช ืชืžื•ื ืช RHEL 8 Beta VM. ืืชื” ื™ื›ื•ืœ ืœื”ืชืงื™ืŸ ืžื›ื•ื ื” ื•ื™ืจื˜ื•ืืœื™ืช ืžืืคืก, ืื• ืœื”ืฉืชืžืฉ ื‘ืชืžื•ื ืช ืื•ืจื— KVM ื”ื–ืžื™ื ื” ืขื ืžื ื•ื™ ื”ื‘ื™ื˜ื ืฉืœืš. ื‘ืขืช ืฉื™ืžื•ืฉ ื‘ืชืžื•ื ืช ืื•ืจื—, ืชืฆื˜ืจืš ืœื”ื’ื“ื™ืจ ืชืงืœื™ื˜ื•ืจ ื•ื™ืจื˜ื•ืืœื™ ืฉื™ื›ื™ืœ ืžื˜ื ื ืชื•ื ื™ื ื•ื ืชื•ื ื™ ืžืฉืชืžืฉ ืœืืชื—ื•ืœ ืขื ืŸ (cloud-init). ืืชื” ืœื ืฆืจื™ืš ืœืขืฉื•ืช ืฉื•ื ื“ื‘ืจ ืžื™ื•ื—ื“ ืขื ืžื‘ื ื” ื”ื“ื™ืกืง ืื• ื”ื—ื‘ื™ืœื•ืช ื”ื–ืžื™ื ื•ืช; ื›ืœ ืชืฆื•ืจื” ืชืชืื™ื.

ื‘ื•ืื• ื ืกืชื›ืœ ืžืงืจื•ื‘ ืขืœ ื›ืœ ื”ืชื”ืœื™ืš.

ื”ืชืงื ืช ื’'ื ื’ื•

ืขื ื”ื’ืจืกื” ื”ื—ื“ืฉื” ื‘ื™ื•ืชืจ ืฉืœ Django, ืชื–ื“ืงืง ืœืกื‘ื™ื‘ื” ื•ื™ืจื˜ื•ืืœื™ืช (virtualenv) ืขื Python 3.5 ื•ืื™ืœืš. ื‘ื”ืขืจื•ืช ื”ื‘ื˜ื ืชื•ื›ืœื• ืœืจืื•ืช ืฉ-Python 3.6 ื–ืžื™ืŸ, ื‘ื•ืื• ื ื‘ื“ื•ืง ืื ื–ื” ืื›ืŸ ื”ืžืงืจื”:

[cloud-user@8beta1 ~]$ python
-bash: python: command not found
[cloud-user@8beta1 ~]$ python3
-bash: python3: command not found

Red Hat ืžืฉืชืžืฉ ื‘ืื•ืคืŸ ืคืขื™ืœ ื‘-Python ื›ืขืจื›ืช ื›ืœื™ื ืžืขืจื›ืชื™ืช ื‘-RHEL, ืื– ืœืžื” ื–ื” ืชื•ืฆืื”?

ื”ืขื•ื‘ื“ื” ื”ื™ื ืฉืžืคืชื—ื™ Python ืจื‘ื™ื ืขื“ื™ื™ืŸ ืฉื•ืงืœื™ื ืืช ื”ืžืขื‘ืจ ืž-Python 2 ืœืคื™ื™ืชื•ืŸ 2, ื‘ืขื•ื“ ืฉ-Python 3 ืขืฆืžื• ื ืžืฆื ื‘ืคื™ืชื•ื— ืคืขื™ืœ, ื•ืขื•ื“ ื•ืขื•ื“ ื’ืจืกืื•ืช ื—ื“ืฉื•ืช ืžื•ืคื™ืขื•ืช ืœืœื ื”ืจืฃ. ืœื›ืŸ, ื›ื“ื™ ืœืขื ื•ืช ืขืœ ื”ืฆื•ืจืš ื‘ื›ืœื™ ืžืขืจื›ืช ื™ืฆื™ื‘ื™ื ืชื•ืš ืžืชืŸ ื’ื™ืฉื” ืœืžืฉืชืžืฉื™ื ืœื’ืจืกืื•ืช ื—ื“ืฉื•ืช ืฉื•ื ื•ืช ืฉืœ Python, ืžืขืจื›ืช Python ื”ื•ืขื‘ืจื” ืœื—ื‘ื™ืœื” ื—ื“ืฉื” ื•ืกื™ืคืงื” ืืช ื”ื™ื›ื•ืœืช ืœื”ืชืงื™ืŸ ื’ื Python 2.7 ื•ื’ื 3.6. ืžื™ื“ืข ื ื•ืกืฃ ืขืœ ื”ืฉื™ื ื•ื™ื™ื ื•ืžื“ื•ืข ื‘ื•ืฆืขื• ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืคืจืกื•ื ื‘ ื”ื‘ืœื•ื’ ืฉืœ ืœื ื’ื“ื•ืŸ ื•ื•ื™ื™ื˜ (ืœื ื’ื“ื•ืŸ ื•ื•ื™ื™ื˜).

ืื– ื›ื“ื™ ืœื”ืชื—ื™ืœ ืœืขื‘ื•ื“ ื‘-Python, ืืชื” ืจืง ืฆืจื™ืš ืœื”ืชืงื™ืŸ ืฉืชื™ ื—ื‘ื™ืœื•ืช, ืขื python3-pip ื›ืœื•ืœื” ื›ืชืœื•ืช.

sudo yum install python36 python3-virtualenv

ืœืžื” ืœื ืœื”ืฉืชืžืฉ ื‘ืงืจื™ืื•ืช ืžื•ื“ื•ืœ ื™ืฉื™ืจื•ืช ื›ืคื™ ืฉืœื ื’ื“ื•ืŸ ืžืฆื™ืข ื•ืœื”ืชืงื™ืŸ pip3? ื‘ื”ืชื—ืฉื‘ ื‘ืื•ื˜ื•ืžืฆื™ื” ื”ืงืจื•ื‘ื”, ื™ื“ื•ืข ืฉ-Ansible ื™ื“ืจื•ืฉ ื”ืชืงื ืช pip ื›ื“ื™ ืœืคืขื•ืœ, ืžื›ื™ื•ื•ืŸ ืฉืžื•ื“ื•ืœ ื”-pip ืื™ื ื• ืชื•ืžืš ื‘-virtualenvs ืขื ืงื•ื‘ืฅ ื”ืคืขืœื” ืžื•ืชืื ืื™ืฉื™ืช ืฉืœ pip.

ืขื ืžืชื•ืจื’ืžืŸ python3 ืขื•ื‘ื“ ืœืจืฉื•ืชื›ื, ืชื•ื›ืœื• ืœื”ืžืฉื™ืš ื‘ืชื”ืœื™ืš ื”ื”ืชืงื ื” ืฉืœ Django ื•ืœืงื‘ืœ ืžืขืจื›ืช ืขื•ื‘ื“ืช ื™ื—ื“ ืขื ืฉืืจ ื”ืจื›ื™ื‘ื™ื ืฉืœื ื•. ื™ืฉื ืŸ ืืคืฉืจื•ื™ื•ืช ื™ื™ืฉื•ื ืจื‘ื•ืช ื”ื–ืžื™ื ื•ืช ื‘ืื™ื ื˜ืจื ื˜. ื™ืฉ ื›ืืŸ ื’ืจืกื” ืื—ืช, ืืš ืžืฉืชืžืฉื™ื ื™ื›ื•ืœื™ื ืœื”ืฉืชืžืฉ ื‘ืชื”ืœื™ื›ื™ื ืžืฉืœื”ื.

ื ืชืงื™ืŸ ืืช ื’ืจืกืื•ืช PostgreSQL ื•-Nginx ื”ื–ืžื™ื ื•ืช ื‘-RHEL 8 ื›ื‘ืจื™ืจืช ืžื—ื“ืœ ื‘ืืžืฆืขื•ืช Yum.

sudo yum install nginx postgresql-server

PostgreSQL ื™ื“ืจื•ืฉ psycopg2, ืื‘ืœ ื”ื•ื ืฆืจื™ืš ืœื”ื™ื•ืช ื–ืžื™ืŸ ืจืง ื‘ืกื‘ื™ื‘ืช Virtualenv, ืื– ื ืชืงื™ืŸ ืื•ืชื• ื‘ืืžืฆืขื•ืช pip3 ื™ื—ื“ ืขื Django ื•-Gunicorn. ืื‘ืœ ืชื—ื™ืœื” ืขืœื™ื ื• ืœื”ื’ื“ื™ืจ ืืช virtualenv.

ืชืžื™ื“ ื™ืฉ ื”ืจื‘ื” ื•ื™ื›ื•ื—ื™ื ื‘ื ื•ืฉื ื‘ื—ื™ืจืช ื”ืžืงื•ื ื”ื ื›ื•ืŸ ืœื”ืชืงื ืช ืคืจื•ื™ืงื˜ื™ Django, ืืš ื›ืืฉืจ ื™ืฉ ืกืคืง, ืืชื” ืชืžื™ื“ ื™ื›ื•ืœ ืœืคื ื•ืช ืœืชืงืŸ ื”ื”ื™ืจืจื›ื™ื” ืฉืœ ืžืขืจื›ืช ื”ืงื‘ืฆื™ื ืฉืœ ืœื™ื ื•ืงืก. ื‘ืื•ืคืŸ ืกืคืฆื™ืคื™, ื”-FHS ืื•ืžืจ ืฉ-/srv ืžืฉืžืฉ ืœ: "ืœืื—ืกืŸ ื ืชื•ื ื™ื ืกืคืฆื™ืคื™ื™ื ืœืžืืจื— - ื ืชื•ื ื™ื ืฉื”ืžืขืจื›ืช ืžื™ื™ืฆืจืช, ื›ื’ื•ืŸ ื ืชื•ื ื™ื ื•ืกืงืจื™ืคื˜ื™ื ืฉืœ ืฉืจืช ืื™ื ื˜ืจื ื˜, ื ืชื•ื ื™ื ื”ืžืื•ื—ืกื ื™ื ื‘ืฉืจืชื™ FTP ื•ื‘ืงืจื” ืขืœ ืžืื’ืจื™ ืžืขืจื›ืช." ื’ืจืกืื•ืช (ืžื•ืคื™ืขื•ืช ื‘-FHS -2.3 ื‘ืฉื ืช 2004)."

ื–ื” ื‘ื“ื™ื•ืง ื”ืžืงืจื” ืฉืœื ื•, ืื– ืื ื—ื ื• ืžื›ื ื™ืกื™ื ืืช ื›ืœ ืžื” ืฉืื ื—ื ื• ืฆืจื™ื›ื™ื ืœืชื•ืš /srv, ืฉื”ื•ื ื‘ื‘ืขืœื•ืช ืžืฉืชืžืฉ ื”ืืคืœื™ืงืฆื™ื” ืฉืœื ื• (Cloud-User).

sudo mkdir /srv/djangoapp
sudo chown cloud-user:cloud-user /srv/djangoapp
cd /srv/djangoapp
virtualenv django
source django/bin/activate
pip3 install django gunicorn psycopg2
./django-admin startproject djangoapp /srv/djangoapp

ื”ื’ื“ืจืช PostgreSQL ื•-Django ื”ื™ื ืงืœื”: ืฆื•ืจ ืžืกื“ ื ืชื•ื ื™ื, ืฆื•ืจ ืžืฉืชืžืฉ, ื”ื’ื“ืจ ื”ืจืฉืื•ืช. ื“ื‘ืจ ืื—ื“ ืฉื™ืฉ ืœื–ื›ื•ืจ ื‘ืขืช ื”ืชืงื ืช PostgreSQL ืœืจืืฉื•ื ื” ื”ื•ื ืกืงืจื™ืคื˜ postgresql-setup ืฉืžื•ืชืงืŸ ืขื ื—ื‘ื™ืœืช postgresql-server. ืกืงืจื™ืคื˜ ื–ื” ืขื•ื–ืจ ืœืš ืœื‘ืฆืข ืžืฉื™ืžื•ืช ื‘ืกื™ืกื™ื•ืช ื”ืงืฉื•ืจื•ืช ืœื ื™ื”ื•ืœ ืืฉื›ื•ืœ ืžืกื“ ื ืชื•ื ื™ื, ื›ื’ื•ืŸ ืืชื—ื•ืœ ืืฉื›ื•ืœ ืื• ืชื”ืœื™ืš ื”ืฉื“ืจื•ื’. ื›ื“ื™ ืœื”ื’ื“ื™ืจ ืžื•ืคืข PostgreSQL ื—ื“ืฉ ื‘ืžืขืจื›ืช RHEL, ืขืœื™ื ื• ืœื”ืคืขื™ืœ ืืช ื”ืคืงื•ื“ื”:

sudo /usr/bin/postgresql-setup -initdb

ืœืื—ืจ ืžื›ืŸ ืชื•ื›ืœ ืœื”ืคืขื™ืœ ืืช PostgreSQL ื‘ืืžืฆืขื•ืช systemd, ืœื™ืฆื•ืจ ืžืกื“ ื ืชื•ื ื™ื ื•ืœื”ื’ื“ื™ืจ ืคืจื•ื™ืงื˜ ื‘-Django. ื–ื›ื•ืจ ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช PostgreSQL ืœืื—ืจ ื‘ื™ืฆื•ืข ืฉื™ื ื•ื™ื™ื ื‘ืงื•ื‘ืฅ ื”ืชืฆื•ืจื” ืฉืœ ืื™ืžื•ืช ื”ืœืงื•ื— (ื‘ื“ืจืš ื›ืœืœ pg_hba.conf) ื›ื“ื™ ืœื”ื’ื“ื™ืจ ืื—ืกื•ืŸ ืกื™ืกืžืื•ืช ืขื‘ื•ืจ ืžืฉืชืžืฉ ื”ืืคืœื™ืงืฆื™ื”. ืื ืืชื” ื ืชืงืœ ื‘ืงืฉื™ื™ื ืื—ืจื™ื, ื”ืงืคื“ ืœืฉื ื•ืช ืืช ื”ื’ื“ืจื•ืช IPv4 ื•-IPv6 ื‘ืงื•ื‘ืฅ pg_hba.conf.

systemctl enable -now postgresql

sudo -u postgres psql
postgres=# create database djangoapp;
postgres=# create user djangouser with password 'qwer4321';
postgres=# alter role djangouser set client_encoding to 'utf8';
postgres=# alter role djangouser set default_transaction_isolation to 'read committed';
postgres=# alter role djangouser set timezone to 'utc';
postgres=# grant all on DATABASE djangoapp to djangouser;
postgres=# q

ื‘ืงื•ื‘ืฅ /var/lib/pgsql/data/pg_hba.conf:

# IPv4 local connections:
host    all        all 0.0.0.0/0                md5
# IPv6 local connections:
host    all        all ::1/128                 md5

ื‘ืงื•ื‘ืฅ /srv/djangoapp/settings.py:

# Database
DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'NAME': '{{ db_name }}',
       'USER': '{{ db_user }}',
       'PASSWORD': '{{ db_password }}',
       'HOST': '{{ db_host }}',
   }
}

ืœืื—ืจ ื”ื’ื“ืจืช ืงื•ื‘ืฅ settings.py ื‘ืคืจื•ื™ืงื˜ ื•ื”ื’ื“ืจืช ืชืฆื•ืจืช ืžืกื“ ื”ื ืชื•ื ื™ื, ืชื•ื›ืœ ืœื”ืคืขื™ืœ ืืช ืฉืจืช ื”ืคื™ืชื•ื— ื›ื“ื™ ืœื•ื•ื“ื ืฉื”ื›ืœ ืขื•ื‘ื“. ืœืื—ืจ ื”ืคืขืœืช ืฉืจืช ื”ืคื™ืชื•ื—, ื›ื“ืื™ ืœื™ืฆื•ืจ ืžืฉืชืžืฉ ืื“ืžื™ืŸ ืขืœ ืžื ืช ืœื‘ื“ื•ืง ืืช ื”ื—ื™ื‘ื•ืจ ืœืžืกื“ ื”ื ืชื•ื ื™ื.

./manage.py runserver 0.0.0.0:8000
./manage.py createsuperuser

WSGI? ื•ื•ืื™?

ืฉืจืช ื”ืคื™ืชื•ื— ืฉื™ืžื•ืฉื™ ืœื‘ื“ื™ืงื”, ืืš ื›ื“ื™ ืœื”ืคืขื™ืœ ืืช ื”ื™ื™ืฉื•ื ืขืœื™ืš ืœื”ื’ื“ื™ืจ ืืช ื”ืฉืจืช ื•ื”-proxy ื”ืžืชืื™ืžื™ื ืขื‘ื•ืจ ืžืžืฉืง ื”-Web Server Gateway (WSGI). ื™ืฉื ื ืžืกืคืจ ืฉื™ืœื•ื‘ื™ื ื ืคื•ืฆื™ื, ืœืžืฉืœ, Apache HTTPD ืขื uWSGI ืื• Nginx ืขื Gunicorn.

ืชืคืงื™ื“ื• ืฉืœ ืžืžืฉืง ืฉืขืจ ื”ืื™ื ื˜ืจื ื˜ ืฉืœ ืฉืจืช ื”ืื™ื ื˜ืจื ื˜ ื”ื•ื ืœื”ืขื‘ื™ืจ ื‘ืงืฉื•ืช ืžืฉืจืช ื”ืื™ื ื˜ืจื ื˜ ืœืžืกื’ืจืช ื”ืื™ื ื˜ืจื ื˜ ืฉืœ Python. WSGI ื”ื•ื ืฉืจื™ื“ ืžื”ืขื‘ืจ ื”ื ื•ืจื ื›ืฉืžื ื•ืขื™ CGI ื”ื™ื• ื‘ืกื‘ื™ื‘ื”, ื•ื›ื™ื•ื WSGI ื”ื•ื ื”ืชืงืŸ ื“ื” ืคืงื˜ื•, ืœืœื ืงืฉืจ ืœืฉืจืช ื”ืื™ื ื˜ืจื ื˜ ืื• ื”ืžืกื’ืจืช ืฉืœ Python ื‘ืฉื™ืžื•ืฉ. ืืš ืœืžืจื•ืช ื”ืฉื™ืžื•ืฉ ื”ื ืจื—ื‘ ื‘ื•, ืขื“ื™ื™ืŸ ื™ืฉื ื ื ื™ื•ืื ืกื™ื ืจื‘ื™ื ื‘ืขื‘ื•ื“ื” ืขื ืžืกื’ืจื•ืช ืืœื•, ื•ืืคืฉืจื•ื™ื•ืช ืจื‘ื•ืช. ื‘ืžืงืจื” ื–ื”, ื ื ืกื” ืœื™ืฆื•ืจ ืื™ื ื˜ืจืืงืฆื™ื” ื‘ื™ืŸ Gunicorn ืœ-Nginx ื‘ืืžืฆืขื•ืช ืฉืงืข.

ืžื›ื™ื•ื•ืŸ ืฉืฉื ื™ ื”ืจื›ื™ื‘ื™ื ื”ืœืœื• ืžื•ืชืงื ื™ื ืขืœ ืื•ืชื• ืฉืจืช, ื‘ื•ืื• ื ื ืกื” ืœื”ืฉืชืžืฉ ื‘ืฉืงืข UNIX ื‘ืžืงื•ื ื‘ืฉืงืข ืจืฉืช. ืžื›ื™ื•ื•ืŸ ืฉืชืงืฉื•ืจืช ืžืฆืจื™ื›ื” ืฉืงืข ื‘ื›ืœ ืžืงืจื”, ื‘ื•ืื• ื ื ืกื” ืœืขืฉื•ืช ืขื•ื“ ืฆืขื“ ืื—ื“ ื•ืœื”ื’ื“ื™ืจ ืืช ื”ืคืขืœืช ื”ืฉืงืข ืขื‘ื•ืจ Gunicorn ื‘ืืžืฆืขื•ืช systemd.

ื”ืชื”ืœื™ืš ืฉืœ ื™ืฆื™ืจืช ืฉื™ืจื•ืชื™ื ืžื•ืคืขืœื™ื ื‘ืฉืงืข ื”ื•ื ื“ื™ ืคืฉื•ื˜. ืจืืฉื™ืช, ื ื•ืฆืจ ืงื•ื‘ืฅ ื™ื—ื™ื“ื” ื”ืžื›ื™ืœ ื”ื ื—ื™ื™ืช ListenStream ื”ืžืฆื‘ื™ืขื” ืขืœ ื”ื ืงื•ื“ื” ื‘ื” ื™ื™ื•ื•ืฆืจ ืฉืงืข ื”-UNIX, ืœืื—ืจ ืžื›ืŸ ืงื•ื‘ืฅ ื™ื—ื™ื“ื” ืขื‘ื•ืจ ื”ืฉื™ืจื•ืช ืฉื‘ื• ื”ื”ื ื—ื™ื” Requires ืชืฆื‘ื™ืข ืขืœ ืงื•ื‘ืฅ ื™ื—ื™ื“ืช ื”ืฉืงืข. ืœืื—ืจ ืžื›ืŸ, ื‘ืงื•ื‘ืฅ ื™ื—ื™ื“ืช ื”ืฉื™ืจื•ืช, ื›ืœ ืฉื ื•ืชืจ ื”ื•ื ืœื”ืชืงืฉืจ ืœ-Gunicorn ืžื”ืกื‘ื™ื‘ื” ื”ื•ื•ื™ืจื˜ื•ืืœื™ืช ื•ืœื™ืฆื•ืจ ื›ืจื™ื›ืช WSGI ืขื‘ื•ืจ ืฉืงืข UNIX ื•ืืคืœื™ืงืฆื™ื™ืช Django.

ืœื”ืœืŸ ื›ืžื” ื“ื•ื’ืžืื•ืช ืœืงื‘ืฆื™ ื™ื—ื™ื“ื” ืฉืชื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ื”ื ื›ื‘ืกื™ืก. ืจืืฉื™ืช ื”ื’ื“ืจื ื• ืืช ื”ืฉืงืข.

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

ืขื›ืฉื™ื• ืืชื” ืฆืจื™ืš ืœื”ื’ื“ื™ืจ ืืช ื”ื“ืžื•ืŸ Gunicorn.

[Unit]
Description=Gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=cloud-user
Group=cloud-user
WorkingDirectory=/srv/djangoapp

ExecStart=/srv/djangoapp/django/bin/gunicorn 
         โ€”access-logfile - 
         โ€”workers 3 
         โ€”bind unix:gunicorn.sock djangoapp.wsgi

[Install]
WantedBy=multi-user.target

ืขื‘ื•ืจ Nginx, ื–ื” ืขื ื™ื™ืŸ ืคืฉื•ื˜ ืฉืœ ื™ืฆื™ืจืช ืงื‘ืฆื™ ืชืฆื•ืจืช proxy ื•ื”ื’ื“ืจืช ืกืคืจื™ื™ื” ืœืื—ืกื•ืŸ ืชื•ื›ืŸ ืกื˜ื˜ื™ ืื ืืชื” ืžืฉืชืžืฉ ื‘ืื—ื“. ื‘-RHEL, ืงื•ื‘ืฆื™ ื”ืชืฆื•ืจื” ืฉืœ Nginx ื ืžืฆืื™ื ื‘- /etc/nginx/conf.d. ืืชื” ื™ื›ื•ืœ ืœื”ืขืชื™ืง ืืช ื”ื“ื•ื’ืžื” ื”ื‘ืื” ืœืงื•ื‘ืฅ /etc/nginx/conf.d/default.conf ื•ืœื”ืคืขื™ืœ ืืช ื”ืฉื™ืจื•ืช. ื”ืงืคื“ ืœื”ื’ื“ื™ืจ ืืช server_name ื›ืš ืฉื™ืชืื™ื ืœืฉื ื”ืžืืจื— ืฉืœืš.

server {
   listen 80;
   server_name 8beta1.example.com;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /srv/djangoapp;
   }

   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_pass http://unix:/run/gunicorn.sock;
   }
}

ื”ืคืขืœ ืืช ืฉืงืข Gunicorn ื•ืืช Nginx ื‘ืืžืฆืขื•ืช systemd ื•ืืชื” ืžื•ื›ืŸ ืœื”ืชื—ื™ืœ ื‘ื‘ื“ื™ืงื”.

ืฉื’ื™ืืช ืฉืขืจ ื’ืจื•ืข?

ืื ืชื–ื™ืŸ ืืช ื”ื›ืชื•ื‘ืช ื‘ื“ืคื“ืคืŸ ืฉืœืš, ืกื‘ื™ืจ ืœื”ื ื™ื— ืฉืชืงื‘ืœ ืฉื’ื™ืืช 502 Bad Gateway. ื–ื” ืขืฉื•ื™ ืœื”ื™ื’ืจื ืžื”ืจืฉืื•ืช ืฉืงืข UNIX ืฉื”ื•ื’ื“ืจื• ื‘ืฆื•ืจื” ืฉื’ื•ื™ื”, ืื• ืฉื–ื” ืขืฉื•ื™ ืœื ื‘ื•ืข ืžื‘ืขื™ื•ืช ืžื•ืจื›ื‘ื•ืช ื™ื•ืชืจ ื”ืงืฉื•ืจื•ืช ืœื‘ืงืจืช ื’ื™ืฉื” ื‘-SELinux.

ื‘ื™ื•ืžืŸ ื”ืฉื’ื™ืื•ืช ืฉืœ nginx ืืชื” ื™ื›ื•ืœ ืœืจืื•ืช ืฉื•ืจื” ื›ื–ื•:

2018/12/18 15:38:03 [crit] 12734#0: *3 connect() to unix:/run/gunicorn.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.122.1, server: 8beta1.example.com, request: "GET / HTTP/1.1", upstream: "http://unix:/run/gunicorn.sock:/", host: "8beta1.example.com"

ืื ื ื‘ื“ื•ืง ืืช Gunicorn ื™ืฉื™ืจื•ืช, ื ืงื‘ืœ ืชืฉื•ื‘ื” ืจื™ืงื”.

curl โ€”unix-socket /run/gunicorn.sock 8beta1.example.com

ื‘ื•ืื• ื ื‘ื™ืŸ ืœืžื” ื–ื” ืงื•ืจื”. ืื ืชืคืชื— ืืช ื”ื™ื•ืžืŸ, ืกื‘ื™ืจ ืœื”ื ื™ื— ืฉืชืจืื” ืฉื”ื‘ืขื™ื” ืงืฉื•ืจื” ืœ-SELinux. ืžื›ื™ื•ื•ืŸ ืฉืื ื• ืžืคืขื™ืœื™ื ื“ืžื•ืŸ ืฉืœื ื ื•ืฆืจื” ืขื‘ื•ืจื• ืžื“ื™ื ื™ื•ืช, ื”ื•ื ืžืกื•ืžืŸ ื›-init_t. ื‘ื•ืื• ื ื‘ื“ื•ืง ืืช ื”ืชื™ืื•ืจื™ื” ื”ื–ื• ื‘ืคื•ืขืœ.

sudo setenforce 0

ื›ืœ ื–ื” ืขืœื•ืœ ืœื’ืจื•ื ืœื‘ื™ืงื•ืจืช ื•ื“ืžืขื•ืช ืฉืœ ื“ื, ืื‘ืœ ื–ื” ืจืง ื ื™ืคื•ื™ ืื‘ื˜ื™ืคื•ืก. ื‘ื•ื ื ื ื˜ืจืœ ืืช ื”ืฆ'ืง ืจืง ื›ื“ื™ ืœื•ื•ื“ื ืฉื–ื• ื”ื‘ืขื™ื” ื•ืœืื—ืจ ืžื›ืŸ ื ื—ื–ื™ืจ ื”ื›ืœ ืœืžืงื•ืžื•.

ืขืœ ื™ื“ื™ ืจืขื ื•ืŸ ื”ื“ืฃ ื‘ื“ืคื“ืคืŸ ืื• ื”ืคืขืœื” ื—ื•ื–ืจืช ืฉืœ ืคืงื•ื“ืช ื”ืกืœืกื•ืœ ืฉืœื ื•, ืชื•ื›ืœ ืœืจืื•ืช ืืช ื“ืฃ ื”ื‘ื“ื™ืงื” ืฉืœ Django.

ืื–, ืœืื—ืจ ืฉื•ื•ื™ื“ืืชื ืฉื”ื›ืœ ืขื•ื‘ื“ ื•ืฉืื™ืŸ ืขื•ื“ ื‘ืขื™ื•ืช ื”ืจืฉืื”, ืื ื• ืžืคืขื™ืœื™ื ืืช SELinux ืฉื•ื‘.

sudo setenforce 1

ืื™ืŸ ื›ืืŸ ื“ื™ื‘ื•ืจ ืขืœ audit2allow ืื• ืขืœ ื™ืฆื™ืจืช ืžื“ื™ื ื™ื•ืช ืžื‘ื•ืกืกืช ื”ืชืจืื•ืช ืขื sepolgen, ืžื›ื™ื•ื•ืŸ ืฉื›ืจื’ืข ืื™ืŸ ืืคืœื™ืงืฆื™ื™ืช Django ืืžื™ืชื™ืช, ื›ืš ืฉืื™ืŸ ืžืคื” ืฉืœืžื” ืฉืœ ืžื” ืฉ-Gunicorn ืขืฉื•ื™ ืœืจืฆื•ืช ืœื’ืฉืช ื•ืœืžื” ืขืœื™ื• ืœืžื ื•ืข ื’ื™ืฉื”. ืœื›ืŸ, ื™ืฉ ืฆื•ืจืš ืœื”ืฉืื™ืจ ืืช SELinux ืคื•ืขืœ ื›ื“ื™ ืœื”ื’ืŸ ืขืœ ื”ืžืขืจื›ืช, ื•ื‘ื• ื‘ื–ืžืŸ ืœืืคืฉืจ ืœืืคืœื™ืงืฆื™ื” ืœืคืขื•ืœ ื•ืœื”ืฉืื™ืจ ื”ื•ื“ืขื•ืช ื‘ื™ื•ืžืŸ ื”ื‘ื™ืงื•ืจืช, ื›ืš ืฉื ื™ืชืŸ ื™ื”ื™ื” ืœื™ืฆื•ืจ ืžื”ืŸ ืืช ื”ืžื“ื™ื ื™ื•ืช ื‘ืคื•ืขืœ.

ืฆื™ื•ืŸ ืชื—ื•ืžื™ื ืžืชื™ืจื™ื

ืœื ื›ื•ืœื ืฉืžืขื• ืขืœ ื“ื•ืžื™ื™ื ื™ื ืžื•ืชืจื™ื ื‘-SELinux, ืื‘ืœ ื”ื ืœื ื—ื“ืฉื™ื. ืจื‘ื™ื ืืคื™ืœื• ืขื‘ื“ื• ืื™ืชื ืžื‘ืœื™ ืœื”ื‘ื™ืŸ ื–ืืช. ื›ืืฉืจ ืžื“ื™ื ื™ื•ืช ื ื•ืฆืจืช ืขืœ ืกืžืš ื”ื•ื“ืขื•ืช ื‘ื™ืงื•ืจืช, ื”ืžื“ื™ื ื™ื•ืช ืฉื ื•ืฆืจื” ืžื™ื™ืฆื’ืช ืืช ื”ืชื—ื•ื ืฉื ืคืชืจ. ื‘ื•ืื• ื ื ืกื” ืœื™ืฆื•ืจ ืžื“ื™ื ื™ื•ืช ืื™ืฉื•ืจ ืคืฉื•ื˜ื”.

ื›ื“ื™ ืœื™ืฆื•ืจ ื“ื•ืžื™ื™ืŸ ืžื•ืชืจ ืกืคืฆื™ืคื™ ืขื‘ื•ืจ Gunicorn, ืืชื” ืฆืจื™ืš ืกื•ื’ ืฉืœ ืžื“ื™ื ื™ื•ืช, ื•ืืชื” ืฆืจื™ืš ื’ื ืœืกืžืŸ ืืช ื”ืงื‘ืฆื™ื ื”ืžืชืื™ืžื™ื. ื‘ื ื•ืกืฃ, ื“ืจื•ืฉื™ื ื›ืœื™ื ืœื”ืจื›ื‘ืช ืคื•ืœื™ืกื•ืช ื—ื“ืฉื•ืช.

sudo yum install selinux-policy-devel

ืžื ื’ื ื•ืŸ ื”ืชื—ื•ืžื™ื ื”ืžื•ืชืจื™ื ื”ื•ื ื›ืœื™ ืžืฆื•ื™ืŸ ืœื–ื™ื”ื•ื™ ื‘ืขื™ื•ืช, ื‘ืžื™ื•ื—ื“ ื›ืฉืžื“ื•ื‘ืจ ื‘ืืคืœื™ืงืฆื™ื” ืžื•ืชืืžืช ืื™ืฉื™ืช ืื• ื™ื™ืฉื•ืžื™ื ื”ื ืฉืœื—ื™ื ืœืœื ืžื“ื™ื ื™ื•ืช ืฉื›ื‘ืจ ื ื•ืฆืจื”. ื‘ืžืงืจื” ื–ื”, ืžื“ื™ื ื™ื•ืช ื”ื“ื•ืžื™ื™ืŸ ื”ืžื•ืชืจืช ืขื‘ื•ืจ Gunicorn ืชื”ื™ื” ืคืฉื•ื˜ื” ื›ื›ืœ ื”ืืคืฉืจ - ื”ื›ืจื–ื” ืขืœ ืกื•ื’ ืจืืฉื™ (gunicorn_t), ื”ื›ืจื–ื” ืขืœ ืกื•ื’ ืฉื‘ื• ื ืฉืชืžืฉ ื›ื“ื™ ืœืกืžืŸ ืžืกืคืจ ืงื•ื‘ืฆื™ ื”ืคืขืœื” (gunicorn_exec_t), ื•ืœืื—ืจ ืžื›ืŸ ื”ื’ื“ืจ ืžืขื‘ืจ ืœืžืขืจื›ืช ืœืกื™ืžื•ืŸ ื ื›ื•ืŸ ืจื™ืฆื” ืชื”ืœื™ื›ื™ื. ื”ืฉื•ืจื” ื”ืื—ืจื•ื ื” ืžื’ื“ื™ืจื” ืืช ื”ืžื“ื™ื ื™ื•ืช ื›ืžื•ืคืขืœืช ื›ื‘ืจื™ืจืช ืžื—ื“ืœ ื‘ื–ืžืŸ ื˜ืขื™ื ืชื”.

gunicorn.te:

policy_module(gunicorn, 1.0)

type gunicorn_t;
type gunicorn_exec_t;
init_daemon_domain(gunicorn_t, gunicorn_exec_t)
permissive gunicorn_t;

ืืชื” ื™ื›ื•ืœ ืœื”ืจื›ื™ื‘ ืงื•ื‘ืฅ ืžื“ื™ื ื™ื•ืช ื–ื” ื•ืœื”ื•ืกื™ืฃ ืื•ืชื• ืœืžืขืจื›ืช ืฉืœืš.

make -f /usr/share/selinux/devel/Makefile
sudo semodule -i gunicorn.pp

sudo semanage permissive -a gunicorn_t
sudo semodule -l | grep permissive

ื‘ื•ืื• ื ื‘ื“ื•ืง ืื SELinux ื—ื•ืกื ืžืฉื”ื• ืื—ืจ ืžืœื‘ื“ ืžื” ืฉื”ื“ืžื•ืŸ ื”ืœื ื™ื“ื•ืข ืฉืœื ื• ื ื™ื’ืฉ ืืœื™ื•.

sudo ausearch -m AVC

type=AVC msg=audit(1545315977.237:1273): avc:  denied { write } for pid=19400 comm="nginx" name="gunicorn.sock" dev="tmpfs" ino=52977 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_run_t:s0 tclass=sock_file permissive=0

SELinux ืžื•ื ืขืช ืž-Nginx ืœื›ืชื•ื‘ ื ืชื•ื ื™ื ืœืฉืงืข UNIX ื”ืžืฉืžืฉ ืืช Gunicorn. ื‘ื“ืจืš ื›ืœืœ, ื‘ืžืงืจื™ื ื›ืืœื”, ื”ืžื“ื™ื ื™ื•ืช ืžืชื—ื™ืœื” ืœื”ืฉืชื ื•ืช, ืื‘ืœ ื™ืฉ ืืชื’ืจื™ื ืื—ืจื™ื ืœืคื ื™ื ื•. ืืชื” ื™ื›ื•ืœ ื’ื ืœืฉื ื•ืช ืืช ื”ื’ื“ืจื•ืช ื”ื“ื•ืžื™ื™ืŸ ืžืชื—ื•ื ื”ื’ื‘ืœื” ืœืชื—ื•ื ื”ืจืฉืื”. ื›ืขืช ื ืขื‘ื™ืจ ืืช httpd_t ืœืชื—ื•ื ื”ื”ืจืฉืื•ืช. ื–ื” ื™ื™ืชืŸ ืœ-Nginx ืืช ื”ื’ื™ืฉื” ื”ื“ืจื•ืฉื” ื•ื ื•ื›ืœ ืœื”ืžืฉื™ืš ื‘ืขื‘ื•ื“ืช ื ื™ืคื•ื™ ื‘ืื’ื™ื ื ื•ืกืคืช.

sudo semanage permissive -a httpd_t

ืื– ื‘ืจื’ืข ืฉื”ืฆืœื—ืช ืœืฉืžื•ืจ ืขืœ SELinux ืžื•ื’ืŸ (ืžืžืฉ ืœื ื›ื“ืื™ ืœืš ืœื”ืฉืื™ืจ ืคืจื•ื™ืงื˜ SELinux ื‘ืžืฆื‘ ืžื•ื’ื‘ืœ) ื•ื“ื•ืžื™ื™ื ื™ ื”ื”ืจืฉืื” ื ื˜ืขื ื™ื, ืืชื” ืฆืจื™ืš ืœื”ื‘ื™ืŸ ืžื” ื‘ื“ื™ื•ืง ืฆืจื™ืš ืœื”ื™ื•ืช ืžืกื•ืžืŸ ื›-gunicorn_exec_t ื›ื“ื™ ืฉื”ื›ืœ ื™ืขื‘ื•ื“ ื›ืžื• ืฉืฆืจื™ืš ืฉื•ื‘. ื‘ื•ืื• ื ื ืกื” ืœื‘ืงืจ ื‘ืืชืจ ื›ื“ื™ ืœืจืื•ืช ื”ื•ื“ืขื•ืช ื—ื“ืฉื•ืช ืขืœ ื”ื’ื‘ืœื•ืช ื’ื™ืฉื”.

sudo ausearch -m AVC -c gunicorn

ืืชื” ืชืจืื” ื”ืจื‘ื” ื”ื•ื“ืขื•ืช ื”ืžื›ื™ืœื•ืช 'comm="gunicorn"' ืฉืขื•ืฉื•ืช ื“ื‘ืจื™ื ืฉื•ื ื™ื ื‘ืงื‘ืฆื™ื ื‘-/srv/djangoapp, ืื– ื‘ืจื•ืจ ืฉื–ื• ืื—ืช ื”ืคืงื•ื“ื•ืช ืฉืฉื•ื•ื” ืœืกืžืŸ.

ืื‘ืœ ื‘ื ื•ืกืฃ, ืžื•ืคื™ืขื” ื”ื•ื“ืขื” ื›ื–ื•:

type=AVC msg=audit(1545320700.070:1542): avc:  denied { execute } for pid=20704 comm="(gunicorn)" name="python3.6" dev="vda3" ino=8515706 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0

ืื ืชืกืชื›ืœ ืขืœ ื”ืกื˜ื˜ื•ืก ืฉืœ ืฉื™ืจื•ืช ื”ื’ื•ื ื™ืงื•ืจืŸ ืื• ืชืคืขื™ืœ ืืช ื”ืคืงื•ื“ื” ps, ืœื ืชืจืื” ืชื”ืœื™ื›ื™ื ืคื•ืขืœื™ื. ื ืจืื” ืฉ-gunicorn ืžื ืกื” ืœื’ืฉืช ืœืžืชื•ืจื’ืžืŸ Python ื‘ืกื‘ื™ื‘ืช ื”ื•ื•ื™ืจื˜ื•ืืœื™ ืฉืœื ื•, ืื•ืœื™ ื›ื“ื™ ืœื”ืจื™ืฅ ืกืงืจื™ืคื˜ื™ื ืฉืœ ืขื•ื‘ื“ื™ื. ืื– ืขื›ืฉื™ื• ื‘ื•ืื• ื ืกืžืŸ ืืช ืฉื ื™ ืงื‘ืฆื™ ื”ื”ืคืขืœื” ื”ืœืœื• ื•ื ื‘ื“ื•ืง ืื ื ื•ื›ืœ ืœืคืชื•ื— ืืช ื“ืฃ ื”ื‘ื“ื™ืงื” ืฉืœื ื• ื‘-Django.

chcon -t gunicorn_exec_t /srv/djangoapp/django/bin/gunicorn /srv/djangoapp/django/bin/python3.6

ื™ื”ื™ื” ืฆื•ืจืš ืœื”ืคืขื™ืœ ืžื—ื“ืฉ ืืช ืฉื™ืจื•ืช ื”ื’ื•ื ื™ืงื•ืจืŸ ืœืคื ื™ ืฉื ื™ืชืŸ ื™ื”ื™ื” ืœื‘ื—ื•ืจ ื‘ืชื’ ื”ื—ื“ืฉ. ืืชื” ื™ื›ื•ืœ ืœื”ืคืขื™ืœ ืื•ืชื• ืžื—ื“ืฉ ืžื™ื“ ืื• ืœื”ืคืกื™ืง ืืช ื”ืฉื™ืจื•ืช ื•ืœืชืช ืœืฉืงืข ืœื”ืคืขื™ืœ ืื•ืชื• ื›ืืฉืจ ืืชื” ืคื•ืชื— ืืช ื”ืืชืจ ื‘ื“ืคื“ืคืŸ. ื•ื“ื ืฉืชื”ืœื™ื›ื™ื ืงื™ื‘ืœื• ืืช ื”ืชื•ื•ื™ื•ืช ื”ื ื›ื•ื ื•ืช ื‘ืืžืฆืขื•ืช ps.

ps -efZ | grep gunicorn

ืืœ ืชืฉื›ื— ืœื™ืฆื•ืจ ืžื“ื™ื ื™ื•ืช SELinux ืจื’ื™ืœื” ืžืื•ื—ืจ ื™ื•ืชืจ!

ืื ืชืกืชื›ืœ ืขื›ืฉื™ื• ืขืœ ื”ื•ื“ืขื•ืช AVC, ื”ื”ื•ื“ืขื” ื”ืื—ืจื•ื ื” ืžื›ื™ืœื” permissive=1 ืœื›ืœ ืžื” ืฉืงืฉื•ืจ ืœืืคืœื™ืงืฆื™ื”, ื•ืžืชื™ืจ=0 ืขื‘ื•ืจ ืฉืืจ ื”ืžืขืจื›ืช. ืื ืืชื” ืžื‘ื™ืŸ ืื™ื–ื” ืกื•ื’ ืฉืœ ื’ื™ืฉื” ืฆืจื™ืš ื™ื™ืฉื•ื ืืžื™ืชื™, ืืชื” ื™ื›ื•ืœ ืœืžืฆื•ื ื‘ืžื”ื™ืจื•ืช ืืช ื”ื“ืจืš ื”ื˜ื•ื‘ื” ื‘ื™ื•ืชืจ ืœืคืชื•ืจ ื‘ืขื™ื•ืช ื›ืืœื”. ืื‘ืœ ืขื“ ืื–, ืขื“ื™ืฃ ืœืฉืžื•ืจ ืขืœ ืื‘ื˜ื—ืช ื”ืžืขืจื›ืช ื•ืœืงื‘ืœ ื‘ื™ืงื•ืจืช ื‘ืจื•ืจื” ื•ืฉืžื™ืฉื” ืฉืœ ืคืจื•ื™ืงื˜ Django.

sudo ausearch -m AVC

ืงืจื”!

ืคืจื•ื™ืงื˜ Django ืขื•ื‘ื“ ื”ื•ืคื™ืข ืขื ื—ื–ื™ืช ื”ืžื‘ื•ืกืกืช ืขืœ Nginx ื•-Gunicorn WSGI. ื”ื’ื“ืจื ื• ืืช Python 3 ื•- PostgreSQL 10 ืžืžืื’ืจื™ RHEL 8 Beta. ื›ืขืช ืืชื” ื™ื›ื•ืœ ืœื”ืชืงื“ื ื•ืœื™ืฆื•ืจ (ืื• ืคืฉื•ื˜ ืœืคืจื•ืก) ื™ื™ืฉื•ืžื™ Django ืื• ืœื—ืงื•ืจ ื›ืœื™ื ื–ืžื™ื ื™ื ืื—ืจื™ื ื‘-RHEL 8 Beta ื›ื“ื™ ืœื”ืคื•ืš ืืช ืชื”ืœื™ืš ื”ืชืฆื•ืจื” ืœืื•ื˜ื•ืžื˜ื™, ืœืฉืคืจ ืืช ื”ื‘ื™ืฆื•ืขื™ื, ืื• ืืคื™ืœื• ืœืžื›ืœ ืืช ื”ืชืฆื•ืจื” ื”ื–ื•.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”