diff --git a/.github/workflows/build_and_push_github_packages.yaml b/.github/workflows/build_and_push_github_packages.yaml index 1d81773..047c765 100644 --- a/.github/workflows/build_and_push_github_packages.yaml +++ b/.github/workflows/build_and_push_github_packages.yaml @@ -5,7 +5,6 @@ on: branches: - master - dev - - mastertmp env: REGISTRY: ghcr.io @@ -39,24 +38,13 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - + - name: Build and push Docker image for Stage if: github.ref == 'refs/heads/dev' uses: docker/build-push-action@v5 - with: - context: . - file: infra/dev/dev.Dockerfile - push: true - 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 + file: infra/dev/dev.Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/prod_deploy.yml b/.github/workflows/prod_deploy.yml deleted file mode 100644 index b245ef7..0000000 --- a/.github/workflows/prod_deploy.yml +++ /dev/null @@ -1,105 +0,0 @@ -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 - environment: - name: prod - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - name: Copy docker-compose.prod.yaml via ssh - uses: appleboy/scp-action@v0.1.3 - with: - 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/scp-action@v0.1.3 - with: - 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/scp-action@v0.1.3 - with: - 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 - with: - 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" diff --git a/.github/workflows/pull_and_run_on_server.yaml b/.github/workflows/pull_and_run_on_server.yaml index 8e8c264..3e885ee 100644 --- a/.github/workflows/pull_and_run_on_server.yaml +++ b/.github/workflows/pull_and_run_on_server.yaml @@ -1,98 +1,98 @@ -name: Pull and run on server +# name: Pull and run on server -on: - workflow_run: - workflows: - - Build and push Docker image - types: - - completed +# on: +# workflow_run: +# workflows: +# - Build and push Docker image +# types: +# - completed -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - DEPLOY_PATH: Goodstart_telegram_bot +# 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.stage.yaml via ssh - uses: appleboy/scp-action@v0.1.3 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USER }} - key: ${{ secrets.SSH_KEY }} - passphrase: ${{ secrets.SSH_PASSPHRASE }} - source: "infra/stage/docker-compose.stage.yaml" - target: ${{ env.DEPLOY_PATH }} - - name: Copy nginx.conf via ssh - uses: appleboy/scp-action@v0.1.3 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USER }} - key: ${{ secrets.SSH_KEY }} - passphrase: ${{ secrets.SSH_PASSPHRASE }} - source: "infra/stage/nginx.conf" - target: ${{ env.DEPLOY_PATH }} - - name: Copy goodstart_bot.service via ssh - uses: appleboy/scp-action@v0.1.3 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USER }} - key: ${{ secrets.SSH_KEY }} - passphrase: ${{ secrets.SSH_PASSPHRASE }} - source: "infra/stage/goodstart_bot.service" - target: ${{ env.DEPLOY_PATH }} - - name: Executing remote ssh commands to deploy - uses: appleboy/ssh-action@master - with: - 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 +# jobs: +# deploy: +# runs-on: ubuntu-latest +# steps: +# - name: Checkout repo +# uses: actions/checkout@v3 +# - name: Copy docker-compose.stage.yaml via ssh +# uses: appleboy/scp-action@v0.1.3 +# with: +# host: ${{ secrets.HOST }} +# username: ${{ secrets.USER }} +# key: ${{ secrets.SSH_KEY }} +# passphrase: ${{ secrets.SSH_PASSPHRASE }} +# source: "infra/stage/docker-compose.stage.yaml" +# target: ${{ env.DEPLOY_PATH }} +# - name: Copy nginx.conf via ssh +# uses: appleboy/scp-action@v0.1.3 +# with: +# host: ${{ secrets.HOST }} +# username: ${{ secrets.USER }} +# key: ${{ secrets.SSH_KEY }} +# passphrase: ${{ secrets.SSH_PASSPHRASE }} +# source: "infra/stage/nginx.conf" +# target: ${{ env.DEPLOY_PATH }} +# - name: Copy goodstart_bot.service via ssh +# uses: appleboy/scp-action@v0.1.3 +# with: +# host: ${{ secrets.HOST }} +# username: ${{ secrets.USER }} +# key: ${{ secrets.SSH_KEY }} +# passphrase: ${{ secrets.SSH_PASSPHRASE }} +# source: "infra/stage/goodstart_bot.service" +# target: ${{ env.DEPLOY_PATH }} +# - name: Executing remote ssh commands to deploy +# uses: appleboy/ssh-action@master +# with: +# 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 +# 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 - cd infra/stage +# cd infra/stage - # Настройка автоматического перезапуска приложения при сбое сервера - sudo cp -f /home/develop/Goodstart_telegram_bot/infra/stage/goodstart_bot.service /etc/systemd/system/goodstart_bot.service - sudo systemctl daemon-reload - sudo systemctl restart goodstart_bot.service +# # Настройка автоматического перезапуска приложения при сбое сервера +# sudo cp -f /home/develop/Goodstart_telegram_bot/infra/stage/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.stage.yaml exec backend sh -c "export RUN_BOT=false" - docker compose -f docker-compose.stage.yaml exec backend python manage.py collectstatic - docker compose -f docker-compose.stage.yaml exec backend python manage.py migrate - docker compose -f docker-compose.stage.yaml exec backend sh -c "export RUN_BOT=true" +# sleep 10 +# docker compose -f docker-compose.stage.yaml exec backend sh -c "export RUN_BOT=false" +# docker compose -f docker-compose.stage.yaml exec backend python manage.py collectstatic +# docker compose -f docker-compose.stage.yaml exec backend python manage.py migrate +# docker compose -f docker-compose.stage.yaml exec backend sh -c "export RUN_BOT=true" diff --git a/.github/workflows/stage_deploy.yml b/.github/workflows/stage_deploy.yml new file mode 100644 index 0000000..ee91d1f --- /dev/null +++ b/.github/workflows/stage_deploy.yml @@ -0,0 +1,93 @@ +name: Bot stage deploy + +on: + workflow_run: + workflows: + - Build and push Docker image + types: + - completed + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + DEPLOY_PATH: Goodstart_telegram_bot + +defaults: + run: + working-directory: . + +jobs: + deploy: + name: Deploy changes on server + runs-on: ubuntu-latest + environment: + name: stage + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + ref: dev + + - name: Create folder for deploy + run: ssh ${{ secrets.HOST_USERNAME }}@${{ secrets.HOST_IP }} mkdir -p ${{ env.DEPLOY_PATH }}/infra + + - name: Copy dev folder to VPS + run: scp -r $GITHUB_WORKSPACE/infra/stage/ ${{ secrets.HOST_USERNAME }}@${{ secrets.HOST_IP }}:${{ env.DEPLOY_PATH }}/infra/ + + - name: Execute commands on VPS + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.HOST_IP }} + username: ${{ secrets.HOST_USERNAME }} + key: ${{ secrets.HOST_SSH_PRIVATE_KEY }} + script: | + cd ${{ env.DEPLOY_PATH }} + + rm .env + touch .env + + echo HOST_NG=Hello-world >> .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" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd10e7a..050a443 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,18 @@ repos: hooks: - id: ruff types_or: [ python ] - #TODO К ruff подключить одинарные кавычки - # - id: ruff-format - # types_or: [ python ] - repo: local hooks: - id: export-dev-dependencies - name: Export development dependencies + name: Export dev Dependencies language: system pass_filenames: false - entry: poetry lock + entry: poetry export --without-hashes --dev --output requirements/dev.txt + files: ^(pyproject.toml|poetry.lock)$ + - id: export-prod-dependencies + name: Export prod Dependencies + language: system + pass_filenames: false + entry: poetry export --without-hashes --output requirements/prod.txt + files: ^(pyproject.toml|poetry.lock)$ diff --git a/infra/dev/dev.Dockerfile b/infra/dev/dev.Dockerfile deleted file mode 100644 index 3f2ed3e..0000000 --- a/infra/dev/dev.Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.12 - -RUN pip install poetry - -WORKDIR /app - -COPY pyproject.toml . -COPY poetry.lock . - -# Copy source code -COPY src/. /app/ - -RUN poetry config virtualenvs.create false \ - && poetry install --without dev --no-root - -CMD ["poetry", "run", "uvicorn", "core.asgi_prod:application", "--lifespan", "on", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/infra/dev/docker-compose.dev.yaml b/infra/dev/docker-compose.dev.yaml deleted file mode 100644 index 8a60ae0..0000000 --- a/infra/dev/docker-compose.dev.yaml +++ /dev/null @@ -1,40 +0,0 @@ - -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:dev - # build: - # context: ../.. - # dockerfile: infra/dev/dev.Dockerfile - env_file: ../../.env - restart: always - depends_on: - - db - volumes: - - static_volume:/app/static/ - ports: - - 8002:8000 - gateway: - image: nginx:1.22.1 - volumes: - - ./nginx.conf:/etc/nginx/templates/default.conf.template:ro - - static_volume:/static/ - depends_on: - - backend - restart: always - ports: - - 8001:80 diff --git a/infra/dev/goodstart_bot.service b/infra/dev/goodstart_bot.service deleted file mode 100644 index 5431004..0000000 --- a/infra/dev/goodstart_bot.service +++ /dev/null @@ -1,28 +0,0 @@ -[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/dev/ - -# Выполняет pull образов с Docker Hub -ExecStartPre=sudo docker compose -f docker-compose.dev.yaml pull - -# Перезапускает все контейнеры в Docker Compose -ExecStartPre=docker compose -f docker-compose.dev.yaml down -ExecStart=docker compose -f docker-compose.dev.yaml up -d - -# Выполняет удаление старых образов -ExecStartPost=docker system prune --force - -[Install] - -WantedBy=multi-user.target \ No newline at end of file diff --git a/infra/dev/nginx.conf b/infra/dev/nginx.conf deleted file mode 100644 index 391764e..0000000 --- a/infra/dev/nginx.conf +++ /dev/null @@ -1,30 +0,0 @@ -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; - } -} \ No newline at end of file diff --git a/infra/stage/docker-compose.stage.yaml b/infra/stage/docker-compose.stage.yaml index 0d19d97..cca6e19 100644 --- a/infra/stage/docker-compose.stage.yaml +++ b/infra/stage/docker-compose.stage.yaml @@ -1,48 +1,53 @@ - -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 + env_file: + - ../../.env ports: - 5432:5432 + restart: always + volumes: + - pg_data:/var/lib/postgresql/data + - ../../logs/db/:/var/log/postgres - backend: + bot: image: ghcr.io/studio-yandex-practicum/goodstart_telegram_bot:dev - container_name: backend + # build: + # context: ../.. + # dockerfile: infra/dev/dev.Dockerfile + container_name: goodstart-bot env_file: ../../.env restart: always depends_on: - db volumes: - static_volume:/app/static/ - ports: - - 8002:8000 - gateway: - image: lscr.io/linuxserver/swag:latest + swag: + image: lscr.io/linuxserver/swag container_name: swag cap_add: - NET_ADMIN environment: - - PUID=1001 # uid=1001(develop) на stage - - PGID=1002 # gid=1002(google-sudoers) на stage - - TZ=Europe/Moscow - - URL=jetrai.ru + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + - URL=raikhert.duckdns.org + - VALIDATION=duckdns + - DUCKDNSTOKEN=4ee0a66c-5935-4bdb-8550-88c2c52a817b volumes: - /home/aptalca/appdata/swag:/config - - ./nginx.conf:/config/nginx/site-confs/default.conf:ro - - static_volume:/static/ - depends_on: - - backend + - ./nginx.stage.conf.template:/etc/nginx/templates/default.conf.template + - static_volume:/var/html/static/ + - ../../logs/nginx/:/var/log/nginx/ ports: - 443:443 - 80:80 + depends_on: + - bot restart: unless-stopped + +volumes: + pg_data: + static_volume: diff --git a/infra/stage/nginx.conf b/infra/stage/nginx.conf deleted file mode 100644 index 46a79aa..0000000 --- a/infra/stage/nginx.conf +++ /dev/null @@ -1,80 +0,0 @@ -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 jetrai.ru; - - include /config/nginx/ssl.conf; - - client_max_body_size 10M; - - 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 /static/material/ { - alias /static/material/; - } - location /static/admin/ { - alias /static/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; - } - - # location / { - # include /config/nginx/proxy.conf; - # set $upstream_app backend; - # set $upstream_port 8000; - # set $upstream_proto http; - # proxy_pass $upstream_proto://$upstream_app:$upstream_port; - # } -} - - -server { - if ($host = jetrai.ru) { - return 301 https://$host$request_uri; - } - - listen 80; - server_name jetrai.ru; - return 301 https://$host$request_uri; - -} diff --git a/infra/stage/nginx.stage.conf.template b/infra/stage/nginx.stage.conf.template new file mode 100644 index 0000000..34baaa2 --- /dev/null +++ b/infra/stage/nginx.stage.conf.template @@ -0,0 +1,57 @@ +server { + listen 80; + server_tokens off; + server_name raikhert.duckdns.org; + client_max_body_size 10M; + + location /static/ { + root /var/html/; + } + + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://bot:8000/admin; + } + location /registration { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://bot:8000/registration; + } + + error_page 500 502 503 504 /50x.html; + + location = /50x.html { + root /usr/share/nginx/html/50x.html; + } +} + +server { + + listen 443 ssl http2; + listen [::]:443 ssl http2; + + keepalive_timeout 45; + reset_timedout_connection on; + client_body_timeout 35; + send_timeout 30; + + server_name raikhert.*;; + + 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; + } + +} diff --git a/infra/stage/stage.Dockerfile b/infra/stage/stage.Dockerfile index 8a7babc..2383d5b 100644 --- a/infra/stage/stage.Dockerfile +++ b/infra/stage/stage.Dockerfile @@ -1,16 +1,15 @@ FROM python:3.12 -RUN pip install poetry - WORKDIR /app -COPY pyproject.toml . -COPY poetry.lock . +COPY requirements/dev.txt . +RUN pip install -r dev.txt --no-cache-dir # Copy source code -COPY src/. /app/ +COPY . . + +WORKDIR ./src -RUN poetry config virtualenvs.create false \ - && poetry install --without dev --no-root +RUN export RUN_BOT=true -CMD ["poetry", "run", "uvicorn", "core.asgi_prod:application", "--lifespan", "on", "--host", "0.0.0.0", "--port", "8000"] +CMD ["uvicorn", "core.asgi_dev:application", "--lifespan", "on", "--host", "0.0.0.0", "--port", "8000"] diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 0000000..799a937 --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,77 @@ +anyio==4.4.0 ; python_version >= "3.12" and python_version < "4.0" +apscheduler==3.10.4 ; python_version >= "3.12" and python_version < "4.0" +asgiref==3.8.1 ; python_version >= "3.12" and python_version < "4.0" +build==1.2.1 ; python_version >= "3.12" and python_version < "4.0" +cachecontrol[filecache]==0.14.0 ; python_version >= "3.12" and python_version < "4.0" +certifi==2024.8.30 ; python_version >= "3.12" and python_version < "4.0" +cffi==1.17.0 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") +cfgv==3.4.0 ; python_version >= "3.12" and python_version < "4.0" +charset-normalizer==3.3.2 ; python_version >= "3.12" and python_version < "4.0" +cleo==2.1.0 ; python_version >= "3.12" and python_version < "4.0" +click==8.1.7 ; python_version >= "3.12" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows" or os_name == "nt") +crashtest==0.4.1 ; python_version >= "3.12" and python_version < "4.0" +cryptography==43.0.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux" +distlib==0.3.8 ; python_version >= "3.12" and python_version < "4.0" +django-asgi-lifespan==0.3.1 ; python_version >= "3.12" and python_version < "4.0" +django-bootstrap5==24.2 ; python_version >= "3.12" and python_version < "4.0" +django-environ==0.11.2 ; python_version >= "3.12" and python_version < "4" +django-filter==24.3 ; python_version >= "3.12" and python_version < "4.0" +django-material-admin==1.8.6 ; python_version >= "3.12" and python_version < "4.0" +django-phonenumber-field[phonenumbers]==7.3.0 ; python_version >= "3.12" and python_version < "4.0" +django-viewflow==2.2.7 ; python_version >= "3.12" and python_version < "4.0" +django==5.0.4 ; python_version >= "3.12" and python_version < "4.0" +dulwich==0.21.7 ; python_version >= "3.12" and python_version < "4.0" +factory-boy==3.3.1 ; python_version >= "3.12" and python_version < "4.0" +faker==28.1.0 ; python_version >= "3.12" and python_version < "4.0" +fastjsonschema==2.20.0 ; python_version >= "3.12" and python_version < "4.0" +filelock==3.15.4 ; python_version >= "3.12" and python_version < "4.0" +h11==0.14.0 ; python_version >= "3.12" and python_version < "4.0" +httpcore==1.0.5 ; python_version >= "3.12" and python_version < "4.0" +httpx==0.27.2 ; python_version >= "3.12" and python_version < "4.0" +identify==2.6.0 ; python_version >= "3.12" and python_version < "4.0" +idna==3.8 ; python_version >= "3.12" and python_version < "4.0" +installer==0.7.0 ; python_version >= "3.12" and python_version < "4.0" +jaraco-classes==3.4.0 ; python_version >= "3.12" and python_version < "4.0" +jeepney==0.8.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux" +keyring==24.3.1 ; python_version >= "3.12" and python_version < "4.0" +loguru==0.7.2 ; python_version >= "3.12" and python_version < "4.0" +more-itertools==10.4.0 ; python_version >= "3.12" and python_version < "4.0" +msgpack==1.0.8 ; python_version >= "3.12" and python_version < "4.0" +nodeenv==1.9.1 ; python_version >= "3.12" and python_version < "4.0" +packaging==24.1 ; python_version >= "3.12" and python_version < "4.0" +pexpect==4.9.0 ; python_version >= "3.12" and python_version < "4.0" +phonenumbers==8.13.44 ; python_version >= "3.12" and python_version < "4.0" +pkginfo==1.11.1 ; python_version >= "3.12" and python_version < "4.0" +platformdirs==4.2.2 ; python_version >= "3.12" and python_version < "4.0" +poetry-core==1.9.0 ; python_version >= "3.12" and python_version < "4.0" +poetry-plugin-export==1.8.0 ; python_version >= "3.12" and python_version < "4.0" +poetry==1.8.3 ; python_version >= "3.12" and python_version < "4.0" +pre-commit==3.8.0 ; python_version >= "3.12" and python_version < "4.0" +psycopg2-binary==2.9.9 ; python_version >= "3.12" and python_version < "4.0" +ptyprocess==0.7.0 ; python_version >= "3.12" and python_version < "4.0" +pycparser==2.22 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") +pyproject-hooks==1.1.0 ; python_version >= "3.12" and python_version < "4.0" +python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0" +python-telegram-bot[job-queue]==21.4 ; python_version >= "3.12" and python_version < "4.0" +pytz==2024.1 ; python_version >= "3.12" and python_version < "4.0" +pywin32-ctypes==0.2.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" +pyyaml==6.0.2 ; python_version >= "3.12" and python_version < "4.0" +rapidfuzz==3.9.6 ; python_version >= "3.12" and python_version < "4.0" +requests-toolbelt==1.0.0 ; python_version >= "3.12" and python_version < "4.0" +requests==2.32.3 ; python_version >= "3.12" and python_version < "4.0" +ruff==0.4.10 ; python_version >= "3.12" and python_version < "4.0" +secretstorage==3.3.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux" +shellingham==1.5.4 ; python_version >= "3.12" and python_version < "4.0" +six==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +sniffio==1.3.1 ; python_version >= "3.12" and python_version < "4.0" +sqlparse==0.5.1 ; python_version >= "3.12" and python_version < "4.0" +tomlkit==0.13.2 ; python_version >= "3.12" and python_version < "4.0" +trove-classifiers==2024.7.2 ; python_version >= "3.12" and python_version < "4.0" +tzdata==2024.1 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows") +tzlocal==5.2 ; python_version >= "3.12" and python_version < "4.0" +urllib3==2.2.2 ; python_version >= "3.12" and python_version < "4.0" +uvicorn==0.29.0 ; python_version >= "3.12" and python_version < "4.0" +virtualenv==20.26.3 ; python_version >= "3.12" and python_version < "4.0" +win32-setctime==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" +xattr==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "darwin" diff --git a/requirements/prod.txt b/requirements/prod.txt new file mode 100644 index 0000000..772a757 --- /dev/null +++ b/requirements/prod.txt @@ -0,0 +1,68 @@ +anyio==4.4.0 ; python_version >= "3.12" and python_version < "4.0" +apscheduler==3.10.4 ; python_version >= "3.12" and python_version < "4.0" +asgiref==3.8.1 ; python_version >= "3.12" and python_version < "4.0" +build==1.2.1 ; python_version >= "3.12" and python_version < "4.0" +cachecontrol[filecache]==0.14.0 ; python_version >= "3.12" and python_version < "4.0" +certifi==2024.8.30 ; python_version >= "3.12" and python_version < "4.0" +cffi==1.17.0 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") +charset-normalizer==3.3.2 ; python_version >= "3.12" and python_version < "4.0" +cleo==2.1.0 ; python_version >= "3.12" and python_version < "4.0" +click==8.1.7 ; python_version >= "3.12" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows" or os_name == "nt") +crashtest==0.4.1 ; python_version >= "3.12" and python_version < "4.0" +cryptography==43.0.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux" +distlib==0.3.8 ; python_version >= "3.12" and python_version < "4.0" +django-asgi-lifespan==0.3.1 ; python_version >= "3.12" and python_version < "4.0" +django-bootstrap5==24.2 ; python_version >= "3.12" and python_version < "4.0" +django-environ==0.11.2 ; python_version >= "3.12" and python_version < "4" +django-filter==24.3 ; python_version >= "3.12" and python_version < "4.0" +django-material-admin==1.8.6 ; python_version >= "3.12" and python_version < "4.0" +django-phonenumber-field[phonenumbers]==7.3.0 ; python_version >= "3.12" and python_version < "4.0" +django-viewflow==2.2.7 ; python_version >= "3.12" and python_version < "4.0" +django==5.0.4 ; python_version >= "3.12" and python_version < "4.0" +dulwich==0.21.7 ; python_version >= "3.12" and python_version < "4.0" +fastjsonschema==2.20.0 ; python_version >= "3.12" and python_version < "4.0" +filelock==3.15.4 ; python_version >= "3.12" and python_version < "4.0" +h11==0.14.0 ; python_version >= "3.12" and python_version < "4.0" +httpcore==1.0.5 ; python_version >= "3.12" and python_version < "4.0" +httpx==0.27.2 ; python_version >= "3.12" and python_version < "4.0" +idna==3.8 ; python_version >= "3.12" and python_version < "4.0" +installer==0.7.0 ; python_version >= "3.12" and python_version < "4.0" +jaraco-classes==3.4.0 ; python_version >= "3.12" and python_version < "4.0" +jeepney==0.8.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux" +keyring==24.3.1 ; python_version >= "3.12" and python_version < "4.0" +loguru==0.7.2 ; python_version >= "3.12" and python_version < "4.0" +more-itertools==10.4.0 ; python_version >= "3.12" and python_version < "4.0" +msgpack==1.0.8 ; python_version >= "3.12" and python_version < "4.0" +packaging==24.1 ; python_version >= "3.12" and python_version < "4.0" +pexpect==4.9.0 ; python_version >= "3.12" and python_version < "4.0" +phonenumbers==8.13.44 ; python_version >= "3.12" and python_version < "4.0" +pkginfo==1.11.1 ; python_version >= "3.12" and python_version < "4.0" +platformdirs==4.2.2 ; python_version >= "3.12" and python_version < "4.0" +poetry-core==1.9.0 ; python_version >= "3.12" and python_version < "4.0" +poetry-plugin-export==1.8.0 ; python_version >= "3.12" and python_version < "4.0" +poetry==1.8.3 ; python_version >= "3.12" and python_version < "4.0" +psycopg2-binary==2.9.9 ; python_version >= "3.12" and python_version < "4.0" +ptyprocess==0.7.0 ; python_version >= "3.12" and python_version < "4.0" +pycparser==2.22 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy") +pyproject-hooks==1.1.0 ; python_version >= "3.12" and python_version < "4.0" +python-telegram-bot[job-queue]==21.4 ; python_version >= "3.12" and python_version < "4.0" +pytz==2024.1 ; python_version >= "3.12" and python_version < "4.0" +pywin32-ctypes==0.2.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" +rapidfuzz==3.9.6 ; python_version >= "3.12" and python_version < "4.0" +requests-toolbelt==1.0.0 ; python_version >= "3.12" and python_version < "4.0" +requests==2.32.3 ; python_version >= "3.12" and python_version < "4.0" +secretstorage==3.3.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux" +shellingham==1.5.4 ; python_version >= "3.12" and python_version < "4.0" +six==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +sniffio==1.3.1 ; python_version >= "3.12" and python_version < "4.0" +sqlparse==0.5.1 ; python_version >= "3.12" and python_version < "4.0" +tomlkit==0.13.2 ; python_version >= "3.12" and python_version < "4.0" +trove-classifiers==2024.7.2 ; python_version >= "3.12" and python_version < "4.0" +tzdata==2024.1 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows") +tzlocal==5.2 ; python_version >= "3.12" and python_version < "4.0" +urllib3==2.2.2 ; python_version >= "3.12" and python_version < "4.0" +uvicorn==0.29.0 ; python_version >= "3.12" and python_version < "4.0" +virtualenv==20.26.3 ; python_version >= "3.12" and python_version < "4.0" +win32-setctime==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32" +xattr==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "darwin" diff --git a/src/bot/bot_interface.py b/src/bot/bot_interface.py index 53c7a76..bf1ebf5 100644 --- a/src/bot/bot_interface.py +++ b/src/bot/bot_interface.py @@ -178,7 +178,7 @@ async def _periodic_update_bot_commands(self): """Периодически обновлять команды бота.""" while not self._stop_event.is_set(): await self._update_bot_commands(self._app) - await asyncio.sleep(10) # Обновлять команды каждые 10 секунд + await asyncio.sleep(360) # Обновлять команды каждые 10 секунд async def get_app(self): """Public method to get the application instance."""