Skip to content

Commit

Permalink
Feature/cicd for prod (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
kudralexandr authored Aug 5, 2024
1 parent f6059f5 commit 293b5b8
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/build_and_push_github_packages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- master
- dev
- mastertmp

env:
REGISTRY: ghcr.io
Expand Down Expand Up @@ -49,3 +50,13 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

# Для тестирования отправки на Prod
- name: Build and push Docker image for Production-Tmp
if: github.ref == 'refs/heads/mastertmp'
uses: docker/build-push-action@v5
with:
context: .
file: infra/prod/prod.Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
103 changes: 103 additions & 0 deletions .github/workflows/prod_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Pull and run on Prod

on:
workflow_run:
workflows:
- Build and push Docker image
types:
- completed

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
DEPLOY_PATH: Goodstart_telegram_bot

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Copy docker-compose.prod.yaml via ssh
uses: appleboy/[email protected]
env:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_PASSPHRASE }}
source: "infra/prod/docker-compose.prod.yaml"
target: ${{ env.DEPLOY_PATH }}
- name: Copy nginx.conf via ssh
uses: appleboy/[email protected]
env:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_PASSPHRASE }}
source: "infra/prod/nginx.conf"
target: ${{ env.DEPLOY_PATH }}
- name: Copy goodstart_bot.service via ssh
uses: appleboy/[email protected]
env:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_PASSPHRASE }}
source: "infra/prod/goodstart_bot.service"
target: ${{ env.DEPLOY_PATH }}
- name: Executing remote ssh commands to deploy
uses: appleboy/ssh-action@master
env:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_PASSPHRASE }}
timeout: 120s
script: |
cd ${{ env.DEPLOY_PATH }}
rm .env
touch .env
echo POSTGRES_DB=${{ secrets.POSTGRES_DB }} >> .env
echo POSTGRES_USER=${{ secrets.POSTGRES_USER }} >> .env
echo POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} >> .env
echo DB_ENGINE=${{ secrets.DB_ENGINE }} >> .env
echo DB_HOST=${{ secrets.DB_HOST }} >> .env
echo DB_PORT=${{ secrets.DB_PORT }} >> .env
echo BASE_URL=${{ secrets.BASE_URL }} >> .env
echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
echo DEBUG=${{ secrets.DEBUG }} >> .env
echo ALLOWED_HOSTS=${{ secrets.ALLOWED_HOSTS }} >> .env
echo CSRF_TRUSTED_ORIGINS=${{ secrets.CSRF_TRUSTED_ORIGINS }} >> .env
echo TELEGRAM_TOKEN=${{ secrets.TELEGRAM_TOKEN }} >> .env
echo DJANGO_SUPERUSER_USERNAME=${{ secrets.DJANGO_SUPERUSER_USERNAME }} >> .env
echo DJANGO_SUPERUSER_EMAIL=${{ secrets.HOST_DJANGO_SUPERUSER_EMAILNG }} >> .env
echo DJANGO_SUPERUSER_PASSWORD=${{ secrets.DJANGO_SUPERUSER_PASSWORD }} >> .env
echo DJANGO_SUPERUSER_FIRSTNAME=${{ secrets.DJANGO_SUPERUSER_FIRSTNAME }} >> .env
echo DJANGO_SUPERUSER_LASTNAME=${{ secrets.DJANGO_SUPERUSER_LASTNAME }} >> .env
echo DJANGO_SUPERUSER_PHONE=${{ secrets.DJANGO_SUPERUSER_PHONE }} >> .env
echo EMAIL_BACKEND=${{ secrets.EMAIL_BACKEND }} >> .env
echo EMAIL_HOST=${{ secrets.EMAIL_HOST }} >> .env
echo EMAIL_PORT=${{ secrets.EMAIL_PORT }} >> .env
echo EMAIL_ACCOUNT=${{ secrets.EMAIL_ACCOUNT }} >> .env
echo EMAIL_PASSWORD=${{ secrets.EMAIL_PASSWORD }} >> .env
echo DEFAULT_EMAIL_ADDRESS=${{ secrets.DEFAULT_EMAIL_ADDRESS }} >> .env
echo NGINX_PORT=${{ secrets.NGINX_PORT }} >> .env
# удалить после мержа в dev
echo DB_NAME=${{ secrets.DB_NAME }} >> .env
echo DB_USERNAME=${{ secrets.DB_USERNAME }} >> .env
echo DB_PASSWORD=${{ secrets.DB_PASSWORD }} >> .env
echo HOST_NG=${{ secrets.HOST_NG }} >> .env
cd infra/prod
# Настройка автоматического перезапуска приложения при сбое сервера
sudo cp -f /home/goodstartuser/Goodstart_telegram_bot/infra/prod/goodstart_bot.service /etc/systemd/system/goodstart_bot.service
sudo systemctl daemon-reload
sudo systemctl restart goodstart_bot.service
sleep 10
docker compose -f docker-compose.prod.yaml exec backend sh -c "export RUN_BOT=false"
docker compose -f docker-compose.prod.yaml exec backend python manage.py collectstatic
docker compose -f docker-compose.prod.yaml exec backend python manage.py migrate
docker compose -f docker-compose.prod.yaml exec backend sh -c "export RUN_BOT=true"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,5 @@ static/
*.pem
# persistence_data
persistence_data/persistence_file
.python-version
.env:Zone.Identifier
58 changes: 58 additions & 0 deletions infra/prod/docker-compose.prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

