Часть девятая. Деплой проекта

Мы у финиша

Цель: Выгрузить сайт в интернет

Задачи:

  • Указать три способа выгрузки сайта

  • Осуществить первый способ

  • Осуществить второй способ

  • Осуществить третий способ

Какие бывают способы деплоя?

Существует 3 способа выгрузить проект в интернет. Выгрузка проекта называется деплоем.

Способ первый. WGET.

Этот способ самый дешёвый, но при это совершенно не правильный, хоть и простой. При использовании этого способа, сайт будет отображаться страница целиком, но никакие механизмы в нём работать не будут.

  • Шаг 0 (для Windows). Скачать на компьютер wget. Это бесплатная утилита для скачивания сайтов целиком. В UNIX-образных системах она установлена.

  • Шаг 1. Запускаем сервер.

  • Шаг 2. Переходим в терминал/командную строку и пишем команду:

    wget -r -k -l 7 -p -E -nc <http://127.0.0.1:8080/>
  • Шаг 3. Заходим в папку загрузки (по умолчанию – это папка пользователя) и находим папку с проектом.

  • Шаг 4. Выгружаем папку целиком на публичный хостинг.

Способ №2. Деплой при помощи PythonAnywhere

Плюсы данного способа – полноценный деплой и простота настройки. Главный минус – использование стороннего ПО.

