Ubuntu + Nginx + uwsgi + supervisor para Django¶
Primeiro vale lembrar que esse é mais um guia do que um tutorial!
Revisado e testado em 2017-09-28
Agradecimentos¶
Antes de mais nada, agradecer a galera que me ajudaram muito!!!
Valeu moçada!!!
- Alessandro Folk
- Rodrigo Rodrigues (grupo ngMasters)
- Romulo (grupo ngMasters)
Preparando servidor¶
Criando usuário¶
useradd -m -d /home/deploy -G adm,www-data,sudo -s /bin/bash deploy passwd deploy
Para confirmar as pemissões, verifique o arquivo /etc/passwd
deploy:x:1001:1001::/home/deploy:/bin/bash
Verifique se o arquivo /home/deploy/.profile está com as seguintes informações
# ~/.profile: executed by the command interpreter for login shells. # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login # exists. # see /usr/share/doc/bash/examples/startup-files for examples. # the files are located in the bash-doc package. # the default umask is set in /etc/profile; for setting the umask # for ssh logins, install and configure the libpam-umask package. #umask 022 # if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi # set PATH so it includes user's private bin directories PATH="$HOME/bin:$HOME/.local/bin:$PATH"
Rede¶
Troque o usuário
As configurações abaixo poderão ser feitas com usuário deploy pois o mesmo foi criado como adminitrador!!!
Adicionando dns e dominio de busca
sudo nano /etc/resolvconf/resolv.conf.d/tail
-- Add
nameserver 192.168.0.16
search gruposcheffer.com
Git¶
Primeiro vamo configurar o git. Para isso vamos criar a chave ssh e configurar o usuário e email global
Vamos Gerar a Chave
ssh-keygen -t rsa -C "email@dominio.com" Generating public/private rsa key pair. Enter file in which to save the key (/home/deploy/.ssh/id_rsa):[Enter] Created directory '/home/deploy/.ssh'. Enter passphrase (empty for no passphrase):[Senha] Enter same passphrase again:[Repete a Senha] Your identification has been saved in /home/deploy/.ssh/id_rsa. Your public key has been saved in /home/deploy/.ssh/id_rsa.pub. The key fingerprint is: SHA256:***************************** ti@gruposcheffer.com.br
Aplique a chave no seu servidor de versões (gitlab, ou github)
Configurando usuário global
git config --global user.name "Seu Nome" git config --global user.email "email@dominio.com"
Oracle¶
Obs
Essa foi a forma mais rapida de instalar e configurar o oracle no ubuntu!!!
Referência https://help.ubuntu.com/community/Oracle%20Instant%20Client
Baixe os rpm's do site http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html e de permissão de execução nos mesmos.
PS: basic, sqlplus, devel
Para efetuar a instalação, vamos usar o alien
sudo apt-get install alien libaio1 libaio1:i386 sudo alien -i oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm sudo alien -i oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm sudo alien -i oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm echo 'export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib/${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}' >> ~/.profile sudo vi /etc/ld.so.conf.d/oracle.conf && sudo chmod o+r /etc/ld.so.conf.d/oracle.conf # Add This on /etc/ld.so.conf.d/oracle.conf /usr/lib/oracle/12.2/client64/lib/ sudo ldconfig echo 'export ORACLE_HOME=/usr/lib/oracle/12.2/client64' >> ~/.profile echo 'export TNS_ADMIN=$ORACLE_HOME/network/admin' >> ~/.profile echo 'export PATH=$PATH:$ORACLE_HOME/bin' >> ~/.profile source ~/.profile mkdir -p $TNS_ADMIN sudo touch $TNS_ADMIN/tnsnames.ora sudo chmod o+r $TNS_ADMIN/tnsnames.ora
Adicione os tns no arquivo tnsnames.ora e feito!
Frontend¶
Vamos instalar o node 6 e npm para depois adicionar as libs de frontend
sudo apt install python-software-properties curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get install nodejs ~$ node -v v4.2.6 ~$ npm -v 3.5.2
Agora vamos preparar algumas libs para o frontend (compilação)
sudo npm i -g bower gulp yarn @angular/cli ~$ bower -v 1.8.2 ~$ yarn -v 1.1.0 ~$ gulp -v [11:08:52] CLI version 3.9.1
Backend¶
Dependencias
sudo apt-get install build-essential libssl-dev libffi-dev python3-dev
Instalando o pyenv
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \ libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev git clone https://github.com/pyenv/pyenv.git ~/.pyenv echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.profile
Vamos instalar o python 3.6.2
pyenv install 3.6.2 pyenv global 3.6.2 python -V
uWsgi¶
PS: Caso esteja com virtualenv ativo, desative o mesmo deactive
Instale o uwsgi
pip install uwsgi
Precisamos configurar um arquivo de uwsgi para cada projeto.
Nesse exemplo vamos utilizar as seguintes propriedades:
- socket: Arquivo que será gerado o socket para comunicação
- master: Ativar Processos master
- wsgi-file: Arquivo uwsgi do projeto django
- processes: Quantidade de Processos
- enable-threads: Ativar Threads
- threads: Quantidades de threads por processo
- max_requests: Maximo de requisições
- harakiri:
- stats: status do socket
- stats-http: mostra status no http
- uid: usuário do SO
- gid: grupo do SO
- chmod-socket: permissão do Socket
- chdir: diretorio raiz do projeto
- home: diretorio do virutalenv
- logger: arquivo de log
- vacuum: Limpar ao fechar
- ignore-write-errors: Ignorar escrita de erros
- disable-write-exception: Desativar escrita de exceções
Nosso arquivo de exemplo que ficara no projeto1 (raiz do projeto/uwsgi.ini), ficará com a seguinte estrutura:
[uwsgi] socket = projeto1.sock master = true wsgi-file = projeto1/wsgi.py processes = 2 enable-threads = true threads = 10 max_requests = 100 harakiri = 60 stats = 127.0.0.1:9191 stats-http = true uid = www-data gid = www-data chmod-socket = 666 chdir = /home/deploy/projects/projeto1 home = /home/deploy/projects/projeto1/.venv/ logger = file:/home/deploy/projects/projeto1/logs/uwsgi.log vacuum = true ignore-write-errors = true disable-write-exception = true
Importante lembra que em stats
a porta não pode repetir para quando configurar uma outra aplicação
uwsgi_params
Na documentação oficial, precisamos definir alguns parametros para integrar com nginx https://github.com/nginx/nginx/blob/master/conf/uwsgi_params
Vamos criar o arquivo uwsgi_params.conf na raiz do projeto com o seguinte conteúdo:
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;
Para testar se esta tudo funcionando, vamos rodar o seguinte comando:
cd %diretorio_projeto% uwsgi --ini uwsgi.ini
nginx¶
Vamos instalar o servidor nginx:
sudo apt-get install nginx
Após instalado, acesse o diretorio cd /etc/nginx/sites-avaliable
Vamos criar a configuração touch projeto1.conf
- Servidor web para frontend na porta 80
- Servidor web para backend mapeando as rotas /statics e / utilizando socket para integrar com uwsgi
Importante ter o dns configurado para utilização de nomes (exemplo: projeto1.seudominio.com)
# projeto1.conf # Frontend server server { # porta listen 80; # nome DNS server_name projeto1.seudominio.com; # caminho raiz root /home/deploy/projects/projeto1/frontend/dist; # index file index index.html; # locais location / { try_files $uri $uri/ =404; } } # Backend server server { # porta listen 8000; # nome DNS server_name projeto1.seudominio.com; # charset charset utf-8; # configs client_body_in_file_only clean; client_body_buffer_size 32M; sendfile on; keepalive_timeout 120; send_timeout 300s; client_max_body_size 300M; # local /static location /static { alias /home/deploy/projects/projeto1/static; } # local / location / { # socket uwsgi_pass projeto1; # configs proxy_read_timeout 40s; proxy_send_timeout 40s; uwsgi_ignore_client_abort on; # params include /home/deploy/projects/projeto1/uwsgi_params; } } # Reader socket upstream projeto1 { server unix:///home/deploy/projects/projeto1/projeto1.sock; }
Feito isso vamos ativar o site e reiniciar o nginx
sudo ln -s /etc/nginx/sites-avaliable/projeto1.conf /etc/nginx/sites-enable/ sudo /etc/init.d/nginx restart
Para testar, abra o navegador e acesse o endereço projeto1.seudominio.com:8000
e você ira recever um erro 502 Bad Gateway
Isso ocorre porque o socket do uwsgi não está em execução. Vamos no projeto e rodar o mesmo.
cd raiz_projeto
uwsgi --ini uwsgi.ini
Acesse novamente e o site estara funcionando!
Supervisor¶
Para não ter a necessidade de ficar levantando o uwsgi e nginx toda vez vamos automatizar essa tarefa com o supervisor.
Para instalar e configurar
sudo apt-get install supervisor sudo touch /etc/supervisor/conf.d/projeto1.conf
Dentro do arquivo, vamos colocar a seguinte estrutura
[program:projeto1] user = deploy command = /home/deploy/.pyenv/shims/uwsgi --ini /home/deploy/projects/projeto1/uwsgi.ini autostart = true environment=LD_LIBRARY_PATH='/usr/lib/oracle/12.2/client64/lib/${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}',ORACLE_HOME='/usr/lib/oracle/12.2/client64/',TNS_ADMIN='$ORACLE_HOME/network/admin' [program:nginx] command = /usr/sbin/nginx user = root autostart = true
Finalizado, vamos instalar o programa no supervisor
sudo supervisorctl reread sudo supervisorctl start all