Готовых решений для Hestia CP я не нашёл. Есть полезные мысли в этих статьях: https://github.com/realjumy/hestiacp-python-templates https://help.clouding.io/hc/es/articles/4408217149458-C%C3%B3mo-instalar-Django-y-Gunicorn-en-HestiaCP
Поэтому сделал просто, в 2 этапа:
В нашем случае не используется Apache и панель Hestia CP через интерфейс предлагает только те шаблоны, которые лежат в папке php-fpm. Значит, мы не можем использовать sh скрипты. Есть подходящие шаблоны no-php.*
Сделаем копии
cd /usr/local/hestia/data/templates/web/nginx/php-fpm
cp no-php.tpl proxy_gunicorn.tpl
cp no-php.stpl proxy_gunicorn.stpl
Отредактируем шаблоны:
nano proxy_gunicorn.tpl
nano proxy_gunicorn.stpl
Чтобы проксировать gunicorn через Nginx нам достаточно взять пару фрагментов конфига из оффициальной документации и на их основе сделать шаблоны:
location / {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://127.0.0.1:8000;
}
Я изменил proxy_pass из документации на "http://127.0.0.1:8000", также закомментировал некоторые строки в исходных шаблонах (в частности строку с параметром index и фрагмент с описанием location ~* ^.+.(jpeg|jpg|png|webp|gif|bmp|ico|svg|css|js) ... ). Больше ничего не пришлось менять.
В настройках панели Hestia CP просто выбираем затем наш шаблон, а для php-fpm - "no-php"
Получаем в итоге такие конфиги для Hestia CP:
proxy_gunicorn.tpl
#=========================================================================#
# Default Web Domain Template #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS #
# https://hestiacp.com/docs/server-administration/web-templates.html #
#=========================================================================#
server {
listen %ip%:%web_port%;
server_name %domain_idn% %alias_idn%;
root %docroot%;
# index index.php index.html index.htm;
access_log /var/log/nginx/domains/%domain%.log combined;
access_log /var/log/nginx/domains/%domain%.bytes bytes;
error_log /var/log/nginx/domains/%domain%.error.log error;
include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*;
location ~ /\.(?!well-known\/) {
deny all;
return 404;
}
location / {
# location ~* ^.+\.(jpeg|jpg|png|webp|gif|bmp|ico|svg|css|js)$ {
# expires max;
# fastcgi_hide_header "Set-Cookie";
# }
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://127.0.0.1:8000;
}
location ~ [^/]\.php(/|$) {
types { } default_type "text/html";
}
location /error/ {
alias %home%/%user%/web/%domain%/document_errors/;
}
location /vstats/ {
alias %home%/%user%/web/%domain%/stats/;
include %home%/%user%/web/%domain%/stats/auth.conf*;
}
include /etc/nginx/conf.d/phpmyadmin.inc*;
include /etc/nginx/conf.d/phppgadmin.inc*;
include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}
proxy_gunicorn.stpl
#=========================================================================#
# Default Web Domain Template #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS #
# https://hestiacp.com/docs/server-administration/web-templates.html #
#=========================================================================#
server {
listen %ip%:%web_ssl_port% ssl;
server_name %domain_idn% %alias_idn%;
root %sdocroot%;
# index index.php index.html index.htm;
access_log /var/log/nginx/domains/%domain%.log combined;
access_log /var/log/nginx/domains/%domain%.bytes bytes;
error_log /var/log/nginx/domains/%domain%.error.log error;
ssl_certificate %ssl_pem%;
ssl_certificate_key %ssl_key%;
ssl_stapling on;
ssl_stapling_verify on;
# TLS 1.3 0-RTT anti-replay
if ($anti_replay = 307) { return 307 https://$host$request_uri; }
if ($anti_replay = 425) { return 425; }
include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;
location ~ /\.(?!well-known\/) {
deny all;
return 404;
}
location / {
# location ~* ^.+\.(jpeg|jpg|png|webp|gif|bmp|ico|svg|css|js)$ {
# expires max;
# fastcgi_hide_header "Set-Cookie";
# }
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://127.0.0.1:8000;
}
location ~ [^/]\.php(/|$) {
types { } default_type "text/html";
}
location /error/ {
alias %home%/%user%/web/%domain%/document_errors/;
}
location /vstats/ {
alias %home%/%user%/web/%domain%/stats/;
include %home%/%user%/web/%domain%/stats/auth.conf*;
}
proxy_hide_header Upgrade;
include /etc/nginx/conf.d/phpmyadmin.inc*;
include /etc/nginx/conf.d/phppgadmin.inc*;
include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}
Предварительно от рута поставим пакет для настройки venv:
apt install python3.12-venv
Потом в папке сайта, которую мы создали через Hestia CP настроим venv для Python и проверим в консоли:
python3 -m venv /home/user/web/example.com/public_html
cd /home/user/web/example.com/public_html/
source bin/activate
pip install dash
pip install gunicorn
pip install python-dateutil
pip install pandas
pip install dash-bootstrap-components
pip install gevent
pip install fast_bitrix24
bin/gunicorn -b 127.0.0.1:8000 app:server
Установим пакет:
apt install supervisor
Настроим конфиг :
cd /etc/supervisor/conf.d
echo "[program:example_com]
command=source /home/user/web/example.com/public_html/bin/activate && bin/gunicorn -b 127.0.0.1:8000 app:server
directory=/home/user/web/example.com/public_html/
user=user
autostart=true
autorestart=true
redirect_stderr=true" > example_com.conf
Служба управляется командами:
supervisorctl status example_com
supervisorctl start example_com
supervisorctl restart example_com
supervisorctl stop example_com
Также можно полностью перезапустить сервис supervisor:
systemctl restart supervisor