Есть много компаний, предоставляющих сервера в интернете. Мы воспользуемся услугами одной из них, с довольно простым процессом публикации: PythonAnywhere (https://www.pythonanywhere.com). PythonAnywhere бесплатен для маленьких приложений с небольшим числом посетителей, и этого будет для нас более чем достаточно.

Другим внешним сервисом, которым мы воспользуемся, будет GitHub (https://github.com) — сервис хостинга кода. Существуют и другие похожие сервисы, но практически у каждого программиста есть GitHub аккаунт.

В итоге код будет в трёх местах. На локальном компьютере мы будем заниматься разработкой и тестированием. Когда результат полностью устроит, мы загрузим свою программу на GitHub. А сайт будет на PythonAnywhere, и мы сможем обновлять его, просто загружая новую версию кода с GitHub.

Git

Git — это «система управления версиями», используемая множеством программистов. Эта программа отслеживает изменения, происходящие с файлами, чтобы впоследствии можно было восстановить состояние кода на нужный момент времени. Это немного похоже на функцию отслеживания изменений в Microsoft Word, но куда мощнее.

Установка Git

Windows

Вы можете загрузить Git с официального сайта git-scm.com. Можно нажимать "дальше, дальше, дальше" на всех этапах установки за исключением одного: на пятом шаге, который называется "Adjusting your PATH environment" (Настройка системной переменной Path), выберите "Use Git and optional Unix tools from the Windows Command Prompt" (Запуск Git и соответствующих Unix утилит через командную строку Windows, нижняя опция). Все остальные настройки можно оставить по умолчанию. Также неплохо будет выбрать опцию "Checkout Windows-style, commit Unix-style line endings".

После окончания установки не забудьте перезапустить командную строку или powershell.

OS X

Загрузи Git с официального сайта git-scm.com и просто следуй инструкциям по установке.

Debian и Ubuntu

command-line
$ sudo apt install git

Fedora

command-line
$ sudo dnf install git

openSUSE

command-line
$ sudo zypper install git

Создаём Git-репозиторий

Git отслеживает изменения определенного набора файлов, который называется репозиторием. Давайте создадим такой для нашего проекта. Откройте консоль и запустите эти команды в папке saitMiigaika:

command-line
$ git init
Initialized empty Git repository in ~/saitMiigaika/.git/
$ git config --global user.name "Your Name"
$ git config --global user.email you@example.com

Инициализировать git-репозиторий придется только один раз за проект.

Git будет отслеживать изменения всех файлов и каталогов в заданной директории, однако некоторые из них мы предпочли бы игнорировать. Для этого нам нужно создать файл .gitignore в корневом каталоге репозитория. Откройте редактор и создай новый файл со следующим содержанием:

.gitignore
*.pyc
*~
__pycache__
myvenv
db.sqlite3
/static
.DS_Store

И сохраните его как .gitignore в корневом каталоге "saitMiigaika".

Используйте команду git status перед git add или в любой другой момент, когда вы не уверены, что изменения — хорошая идея. Это убережёт сайт от таких неприятных сюрпризов, как добавление неправильных файлов. Команда git status возвращает информацию обо всех ранее неотслеживаемых/изменённых/добавленных в git файлах, а также статус ветки и многое другое. Результат должен быть похож на:

command-line
$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)

    .gitignore
    blog/
    manage.py
    mysite/

nothing added to commit but untracked files present (use "git add" to track)

И, наконец, мы сохраним наши изменения. Переключаемся на консоль и набираем:

command-line
$ git add --all .
$ git commit -m "My Django MIIGAiK app, first commit"
[...]
13 files changed, 200 insertions(+)
create mode 100644 .gitignore
[...]
create mode 100644 mysite/wsgi.py

Загружаем код в репозиторий GitHub

Зайдите на GitHub.com и создайте новую бесплатную учётную запись.

Затем создайте новый репозиторий и назови его "my-first-blog" (к примеру). Не выбирайте опцию "initialise with a README", не создавайте файл .gitignore (мы сделаем это локально сами) и оставьте лицензию None.

На следующем экране мы видим URL для клонирования репозитория. Выберите вариант "HTTPS" и скопируй ссылку:

Теперь нужно связать локальный репозиторий с репозиторием на GitHub.

Напечатайте у себя в консоли следующую команду (замените \ на имя, указанное при создании аккаунта на GitHub, но без угловых скобок):

command-line
$ git remote add origin https://github.com/<github-username>/my-first-blog.git
$ git push -u origin master

Введите свое имя пользователя и пароль от аккаунта GitHub; мы должны увидеть примерно следующее:

command-line
Username for 'https://github.com': Username
Password for 'https://hjwp\@github.com':
Counting objects: 6, done.
Writing objects: 100% (6/6), 200 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/hjwp/my-first-blog.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.

Наш код теперь на GitHub. Зайдите на сайт и проверьте.

Настройка блога на PythonAnywhere

Регистрация на PythonAnywhere

PythonAnywhere — это сервис по запуску кода на Python в облаке. Мы будем использовать его, чтобы разместить наш сайт «вживую» в интернете.

Создайте аккаунт уровня "Beginner" на PythonAnywhere. Он бесплатный.

Создание API токена для PythonAnywhere

Это нужно будет сделать только один раз. Когда вы зарегистрируетесь на PythonAnywhere, откроется панель управления (dashboard). На ней в правом верхнем углу будет ссылка на страницу «Account»:

Там выберите вкладку «API token» и нажмите кнопку, на которой написано «Create new API token» (создать новый API token).

Настройка сайта на PythonAnywhere

Вернитесь на главную страницу PythonAnywhere, кликнув логотип. Затем запустите Bash-консоль. Нажав на кнопку bash мы запускаем командную строку, которая находится на серверах PythonAnywhere. Эта командная строка аналогична тому, что есть на компьютере.

Чтобы опубликовать сайт на PythonAnywhere, нужно загрузить на PythonAnywhere код с Github и затем настроить PythonAnywhere так, чтобы он распознал код и запустил веб-приложение. Существуют способы сделать это «вручную», но для PythonAnywhere есть программа-помощник, которая сделает это за нас. Давайте её установим.

PythonAnywhere command-line
$ pip3.6 install --user pythonanywhere

Когда мы это запустим, в консоли будет печататься лог установки. Он начнётся с чего-то вроде Collecting pythonanywhere, а последней будет строчка Successfully installed (...) pythonanywhere- (...).

Теперь запустим эту вспомогательную утилиту, которую только что установили. Она настроит приложение, скачав его код с GitHub. Напечатайте следующее в консоли PythonAnywhere:

PythonAnywhere command-line
$ pa_autoconfigure_django.py https://github.com/<github-username>/my-first-blog.git

Утилита будет печатать в консоль, что она делает:

  • Скачивает код с GitHub

  • Создаёт виртуальное окружение на PythonAnywhere, такое же, как на компьютере

  • Обновляет файл настроек с настройками деплоя

  • Создаёт базу данных на PythonAnywhere, используя команду manage.py migrate

  • Разбирается со статическими файлами

  • Настраивает PythonAnywhere так, чтобы приложение было доступно в интернете

Все эти шаги автоматизированы на PythonAnywhere, но они совершенно такие же, какие надо было бы совершить с любым другим хостинговым сервисом.

Главное, на что нужно обратить внимание сейчас, — это то, что база данных на PythonAnywhere никак не связана с базой данных на компьютере. Поэтому там будут разные посты и разные аккаунты администраторов. Как следствие, для базы на PythonAnywhere необходимо создать аккаунт администратора так же, как мы это дели локально с помощью команды createsuperuser. На PythonAnywhere заранее активировано виртуальное окружение, так что всё, что нужно сделать — это запустить в консоли PythonAnhywhere команду:

PythonAnywhere command-line
(ola.pythonanywhere.com) $ python manage.py createsuperuser

Введите параметры для своего пользователя-админа. Лучше всего использовать те же самые данные, что и на локальном компьютере, чтобы избежать путаницы.

Сейчас, если хотите, посмотрите на файлы на PythonAnywhere с помощью команды ls:

PythonAnywhere command-line
(ola.pythonanywhere.com) $ ls
blog db.sqlite3 manage.py mysite requirements.txt static
(ola.pythonanywhere.com) $ ls blog/
__init__.py __pycache__ admin.py apps.py migrations models.py tests.py views.py

Вариант 3. Без автоматизации PythonAnywhere (не рекомендуется новичку)

Самый сложный, но при этом самый правильный метод настройки, так как нам не потребуется использовать стороннее ПО для деплоя, а это уменьшает число уязвимостей.

Необходимо купить выделенный VDS или VPS сервер. VDS выделяет место на сервере физически, VPS – программным методом.

Предположим, у Вас куплена свежая машина, мы первый раз к ней подключаемся. Используем мы Ubuntu.

Далее буду вводить команды списком, чтобы не запутаться в шагах.

rm .ssh/known_hosts
ssh root\@5.45.120.175
passwd root
apt-get update
apt-get upgrade
perl -v
locale-gen en_US en_US.UTF-8 ru_RU.UTF-8
dpkg-reconfigure locales
perl -v
apt-get install nginx
service nginx start
service nginx status
service apache2 status
service apache2 stop
apt-get purge apache2 apache2-utils apache2.2-bin apache2-common
apt-get autoremove
whereis apache2
rm -rf /etc/apache2
service nginx start
service nginx status
apt-get install python3-dev python3-setuptools
easy_install-3.4 virtualenv
adduser django
login django
cd /home/django
virtualenv venv
apt-get install git nano
ssh-keygen -t rsa -C "your_mail\@mail.com"
sshfs root@5.45.120.175:/ /home/user/Develop/sites/my_site/
/root/.ssh/id_rsa.pub
su - root
cd /home/django/
git clone git@github.com:user/my_site.git
login django
source venv/bin/activate
pip install Django
cd my_site
pip install uwsgi
nano test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
uwsgi --http :8000 --wsgi-file test.py
apt-get install libpq-dev postgresql postgresql-contrib
su - postgres
createdb my_site
createuser -P django
psql
postgres=# GRANT ALL PRIVILEGES ON DATABASE my_site TO django;
su - root
login django
source /home/django/venv/bin/activate
pip install psycopg2
pip install -r requirements.txt
pip install X==2.9.0
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'my_site',
        'USER': 'django',
        'PASSWORD': '1234567890',
        'HOST': 'localhost',
        'PORT': '',
    }
}
MEDIA_ROOT = "/home/django/my_site/media"
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver 0.0.0.0:8080
python manage.py collectstatic
uwsgi --http :8000 --module my_site.wsgi
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 REQUEST_SCHEME $scheme;
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;
# the upstream component nginx needs to connect to
upstream django {
    server unix:///home/django/my_site/uwsgi_nginx.sock; # for a file socket
    # server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen 8000;
    # the domain name it will serve for
    server_name my_site.ru; # substitute your machine's IP address or FQDN
    charset utf-8;

    # max upload size
    client_max_body_size 75M; # adjust to taste

    # Django media
    location /media {
        alias /home/django/my_site/media; # your Django project's media files - amend as required
    }

    location /static {
    alias /home/django/my_site/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass django;
        include /home/django/my_site/deployment/uwsgi_params; # the uwsgi_params file you installed
    }
}
sudo ln -s /home/django/rss_news/deployment/rss_news_nginx.conf /etc/nginx/sites-enabled
/etc/init.d/nginx restart
uwsgi --socket uwsgi_nginx.sock --wsgi-file test.py —-chmod-socket=666
uwsgi --socket uwsgi_nginx.sock --module my_site.wsgi --chmod-socket=666
#mysite_uwsgi.ini
[uwsgi]

