Lucas F
3 years ago
4 changed files with 564 additions and 0 deletions
@ -0,0 +1 @@ |
|||
centos_django.step |
@ -0,0 +1,54 @@ |
|||
# ATENÇÃO, NÃO DEVE HAVER SEPARAÇÃO ENTRE O NOME DA VARIÁVEL E O VALOR DA VARIÁVEL APÓS O SINAL DE IGUALDADE |
|||
# ATTENTION, NO SPACES BETWEEN VAR NAME AND VAR CONTENT |
|||
|
|||
# Nome do usuário no sistema |
|||
# Sistem's username |
|||
USERNAME="lucas" |
|||
|
|||
# Nome do App no repositório |
|||
# App name on repo |
|||
APP="3m" |
|||
|
|||
# Nome do ambiente virtual python |
|||
# Virtual environment name |
|||
VENV=".venv" |
|||
|
|||
# Nome de usuário do repositório |
|||
# Git username |
|||
GIT_USER="lucas" |
|||
|
|||
# Endereço do projeto no repositório |
|||
# Git project url |
|||
GITURL="https://git.lucasf.dev/$GIT_USER/$APP.git" |
|||
|
|||
# IP público ou domínio |
|||
# Public IP address or domain |
|||
PUB_IP="" |
|||
|
|||
# Nome da pasta que está no mesmo nível do arquivo wsgi.py |
|||
# Folder name that is at the same level as wsgi.py file |
|||
WSGI_FOLDER_NAME="3m" |
|||
|
|||
# Nome desejado para o serviço no Systemctl |
|||
# Systemctl desirable name |
|||
SERVICE="app.service" |
|||
|
|||
# Descrição do serviço no Systemctl |
|||
# Systemctl service description |
|||
DESCRIPTION="Django VPS uWSGI Emperor" |
|||
|
|||
# Adicionar o certificado digital na aplicação com Certbot. Escreva sim, se já possuir um domínio na internet |
|||
# Apply certbot ssl certificate, hit yes if you already have a domain |
|||
CERTBOT="no" |
|||
|
|||
# Adicionar renovação do certbot no crontab. Escreva sim, apenas se já possuir um domínio na internet |
|||
# Create a renew certbot cron job, hit yes if you already have a domain |
|||
CRON_CERTBOT="no" |
|||
|
|||
# Incrementar IP em ALLOWED_HOSTS no arquivo .env caso não tenha incrementado |
|||
# Increase ALLOWED_HOSTS IP on .env file |
|||
IP_INCRE="yes" |
|||
|
|||
# Mensagens em Português Brasil |
|||
# PT_BR messages |
|||
PTBR="no" |
@ -0,0 +1,14 @@ |
|||
[tool.poetry] |
|||
name = "django_centos_deploy" |
|||
version = "0.1.0" |
|||
description = "" |
|||
authors = ["Lucas F. <lucasf_dev@protonmail.com>"] |
|||
|
|||
[tool.poetry.dependencies] |
|||
python = "^3.9" |
|||
|
|||
[tool.poetry.dev-dependencies] |
|||
|
|||
[build-system] |
|||
requires = ["poetry-core>=1.0.0"] |
|||
build-backend = "poetry.core.masonry.api" |
@ -0,0 +1,495 @@ |
|||
#!/bin/bash |
|||
|
|||
# =============================================== |
|||
# Esse script foi desenvolvido por Lucas F. |
|||
# This script was developed by Lucas F. |
|||
# |
|||
# Novembro de 2019 |
|||
# 2019, November |
|||
# |
|||
# =============================================== |
|||
|
|||
# Arquivo de configuração |
|||
# Config filename |
|||
ARQ_CONF="centos.conf" |
|||
|
|||
# Nome do usuário no sistema |
|||
# Sistem's username |
|||
USERNAME="centos" |
|||
|
|||
# Nome do App no repositório |
|||
# App name on repo |
|||
APP="appname" |
|||
|
|||
# Nome do ambiente virtual python |
|||
# Virtual environment name |
|||
VENV=".venv" |
|||
|
|||
# Nome de usuário do repositório |
|||
# Git username |
|||
GIT_USER="username" |
|||
|
|||
# Endereço do projeto no repositório |
|||
# Git project url |
|||
GITURL="https://repositório.com/$GIT_USER/$APP.git" |
|||
|
|||
# IP público ou domínio |
|||
# Public IP address or domain |
|||
PUB_IP="" |
|||
|
|||
# Nome da pasta que está no mesmo nível do arquivo wsgi.py |
|||
# Folder name that is at the same level as wsgi.py file |
|||
WSGI_FOLDER_NAME="appdirname" |
|||
|
|||
# Nome desejado para o serviço no Systemctl |
|||
# Systemctl desirable name |
|||
SERVICE="app.service" |
|||
|
|||
# Descrição do serviço no Systemctl |
|||
# Systemctl service description |
|||
DESCRIPTION="Django VPS uWSGI Emperor" |
|||
|
|||
# Adicionar o certificado digital na aplicação com Certbot. Escreva sim, se já possuir um domínio na internet |
|||
# Apply certbot ssl certificate, hit yes if you already have a domain |
|||
CERTBOT="no" |
|||
|
|||
# Adicionar renovação do certbot no crontab. Escreva sim, apenas se já possuir um domínio na internet |
|||
# Create a renew certbot cron job, hit yes if you already have a domain |
|||
CRON_CERTBOT="no" |
|||
|
|||
# Incrementar IP em ALLOWED_HOSTS caso não tenha incrementado |
|||
# Increase ALLOWED_HOSTS IP on .env file |
|||
IP_INCRE="no" |
|||
|
|||
# Mensagens em Português Brasil |
|||
# PT_BR messages |
|||
PTBR="yes" |
|||
|
|||
HAS_ERROS="no" |
|||
ERRORS=() |
|||
|
|||
declare -A MSGS |
|||
declare -A MSG_PT |
|||
MSG_PT[errors]="Por favor verifique os seguintes erros:" |
|||
MSG_PT[before]="Antes de começarmos verifique se as variáveis estão corretas:" |
|||
MSG_PT[entry]="Digite sim ou s para continuar (sim/não): " |
|||
MSG_PT[error_root]="Você precisa executar o script como root" |
|||
MSG_PT[error_requirements]="Não encontrei o arquivo requirements.txt" |
|||
MSG_PT[error_env]="Não encontrei o arquivo .env" |
|||
MSG_PT[error_allwhost]="Não encontrei a variável ALLOWED_HOSTS, você lembrou de extrair do settings.py?" |
|||
MSG_PT[error_debug]="Não encontrei a variável DEBUG, você lembrou de extrair do settings.py?" |
|||
MSG_PT[repo]="Por favor verificar o repositório ou suas credenciais" |
|||
MSG_PT[done]="FEITO" |
|||
MSG_PT[fail]="FALHOU" |
|||
|
|||
declare -A MSG_EN |
|||
MSG_EN[errors]="Please check this errors:" |
|||
MSG_EN[before]="Please check the variables before starting:" |
|||
MSG_EN[entry]="Shall we proceed? (yes/no): " |
|||
MSG_EN[error_root]="You must be root" |
|||
MSG_EN[error_req]="Can't find requirements.txt file" |
|||
MSG_EN[error_env]="Can't find .env file" |
|||
MSG_EN[error_allwhost]="Can't find ALLOWED_HOSTS variable did you extract it from settings.py?" |
|||
MSG_EN[error_debug]="Can't find DEBUG variable did you extract it from settings.py?" |
|||
MSG_EN[repo]="Please check your repo or credentials" |
|||
MSG_EN[done]="DONE" |
|||
MSG_EN[fail]="FAIL" |
|||
|
|||
STEP=0 |
|||
SCRIPT_PATH=$(dirname $0) |
|||
SCRIPT_STEP_FILE="$SCRIPT_PATH/centos_django.step" |
|||
|
|||
# Lê o arquivo de configuração e atualiza os valores das variáveis |
|||
# Read config file and set all variables |
|||
if [[ -f "$SCRIPT_PATH/$ARQ_CONF" ]]; then |
|||
. "$SCRIPT_PATH/$ARQ_CONF" |
|||
fi |
|||
|
|||
# Lê o arquivo de passos e atualiza o valor da variável |
|||
# Read step file and update the value |
|||
if [[ -f "$SCRIPT_STEP_FILE" ]]; then |
|||
. "$SCRIPT_STEP_FILE" |
|||
fi |
|||
echo "step>$STEP" |
|||
# Verifica se deve exibir as mensagens em português do Brasil |
|||
# Check if the language pt_br has been chosen |
|||
if [[ ${PTBR,,} == "yes" ]] || [[ ${PTBR,,} == "sim" ]]; then |
|||
for i in ${!MSG_PT[@]}; do |
|||
MSGS[$i]=${MSG_PT[$i]} |
|||
done |
|||
else |
|||
for i in ${!MSG_EN[@]}; do |
|||
MSGS[$i]=${MSG_EN[$i]} |
|||
done |
|||
fi |
|||
|
|||
# Verifica se o usuário ativo é o root |
|||
# Verify if is a root user |
|||
if [[ "$EUID" -ne 0 ]];then |
|||
HAS_ERROS="yes" |
|||
ERRORS+=("${MSGS[error_root]}") |
|||
fi |
|||
|
|||
# Verifica a existência do usuário no sistema |
|||
# Check if user exists |
|||
CNU=$(grep -c $USERNAME /etc/passwd) |
|||
if [[ $CNU -lt 1 ]]; then |
|||
echo "precisa criar o usuário" |
|||
#useradd --create-home $USERNAME |
|||
fi |
|||
|
|||
# Obtém o IP |
|||
# Get IP address |
|||
if [[ -n $(man hostname | awk '{RS="";FS="\n"} /-i,/ {print}') ]];then |
|||
PUB_IP=$(hostname -i | cut -d" " -f1) |
|||
else |
|||
PUB_IP=$(hostname -I | cut -d" " -f1) |
|||
fi |
|||
|
|||
update_step_error() { |
|||
STEP="$x" |
|||
echo "STEP=$STEP" > "$SCRIPT_STEP_FILE" |
|||
exit 1 |
|||
} |
|||
|
|||
# Exibe todas as variáveis |
|||
# Display all variables |
|||
DISPLAY=" |
|||
\033[33mUSERNAME \033[0m= \033[37m$USERNAME |
|||
\033[33mAPP \033[0m= \033[37m$APP |
|||
\033[33mVENV \033[0m= \033[37m$VENV |
|||
\033[33mGIT_USER \033[0m= \033[37m$GIT_USER |
|||
\033[33mGITURL \033[0m= \033[37m$GITURL |
|||
\033[33mPUB_IP \033[0m= \033[37m$PUB_IP |
|||
\033[33mWSGI_FOLDER_NAME \033[0m= \033[37m$WSGI_FOLDER_NAME |
|||
\033[33mSERVICE \033[0m= \033[37m$SERVICE |
|||
\033[33mDESCRIPTION \033[0m= \033[37m$DESCRIPTION |
|||
\033[33mCERTBOT \033[0m= \033[37m$CERTBOT |
|||
\033[33mCRON_CERTBOT \033[0m= \033[37m$CRON_CERTBOT |
|||
\033[33mIP_INCRE \033[0m= \033[37m$IP_INCRE |
|||
\033[0m" |
|||
|
|||
# Clonar o projeto |
|||
# Clone project |
|||
clone_project() { |
|||
if ! command -v git &> /dev/null; then |
|||
yum install -y git-core |
|||
fi |
|||
|
|||
git clone $GITURL "/home/$USERNAME/$APP" |
|||
|
|||
if [[ $? -ge 1 ]]; then |
|||
echo -e "\033[31m${MSGS[repo]}\033[0m" |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Verifica a existência dos arquivos requirements.txt e .env |
|||
# Check for existence of requirements.txt and .env files |
|||
validate_files() { |
|||
if [[ ! -f "/home/$USERNAME/$APP/requirements.txt" ]]; then |
|||
HAS_ERROS="yes" |
|||
ERRORS+=("${MSGS[error_req]}") |
|||
fi |
|||
|
|||
if [[ ! -f "/home/$USERNAME/$APP/.env" ]]; then |
|||
HAS_ERROS="yes" |
|||
ERRORS+=("${MSGS[error_env]}") |
|||
fi |
|||
|
|||
if [[ ${#ERRORS[@]} -ge 1 ]]; then |
|||
echo -e "\033[31m${MSGS[errors]}" |
|||
for error in "${ERRORS[@]}"; do |
|||
echo -e "\033[0m - \033[37m$error\033[0m" |
|||
done |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Incrementar IP em ALLOWED_HOSTS no arquivo .env caso não tenha incrementado |
|||
# Increase ALLOWED_HOSTS IP on .env file if it doesn't exist |
|||
increment_ip() { |
|||
if [[ ${IP_INCRE,,} == "sim" ]] || [[ ${IP_INCRE,,} == "yes" ]]; then |
|||
if [[ ! -n $(awk '{FS="="} /ALLOWED_HOSTS=/ {print $1}' /home/$USERNAME/$APP/.env) ]]; then |
|||
echo -e "\033[31m${MSGS[error_allwhost]}\033[0m\n" |
|||
update_step_error "$x" |
|||
fi |
|||
if [[ ! -n $(awk '{FS="="} /ALLOWED_HOSTS=/ {print $2}' /home/$USERNAME/$APP/.env) ]]; then |
|||
sed -i "/ALLOWED_HOST/ s/$/$PUB_IP,/g" /home/$USERNAME/$APP/.env |
|||
else |
|||
SUBS_IP=$(sed -n "/ALLOWED_HOSTS/p" /home/$USERNAME/$APP/.env | sed "/$PUB_IP/g") |
|||
if [[ ${#SUBS_IP} -ge 1 ]]; then |
|||
if [[ ${SUBS_IP: -1} == "," ]]; then |
|||
sed -i "/ALLOWED_HOST/ s/$/$PUB_IP,/g" /home/$USERNAME/$APP/.env |
|||
else |
|||
sed -i "/ALLOWED_HOST/ s/$/,$PUB_IP,/g" /home/$USERNAME/$APP/.env |
|||
fi |
|||
fi |
|||
fi |
|||
fi |
|||
} |
|||
|
|||
# Muda a variável DEBUG para valor Falso |
|||
# Update DEBUG variable to False |
|||
update_debug() { |
|||
if [[ ! -n $(awk '{FS="="} /DEBUG=/ {print $1}' /home/$USERNAME/$APP/.env) ]]; then |
|||
echo -e "\033[31m${MSGS[error_debug]}\033[0m\n" |
|||
update_step_error "$x" |
|||
fi |
|||
sed -i "/DEBUG/ s/=.*/=False/g" /home/$USERNAME/$APP/.env |
|||
} |
|||
|
|||
# Instala pacotes necessários |
|||
# Install required packages |
|||
install_packages() { |
|||
yum -y install vim && |
|||
yum -y install epel-release && |
|||
yum -y install bind-utils && |
|||
yum -y install wget && |
|||
yum -y install python3 && |
|||
yum -y install python3-devel && |
|||
yum -y install gcc && |
|||
yum -y install nginx && |
|||
yum -y install policycoreutils-python-utils.noarch && |
|||
dnf update |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Criar o ambiente Virtual |
|||
# Create venv |
|||
create_venv() { |
|||
# python3 -m venv /home/$USERNAME/$APP/$VENV && . /home/$USERNAME/$APP/$VENV/bin/activate |
|||
python3 -m venv /home/$USERNAME/$APP/$VENV |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Instalar as dependências do projeto |
|||
# Install project dependencies |
|||
install_dependencies() { |
|||
/home/$USERNAME/$APP/$VENV/bin/pip3 install --upgrade pip && |
|||
/home/$USERNAME/$APP/$VENV/bin/pip3 install uwsgi && |
|||
/home/$USERNAME/$APP/$VENV/bin/pip3 install -r /home/$USERNAME/$APP/requirements.txt |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Coletar arquivos estáticos, criar tabelas e criar super usuário |
|||
# Perform collectstatic, migrate and createsuperuser |
|||
execute_collec_mig_createsup() { |
|||
if [[ -d /home/$USERNAME/$APP/staticfiles ]]; then |
|||
mkdir -p /home/$USERNAME/$APP/staticfiles |
|||
fi |
|||
/home/$USERNAME/$APP/$VENV/bin/python3 /manage.py collectstatic && |
|||
/home/$USERNAME/$APP/$VENV/bin/python3 /manage.py migrate && |
|||
/home/$USERNAME/$APP/$VENV/bin/python3 /manage.py createsuperuser |
|||
} |
|||
|
|||
# Instala o firewall |
|||
# Install firewall |
|||
install_firewall() { |
|||
yum install -y firewalld && |
|||
systemctl start firewalld && |
|||
firewall-cmd --permanent --add-service=ssh |
|||
firewall-cmd --permanent --add-service=http && |
|||
firewall-cmd --permanent --add-service=https && |
|||
firewall-cmd --reload && |
|||
systemctl enable firewalld |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Autorizar as portas |
|||
# Enable Ports |
|||
enable_ports() { |
|||
semanage port -m -t http_port_t -p tcp 80 && |
|||
semanage permissive -a httpd_t && |
|||
iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT |
|||
firewall-cmd --zone=public --add-port=80/tcp --permanent |
|||
firewall-cmd --reload |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Criar o arquivo de configurações do NGINX |
|||
# Create nginx config file |
|||
create_nginx_file() { |
|||
cat > /etc/nginx/conf.d/$APP.conf <<EOF |
|||
upstream django { |
|||
server unix:///home/$USERNAME/$APP/mysite.sock; |
|||
} |
|||
|
|||
server { |
|||
listen 80; |
|||
server_name $PUB_IP; |
|||
charset utf-8; |
|||
client_max_body_size 75M; |
|||
location /media { |
|||
alias /home/$USERNAME/$APP/media; |
|||
} |
|||
location /static { |
|||
alias /home/$USERNAME/$APP/static; |
|||
} |
|||
location / { |
|||
uwsgi_pass django; |
|||
include /etc/nginx/uwsgi_params; |
|||
} |
|||
} |
|||
EOF |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Criar o arquivo de inicialização do uWSGI |
|||
# Create uwsgi ini file |
|||
create_uwsgi_ini_file() { |
|||
cat > /home/$USERNAME/$APP/uwsgi.ini <<EOF |
|||
[uwsgi] |
|||
chdir = /home/$USERNAME/$APP |
|||
module = $WSGI_FOLDER_NAME.wsgi |
|||
pythonpath = /home/$USERNAME/$APP/$VENV |
|||
master = true |
|||
processes = 10 |
|||
socket = /home/$USERNAME/$APP/mysite.sock |
|||
vacuum = true |
|||
chmod-socket = 666 |
|||
EOF |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Criar o modo Emperor do uWSGI |
|||
# Create uWSGI Emperor mode |
|||
criar_emperor_uwsgi() { |
|||
mkdir -p /etc/uwsgi/vassals && |
|||
if [[ ! -f /etc/uwsgi/vassals/uwsgi.ini ]]; then |
|||
ln -s /home/$USERNAME/$APP/uwsgi.ini /etc/uwsgi/vassals |
|||
fi |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Cria um serviço no systemctl |
|||
# Create a systemctl service |
|||
create_service_file() { |
|||
cat > /etc/systemd/system/$SERVICE <<EOF |
|||
====== |
|||
[Unit] |
|||
Description=$DESCRIPTION |
|||
After=syslog.target |
|||
|
|||
[Service] |
|||
ExecStart=/usr/local/bin/$SERVICE.sh |
|||
RuntimeDirectory=uwsgi |
|||
Restart=always |
|||
KillSignal=SIGQUIT |
|||
Type=notify |
|||
StandardError=syslog |
|||
NotifyAccess=all |
|||
User=$USERNAME |
|||
|
|||
[Install] |
|||
WantedBy=multi-user.target |
|||
======= |
|||
EOF |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Criar o script que executa o modo Emperor do uWSGI |
|||
# Create the script called by systemctl service |
|||
create_script_emperor() { |
|||
cat > /usr/local/bin/$SERVICE.sh <<EOF |
|||
#!/bin/bash |
|||
/home/$USERNAME/$APP/$VENV/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data |
|||
EOF |
|||
chmod +x /usr/local/bin/$SERVICE.sh |
|||
if [[ $? -ge 1 ]]; then |
|||
update_step_error "$x" |
|||
fi |
|||
} |
|||
|
|||
# Rodar o sistema |
|||
# Start service |
|||
run_service() { |
|||
chmod -R 751 /home/$USERNAME |
|||
chmod 664 /etc/systemd/system/$SERVICE.service && |
|||
chown -R $USERNAME:$USERNAME /home/$USERNAME && |
|||
systemctl daemon-reload && |
|||
systemctl enable nginx && |
|||
systemctl start nginx && |
|||
systemctl enable $SERVICE.service && |
|||
systemctl start $SERVICE.service && |
|||
systemctl restart nginx |
|||
} |
|||
|
|||
# Instalar o Certbot |
|||
# Install Certbot |
|||
certbot() { |
|||
if [ "$CERTBOT" == "sim" ]; then |
|||
wget https://dl.eff.org/certbot-auto && |
|||
mv certbot-auto /usr/local/bin/certbot-auto && |
|||
chown root /usr/local/bin/certbot-auto && |
|||
chmod 755 /usr/local/bin/certbot-auto && |
|||
/usr/local/bin/certbot-auto --nginx |
|||
fi |
|||
} |
|||
|
|||
# Adicionar no crontab a renovação do certificado |
|||
# Add recursive renew on crotab |
|||
crontab_certbot() { |
|||
if [ "$CRON_CERTBOT" == "sim" ] |
|||
then |
|||
echo "0 0,12 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew" | tee -a /etc/crontab > /dev/null |
|||
fi |
|||
} |
|||
|
|||
declare -a commands=( |
|||
"clone_project" |
|||
"validate_files" |
|||
"increment_ip" |
|||
"update_debug" |
|||
"install_packages" |
|||
"create_venv" |
|||
"install_dependencies" |
|||
"install_firewall" |
|||
"enable_ports" |
|||
"create_nginx_file" |
|||
"create_uwsgi_ini_file" |
|||
"criar_emperor_uwsgi" |
|||
"create_service_file" |
|||
"create_script_emperor" |
|||
"run_service" |
|||
) |
|||
|
|||
|
|||
REPORT=() |
|||
|
|||
if [[ ${#ERRORS[@]} -ge 1 ]]; then |
|||
echo "${MSGS[errors]}" |
|||
for error in "${ERRORS[@]}"; do |
|||
echo " - $error" |
|||
done |
|||
else |
|||
echo -e "\n${MSGS[before]}\n$DISPLAY" |
|||
read -p "${MSGS[entry]} " resp |
|||
|
|||
if [[ -n $resp ]]; then |
|||
if [[ ${resp,,} == "sim" ]] || [[ ${resp,,} == "s" ]] || [[ ${resp,,} == "yes" ]] || [[ ${resp,,} == "y" ]]; then |
|||
for ((x=$STEP; x<${#commands[@]};x++)); do |
|||
echo "${commands[$x]}_$x" |
|||
${commands[$x]} $x |
|||
done |
|||
fi |
|||
fi |
|||
fi |
Loading…
Reference in new issue