28 січня 2019 р.
Розглянемо простий варіант деплою декількох сайтів на Linux VPS (дистрибютив Ubuntu). Заходити по ssh з командної стрічки (напр. ssh root@12.34.56.78, потім пароль).
Як правило серверa "голі" без nginx, apache і т.д. Але може бути вже дещо встановлено (це як на мене гірше, бо багато чого не потрібного, включаючи у conf файлах)..
Перевіряємо чи запущений apache2 і зупиняєм по потребі, перевірка/встановлення nginx:
sudo service apache2 status
sudo service apache2 stop
sudo service nginx status
sudo apt-get update
sudo apt-get install nginx
sudo service nginx start
В дистрибютиві Ubuntu (16 і вище) використовуємо Python v3+
Встановлюємо uWSGI глобально (режим Emperor, щоб запустити на однму сервері декілька проектів)
Також встановлюємо Supervisor:
sudo apt-get install python3-pip python3-dev build-essential
sudo apt-get install python3-setuptools
sudo pip3 install virtualenv
sudo pip3 install uwsgi
sudo apt-get install supervisor
Створюєм папку для конфігураційних файлів:
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
Заходимо в /etc/supervisor/supervisord.conf i додаємо наступні конфігурації:
[program:uwsgi]
command = /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals
autostart = true
Далі наші проекти.
Для прикладу поміщаємо все в /home
Створюємо в /home папку virtenv для "віртуалок" та віртуальне середовище:
cd /home
mkdir virtenv
cd /virtenv
virtualenv venv3
активуємо і інсталюємо все що потрібно
Розглянемо для прикладу два проекти django: kyiv та lviv (віртуалку викоритаєм одну для двох, для демонстрації). Вони будуть також в /home
структура приблизно така:
home/kyiv/mysite
- mysite
---- init.py
---- settings.py
---- urls.py
---- wsgi.py
- myapp
---- init.py
---- admin.py
---- models.py
---- views.py
- media
- static
- templates
- manage.py
- db.sqlite3
те саме для другого, замість kyiv - lviv
Готові проекти переносимо за допомогою GIT (можна і копіпастом в nautilus, якщо туго з GITом о_О ), незабуваючи про права доступу до файлів (можуть бути змінені, наприклад, доступи до папки статики і в браузері видасть 403 forbidden; допоможе chmod -R 755 або 777 /home/kyiv/mysite/static
).
Також в settings.py не забуваєм поставити ALLOWED_HOSTS = ["*"] (детальніше про це налаштування краще почитати тут django allowed-hosts)
В папці де знаходиться файл manage.py створюємо файл налаштування uwsgi, напр. kyiv_uwsgi.ini
(для lviv відповідно lviv_uwsgi.ini
) з такими налаштуваннями:
kyiv_uwsgi.ini
[uwsgi]
chdir = /home/kyiv/mysite
module = django.core.wsgi:get_wsgi_application()
home = /home/virtenv/venv3/
env = DJANGO_SETTINGS_MODULE=mysite.settings
master = true
processes = 10
socket = /tmp/kyiv.sock
logfile = /home/kyiv/logs/uwsgi.log
chmod-socket = 666
vacuum = true
lviv_uwsgi.ini
[uwsgi]
chdir = /home/lviv/mysite
module = django.core.wsgi:get_wsgi_application()
home = /home/virtenv/venv3/
env = DJANGO_SETTINGS_MODULE=mysite.settings
master = true
processes = 10
socket = /tmp/lviv.sock
logfile = /home/lviv/logs/uwsgi.log
chmod-socket = 666
vacuum = true
Різні варіації можна подивитись тут:
uWSGI Django and Nginx
Також треба створити папку logs для logfile.
Будем вважати, що в нас є зареестровані домени kyiv.ua та lviv.ua і в них прописані NS сервера нашого хостера. А також у хостера до ІР сервера привязані дані домени.
Налаштовуємо nginx.conf
в /etc/nginx
Взагальному цей файл всюди однаковий, хоча можуть бути індивідуальні варіації. Використовуємо такий варіант налаштуваня файлу nginx.conf:
# Server globals
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log crit;
pid /var/run/nginx.pid;
# Worker config
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_min_length 1000;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss application/x-font-ttf text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
В папці де файл manage.py
створюємо файл налаштування nginx, для кожного проекту напр. kyiv_nginx.conf (для lviv відповідно lviv_nginx.conf) з такими налаштуваннями:
kyiv_nginx.conf
upstream kyiv {
server unix:///tmp/kyiv.sock;
}
server {
listen 80;
server_name kyiv.ua;
return 301 http://www.kyiv.ua$request_uri;
}
server {
listen 80;
server_name www.kyiv.ua;
charset utf-8;
access_log /home/kyiv/logs/access.log;
error_log /home/kyiv/logs/error.log;
root /home/kyiv/mysite/;
client_max_body_size 75M;
location /media {
alias /home/kyiv/mysite/media;
}
location /static {
alias /home/kyiv/mysite/static;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location / {
uwsgi_pass kyiv;
include /home/kyiv/mysite/uwsgi_params;
}
}
lviv_nginx.conf
upstream lviv {
server unix:///tmp/lviv.sock;
}
server {
listen 80;
server_name lviv.ua;
return 301 http://www.lviv.ua$request_uri;
}
server {
listen 80;
server_name www.lviv.ua;
charset utf-8;
access_log /home/lviv/logs/access.log;
error_log /home/lviv/logs/error.log;
root /home/lviv/mysite/;
client_max_body_size 75M;
location /media {
alias /home/lviv/mysite/media;
}
location /static {
alias /home/lviv/mysite/static;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
location / {
uwsgi_pass lviv;
include /home/lviv/mysite/uwsgi_params;
}
}
В нашому випадку налаштований редірект сайту з без www на www
В /etc/nginx
має бути файл uwsgi_params, копіюємо його в папку де файл manage.py
(щоб все було в одному місці). Якщо немає то створюємо (всюди однаковий):
uwsgi_params
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
Тепер важливий момент, створюєм посилання конфігурацій для uwsgi та nginx:
sudo ln -s /home/kyiv/mysite/kyiv_uwsgi.ini /etc/uwsgi/vassals/
sudo ln -s /home/lviv/mysite/lviv_uwsgi.ini /etc/uwsgi/vassals/
sudo ln -s /home/kyiv/mysite/kyiv_nginx.conf /etc/nginx/sites-enabled/
sudo ln -s /home/lviv/mysite/lviv_nginx.conf /etc/nginx/sites-enabled/
Можем попередньо перевірити на помилки в nginx командою nginx -t
Перезапускаєм uwsgi та nginx:
sudo supervisorctl restart uwsgi
sudo service nginx restart
Можуть бути помилки в nginx і видасть попередження, що неперезапустилось - дивимось командою sudo journalctl -xe
а також в логах.
uwsgi при рестарті повідомлення в терміналі не дає, тому якщо не працює дивимось в логах
Якщо все без омилок то по kyiv.ua та lviv.ua мають працювати наші сайти. Шляхи до статики в проекті і шаблонах треба налаштовувати індивідуально, шлях до папки /static чи /media прописаний в kyiv_nginx.conf
та lviv_nginx.conf
Після кожних змін в проекті в .ру файлах потрібно перезапускати uwsgi (sudo supervisorctl restart uwsgi
) щоб підтянулись зміни
Як виконати декілька тестів в одній фнкції.
Вишенька на торті - git команда, яка забирає тільки зміни