# Настройки, связанные с Django
# Корневая папка проекта (полный путь)
chdir = /home/django/my_site
# Django wsgi файл
module = my_site.wsgi
# полный путь к виртуальному окружению
home = /home/django/venv
# общие настройки
# master
master = true
# максимальное количество процессов
processes = 10
# полный путь к файлу сокета
socket = /home/django/my_site/uwsgi_nginx.sock
# права доступа к файлу сокета
chmod-socket = 666
# очищать окружение от служебных файлов uwsgi по завершению
vacuum = true
env = DEBUG_MODE=False
daemonize=/var/log/uwsgi/my_site.log
uwsgi --ini my_site_uwsgi.ini
deactivate
apt-get install python-pip python3-pip
pip3 install uwsgi
uwsgi --ini my_site_uwsgi.ini
sudo mkdir /etc/uwsgi

sudo mkdir /etc/uwsgi/vassals
sudo ln -s /home/django/my_site/deployment/my_site_uwsgi.ini /etc/uwsgi/vassals/
uwsgi --emperor "/home/django/my_site/deployment/my_site_uwsgi.ini"
apt-get install supervisor
echo_supervisord_conf > /etc/supervisord.conf
[program:my_site]
command=uwsgi --emperor "/home/django/my_site/deployment/my_site_uwsgi.ini"
stdout_logfile=/home/django/my_site/deployment/uwsgi.log
stderr_logfile=/home/django/my_site/deployment/uwsgi_err.log
autostart=true
autorestart=true
supervisorctl reread
supervisorctl update
service supervisor start|stop|status ...
service supervisor stop
touch my_site_uwsgi.ini
service supervisor start

Last updated