version: '3'

volumes:
pg_data:
static_volume:

services:
db:
image: postgres:latest
env_file: ../../.env
restart: always
container_name: GoodStart-DB
volumes:
- pg_data:/var/lib/postgresql/data
ports:
- 5432:5432
backend:
# для тестовой отправки на сервер:
image: ghcr.io/studio-yandex-practicum/goodstart_telegram_bot:mastertmp
# для финальной отправки на сервер:
# image: ghcr.io/studio-yandex-practicum/goodstart_telegram_bot:master
env_file: ../../.env
restart: always
depends_on:
- db
volumes:
- static_volume:/app/static/
ports:
- 8002:8000
gateway:
image: lscr.io/linuxserver/swag:latest
container_name: swag
cap_add:
- NET_ADMIN
environment:
- PUID=1000 # id goodstartuser на проде
- PGID=1000 # id goodstartuser group на проде
- TZ=Europe/Moscow
- URL=${HOST_NG}
- VALIDATION=http
- SUBDOMAINS=www,bot #optional
- CERTPROVIDER= #optional
- DNSPLUGIN=cloudflare #optional
- PROPAGATION= #optional
- EMAIL= #optional
- ONLY_SUBDOMAINS=false #optional
- EXTRA_DOMAINS= #optional
- STAGING=false #optional
volumes:
- ./nginx.conf:/config/nginx/site-confs/default.conf:ro
- static_volume:/static/
depends_on:
- backend
ports:
- 8001:80
- 443:443
restart: unless-stopped
28 changes: 28 additions & 0 deletions infra/prod/goodstart_bot.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[Unit]

Description=goodstart_telegram_bot
Requires=docker.service
After=docker.service

[Service]

Restart=always
RestartSec=5
TimeOutStartSec=1200
User=goodstartuser

WorkingDirectory=/home/goodstartuser/Goodstart_telegram_bot/infra/prod/

# Выполняет pull образов с Docker Hub
ExecStartPre=sudo docker compose -f docker-compose.prod.yaml pull

# Перезапускает все контейнеры в Docker Compose
ExecStartPre=docker compose -f docker-compose.prod.yaml down
ExecStart=docker compose -f docker-compose.prod.yaml up -d

# Выполняет удаление старых образов
ExecStartPost=docker system prune --force

[Install]

WantedBy=multi-user.target
76 changes: 76 additions & 0 deletions infra/prod/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
server {
listen 80;
index index.html;
server_tokens off;
client_max_body_size 10M;

location /static/material/ {
alias /static/material/;
}
location /static/admin/ {
alias /static/admin/;
}
location /admin {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://backend:8000/admin;
}
location /registration {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://backend:8000/registration;
}
location / {
alias /static/;
autoindex on;
proxy_set_header Host $host;
}
}

server {

listen 443 ssl http2;
listen [::]:443 ssl http2;

keepalive_timeout 45;
reset_timedout_connection on;
client_body_timeout 35;
send_timeout 30;

sendfile on;
aio on;
tcp_nopush on;

open_file_cache max=100000 inactive=20s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

gzip on;
gzip_disable "msie6";

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 1100;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

server_name ${HOST_NG};

include /config/nginx/ssl.conf;

client_max_body_size 10M;

location / {
include /config/nginx/proxy.conf;
set $upstream_app bot;
set $upstream_port 8000;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}

}

0 comments on commit 293b5b8

Please sign in to comment.