Preparando um servidor para publicar um aplicativo Web em Python

Bom dia, Habrovsk!

Havia tempo livre e um desejo de criar um pequeno aplicativo da web. Existe uma idéia (para receber dados de um sensor climático, armazenar no banco de dados e fazer algo interessante), um servidor gratuito no centos também. Tutoriais sobre configuração parece ser o mesmo também ... Mas no momento da escrita, nem um único trabalho totalmente um foi encontrado. Se você também deseja implantar o aplicativo em um servidor CentOS 7.4 usando o pacote python3. *, Uwsgi e nginx, bem-vindo ao gato.

Portanto, o que já deve ser e o que não será abordado neste artigo:

  1. Um servidor físico ou virtual executando o CentOS 7.4 (o desempenho não é garantido para outros sistemas operacionais e versões).
  2. Acesso ao servidor com privilégios de superusuário * se o servidor for virtual, pressupõe-se que exista a capacidade e a capacidade de conectar-se a ele via SSH).

Após conectar-se como usuário root, a primeira etapa é criar um novo usuário com direitos de administrador (isso não é necessário, mas pelo menos é um bom tom):

adduser developer
passwd developer

Aqui você precisará digitar e confirmar a senha do usuário

usermod -aG wheel developer

Adicionar usuário ao grupo de administradores locais

su - developer

Alterne para o usuário recém-criado.

Agora prepare o ambiente:

sudo yum install -y epel-release
sudo yum install -y python3 python3-pip python3-devel nginx gcc
sudo yum update -y python36 python2
sudo yum groupinstall -y "Development Tools" "Development Libraries"
sudo yum install -y python3-devel python36-virtualenv

Gostaria de chamar a atenção para a penúltima linha - “Ferramentas de Desenvolvimento” e “Bibliotecas de Desenvolvimento” são necessárias para o correto lançamento do ambiente virtual. Usamos a bandeira para que a equipe cumpra sem pedir confirmação.

Agora você pode começar a criar o diretório de trabalho:

sudo mkdir /opt/myproject && cd /opt/myproject
sudo chown -R developer /opt/
python3 -m venv myprojectenv
source myprojectenv/bin/activate

pip3 install --upgrade pip
pip3 install uwsgi flask

Agora, prepararemos o ponto de entrada para o aplicativo da Web:

vi /opt/myproject/wsgi.py(daqui em diante usarei o editor vi, no entanto, isso é uma questão de gosto)

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ["<h1 style='color:blue'>Testing Success!</h1>"]

Esse código após o lançamento nos permitirá garantir que todas as etapas anteriores foram bem-sucedidas. Para testar, execute o serviço:

uwsgi --socket 0.0.0.0:8080 --protocol=http -w wsgi

Com uma conexão ljcnegt ou rdp física, o resultado pode ser verificado em um navegador em 0.0.0.0:8080. Com uma conexão SSH, abra uma nova sessão e teste com curl:

curl -v 0.0.0.0:8080

O sinalizador -v permite que você veja a saída completa.

Após a conclusão do teste, você deve encerrar o serviço pressionando CTRL + C (caso contrário, você deve procurar o processo e matá-lo com kill. Também é uma saída, mas definitivamente menos conveniente).

Agora você pode criar o aplicativo Web principal:

vi /opt/myproject/myproject.py

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
   return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
   application.run(host='0.0.0.0')

O processo de teste é bastante semelhante ao anterior - iniciamos o aplicativo usando o comando python3 /opt/myproject/myproject.pye o check. O resultado deve ser o mesmo.

Agora edite o ponto de entrada para que, quando for chamado, nosso aplicativo inicie:

vi /opt/myproject/wsgi.py

from myproject import application

if __name__ == "__main__":
   application.run()

Agora o mais difícil e interessante. É hora de criar um serviço com esse aplicativo que funcionará automaticamente e em segundo plano.

Primeiro, prepare o arquivo ini para o uwsgi:

vi /opt/myproject/myproject.ini

[uwsgi]
wsgi-file = myproject/wsgi.py

master = true
processes = 2

uid = developer
socket = /tmp/uwsgi/myproject.sock
chown-socket = nginx:nginx
chmod-socket = 666
vacuum = true

die-on-term = true

Aqui, quero prestar atenção às seguintes linhas:

  1. socket = /tmp/uwsgi/myproject.sock - para acelerar o serviço, você deve usar o unix-socket e, para que o nginx se conecte a ele, crie-o na pasta temporária / tmp / uwsgi
  2. chown-socket = nginx: o nginx transfere os direitos de uso do soquete para o usuário nginx
  3. chmod-socket = 666 - serve ao mesmo propósito que o anterior. Manuais e dicas diferentes têm valores de parâmetros diferentes - 664, 665, 777 - mas foi estabelecido experimentalmente que 666 é um trabalho minimamente funcional.

Agora você pode prosseguir diretamente para a criação do serviço:

sudo vi /etc/systemd/system/myproject.service

[Unit]
Description=uWSGI instance to serve myproject app
After=network.target

[Service]
ExecStartPre=-/usr/bin/bash -c 'mkdir -p /tmp/uwsgi chown nginx:nginx /tmp/uwsgi'
ExecStart=/usr/bin/bash -c 'cd /opt/myproject; source myprojectenv/bin/activate; uwsgi --ini myproject.ini'
ExecStartPost=/usr/bin/bash -c 'setenforce 0'
PrivateTmp=false
[Install]
WantedBy=multi-user.target

Todas as linhas interessantes estão no bloco Serviço:

  1. ExecStartPre é um comando que o gerente do sistema executará antes de iniciar o serviço.

    - / usr / bin / bash -c anuncia o início da próxima sequência de comandos e 'mkdir -p / tmp / uwsgi chown nginx: nginx / tmp / uwsgi' cria uma pasta temporária para o soquete e transfere os direitos para o usuário nginx.
  2. ExecStart é o comando que inicia o serviço diretamente, e nele iremos sucessivamente para o diretório de trabalho, ativamos o ambiente virtual e iniciaremos o uwsgi-server a partir do arquivo ini.
  3. ExecStartPost - um comando que é executado após o início do serviço. No nosso caso, é necessário para a transferência correta de solicitações do servidor nginx para o servidor uwsgi.
  4. PrivateTmp = false é um parâmetro que torna a pasta temporária criada visível para outros processos.

Agora execute o serviço:

systemctl start myproject
systemctl status myproject
systemctl enable myproject

O último comando fará com que seja iniciado automaticamente após a reinicialização do servidor.

E o último empurrão - configuraremos o servidor nginx e disponibilizaremos nosso aplicativo Web para a rede externa. O log de seu trabalho sempre pode ser visualizado usando o comando

journalctl -u  myproject

sudo vi /usr/lib/systemd/system/nginx.service

Encontre o bloco [Service] e adicione PrivateTmp = false no final.

Depois disso, reinicie os daemons com o comando: systemctl daemon-reload

Agora vamos diretamente para a configuração do servidor:

vi /etc/nginx/nginx.conf

http {
    . . .

    include /etc/nginx/conf.d/*.conf;

    server {
        listen 80 default_server;

        . . .

Encontre o bloco http e adicione um novo servidor:

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/uwsgi/myproject.sock;
    }
}

Agora resta ativar o servidor e editar as regras no firewall:

systemctl start nginx
systemctl enable nginx

firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --zone=public --permanent --add-service=https

firewall-cmd --reload

Agora, ao acessar o servidor por seu nome de domínio ou endereço IP, receberemos uma resposta do nosso aplicativo Flask.

Espero que este material seja útil.

All Articles