commit
3c8cd2872a
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@ celerybeat-schedule
|
|||
backend/static
|
||||
backend/media
|
||||
bot/logs.log
|
||||
bot/logfile.log
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
FROM python:3.11
|
||||
|
||||
# python envs
|
||||
ENV PYTHONFAULTHANDLER=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONHASHSEED=random \
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
||||
PIP_DEFAULT_TIMEOUT=100
|
||||
COPY . /app
|
||||
|
||||
# python dependencies
|
||||
COPY ./requirements.txt /
|
||||
RUN pip install -r ./requirements.txt
|
||||
|
||||
COPY ./scripts/entrypoint.sh ./scripts/start.sh ./scripts/gunicorn.sh ./scripts/start_celery.sh /
|
||||
# upload scripts
|
||||
|
||||
# Fix windows docker bug, convert CRLF to LF
|
||||
RUN sed -i 's/\r$//g' /start.sh && chmod +x /start.sh && sed -i 's/\r$//g' /entrypoint.sh && chmod +x /entrypoint.sh &&\
|
||||
sed -i 's/\r$//g' /gunicorn.sh && chmod +x /gunicorn.sh && sed -i 's/\r$//g' /start_celery.sh && chmod +x /start_celery.sh
|
||||
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
||||
|
||||
WORKDIR /app
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
cmd="$@"
|
||||
|
||||
function postgres_ready(){
|
||||
python << END
|
||||
import sys
|
||||
import os
|
||||
import psycopg2
|
||||
|
||||
try:
|
||||
dbname = os.getenv('POSTGRES_DB')
|
||||
user = os.getenv('POSTGRES_USER')
|
||||
password = os.getenv('POSTGRES_PASSWORD')
|
||||
host = os.getenv('DB_HOST', 'postgres')
|
||||
port = os.getenv('POSTGRES_PORT', '5432')
|
||||
conn = psycopg2.connect(dbname=dbname, user=user, password=password, host=host, port=port)
|
||||
except psycopg2.OperationalError:
|
||||
sys.exit(-1)
|
||||
sys.exit(0)
|
||||
END
|
||||
}
|
||||
|
||||
until postgres_ready; do
|
||||
>&2 echo "Postgres is unavailable - sleeping"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
>&2 echo "Postgres is up - continuing..."
|
||||
exec $cmd
|
0
backend/scripts/gunicorn.sh
Normal file → Executable file
0
backend/scripts/gunicorn.sh
Normal file → Executable file
0
backend/scripts/start.sh
Normal file → Executable file
0
backend/scripts/start.sh
Normal file → Executable file
8
backend/scripts/start_celery.sh
Normal file → Executable file
8
backend/scripts/start_celery.sh
Normal file → Executable file
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
|
||||
for i in {0..$CELERY_WORKER_COUNT}
|
||||
do
|
||||
celery -A clicker worker -l info --concurrency=10 -n worker$i@%h
|
||||
for i in $(seq 1 "${CELERY_WORKER_COUNT}"); do
|
||||
celery -A clicker worker -l info --concurrency=10 -n "worker${i}@$(%h)"
|
||||
done
|
||||
|
||||
celery -A clicker beat -l info
|
||||
|
|
|
@ -2,12 +2,10 @@ FROM python:3.12
|
|||
|
||||
WORKDIR /batcher
|
||||
|
||||
COPY ./requirements.txt /batcher/requirements.txt
|
||||
COPY ./ /batcher
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /batcher/requirements.txt
|
||||
|
||||
COPY ./app /batcher/app
|
||||
|
||||
ENV PYTHONPATH="${PYTHONPATH}:/batcher/app"
|
||||
|
||||
CMD uvicorn app.main:app --host 0.0.0.0 --port "${HTTP_PORT}"
|
||||
CMD uvicorn app.main:app --host 0.0.0.0 --port "${HTTP_PORT}"
|
||||
|
|
|
@ -15,14 +15,7 @@ MIGRATIONS_DIR = Path(__file__).parent.resolve() / "migrations"
|
|||
logger = logging.getLogger("uvicorn")
|
||||
|
||||
async def connect_pg() -> asyncpg.Pool:
|
||||
while True:
|
||||
try:
|
||||
logger.info(DB_URL)
|
||||
pg_conn = await asyncpg.create_pool(DB_URL)
|
||||
return pg_conn
|
||||
except OSError:
|
||||
logger.info("Postgres is unavailable - sleeping")
|
||||
await asyncio.sleep(2)
|
||||
return await asyncpg.create_pool(DB_URL)
|
||||
|
||||
|
||||
async def get_pg(request: Request) -> asyncpg.Connection:
|
||||
|
|
|
@ -11,13 +11,7 @@ fqdn = f'amqp://{RMQ_USER}:{str(RMQ_PASSWORD)}@{RMQ_HOST}:{RMQ_PORT}/'
|
|||
logger = logging.getLogger("uvicorn")
|
||||
|
||||
async def get_connection() -> AbstractRobustConnection:
|
||||
while True:
|
||||
try:
|
||||
conn = await aio_pika.connect_robust(fqdn)
|
||||
return conn
|
||||
except ConnectionError:
|
||||
logger.info("RabbitMQ is unavailable - sleeping")
|
||||
await asyncio.sleep(2)
|
||||
return await aio_pika.connect_robust(fqdn)
|
||||
|
||||
|
||||
async def get_channel(conn_pool: AbstractRobustConnection) -> aio_pika.Channel:
|
||||
|
|
|
@ -1,21 +1,7 @@
|
|||
FROM python:3.10.7
|
||||
FROM python:3.11
|
||||
|
||||
# python envs
|
||||
ENV PYTHONFAULTHANDLER=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONHASHSEED=random \
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
||||
PIP_DEFAULT_TIMEOUT=100
|
||||
|
||||
# python dependencies
|
||||
COPY ./requirements.txt /
|
||||
RUN pip install -r /requirements.txt
|
||||
|
||||
COPY ./scripts/start.sh ./scripts/gunicorn.sh /
|
||||
|
||||
RUN chmod +x /start.sh
|
||||
RUN chmod +x /gunicorn.sh
|
||||
COPY . /app
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
||||
|
||||
WORKDIR /app
|
||||
|
|
|
@ -8,7 +8,7 @@ from aiogram.dispatcher.filters.state import State, StatesGroup
|
|||
from create_bot import bot, important_message, event_number
|
||||
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from aiogram.utils.exceptions import MessageToDeleteNotFound
|
||||
from bot.dbm_defs import add_rec, get_rec
|
||||
from dbm_defs import add_rec, get_rec
|
||||
|
||||
from loguru import logger
|
||||
|
||||
|
|
0
bot/scripts/gunicorn.sh
Normal file → Executable file
0
bot/scripts/gunicorn.sh
Normal file → Executable file
0
bot/scripts/start.sh
Normal file → Executable file
0
bot/scripts/start.sh
Normal file → Executable file
|
@ -2,20 +2,23 @@ volumes:
|
|||
db_data: {}
|
||||
batcher_db_data: {}
|
||||
redis_data: {}
|
||||
backend_media: {}
|
||||
certbot_www: {}
|
||||
certbot_conf: {}
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
command: /gunicorn.sh
|
||||
entrypoint: /entrypoint.sh
|
||||
- backend_media:/app/media
|
||||
command: /app/scripts/gunicorn.sh
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
env_file:
|
||||
postgres: &healthy-dependency
|
||||
condition: service_healthy
|
||||
rabbitmq: *healthy-dependency
|
||||
env_file: &backend-env-files
|
||||
- .env/prod/pg
|
||||
- .env/prod/back
|
||||
- .env/prod/rmq
|
||||
|
@ -23,29 +26,33 @@ services:
|
|||
- .env/prod/web
|
||||
|
||||
bot:
|
||||
build:
|
||||
context: ./bot
|
||||
build: ./bot
|
||||
depends_on:
|
||||
- backend
|
||||
volumes:
|
||||
- ./bot:/app
|
||||
environment:
|
||||
PROD: 1
|
||||
backend: &started-dependency
|
||||
condition: service_started
|
||||
batcher: *started-dependency
|
||||
memcached: *started-dependency
|
||||
env_file:
|
||||
- .env/prod/bot
|
||||
- .env/prod/web
|
||||
command: /gunicorn.sh
|
||||
command: /app/scripts/gunicorn.sh
|
||||
restart: on-failure
|
||||
|
||||
memcached:
|
||||
image: memcached:latest
|
||||
|
||||
postgres:
|
||||
image: postgres:14.5-alpine
|
||||
postgres: &pg-conf
|
||||
image: postgres:17-alpine
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
env_file:
|
||||
- .env/prod/pg
|
||||
user: postgres
|
||||
healthcheck: &pg-healthcheck
|
||||
test: [ "CMD-SHELL", "pg_isready" ]
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 5
|
||||
|
||||
nginx:
|
||||
build:
|
||||
|
@ -55,61 +62,30 @@ services:
|
|||
- '80:80'
|
||||
- '443:443'
|
||||
depends_on:
|
||||
- backend
|
||||
- bot
|
||||
- rabbitmq
|
||||
- batcher
|
||||
bot: *started-dependency
|
||||
volumes:
|
||||
- ./backend/static/:/static/
|
||||
- ./nginx/certbot/conf:/etc/letsencrypt
|
||||
- ./nginx/certbot/www:/var/www/certbot
|
||||
restart: unless-stopped
|
||||
command: '/bin/sh -c ''while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"'''
|
||||
|
||||
certbot:
|
||||
container_name: certbot
|
||||
image: certbot/certbot
|
||||
volumes:
|
||||
- ./nginx/certbot/conf:/etc/letsencrypt
|
||||
- ./nginx/certbot/www:/var/www/certbot
|
||||
restart: unless-stopped
|
||||
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
||||
|
||||
celery:
|
||||
build: ./backend
|
||||
command: /start_celery.sh
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
env_file:
|
||||
- .env/prod/back
|
||||
- .env/prod/rmq
|
||||
- .env/prod/pg
|
||||
- .env/prod/bot
|
||||
command: /app/scripts/start_celery.sh
|
||||
env_file: *backend-env-files
|
||||
environment:
|
||||
- CELERY_WORKER_COUNT=10
|
||||
depends_on:
|
||||
- backend
|
||||
- rabbitmq
|
||||
|
||||
celery-beat:
|
||||
build: ./backend
|
||||
command: celery -A clicker beat -l info
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
env_file:
|
||||
- .env/prod/back
|
||||
- .env/prod/rmq
|
||||
- .env/prod/pg
|
||||
- .env/prod/bot
|
||||
depends_on:
|
||||
- backend
|
||||
- rabbitmq
|
||||
backend: *started-dependency
|
||||
|
||||
rabbitmq:
|
||||
container_name: 'rabbitmq'
|
||||
image: 'rabbitmq:3-management-alpine'
|
||||
env_file:
|
||||
- .env/prod/rmq
|
||||
ports:
|
||||
- '15672:15672'
|
||||
healthcheck:
|
||||
<<: *pg-healthcheck
|
||||
test: rabbitmq-diagnostics -q ping
|
||||
interval: 10s
|
||||
timeout: 2s
|
||||
|
||||
redis:
|
||||
env_file:
|
||||
|
@ -118,14 +94,16 @@ services:
|
|||
command: bash -c "redis-server --appendonly yes --requirepass $${REDIS_PASSWORD}"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
<<: *pg-healthcheck
|
||||
test: "[ $$(redis-cli -a $${REDIS_PASSWORD} ping) = 'PONG' ]"
|
||||
|
||||
batcher:
|
||||
build:
|
||||
context: ./batcher
|
||||
build: ./batcher
|
||||
depends_on:
|
||||
- redis
|
||||
- batcher-postgres
|
||||
- rabbitmq
|
||||
redis: *healthy-dependency
|
||||
batcher-postgres: *healthy-dependency
|
||||
rabbitmq: *healthy-dependency
|
||||
env_file:
|
||||
- .env/prod/rmq
|
||||
- .env/prod/redis
|
||||
|
@ -134,7 +112,7 @@ services:
|
|||
- .env/prod/bot
|
||||
|
||||
batcher-postgres:
|
||||
image: postgres:14.5-alpine
|
||||
<<: *pg-conf
|
||||
volumes:
|
||||
- batcher_db_data:/var/lib/postgresql/data
|
||||
env_file:
|
||||
|
|
|
@ -2,20 +2,20 @@ volumes:
|
|||
db_data: {}
|
||||
batcher_db_data: {}
|
||||
redis_data: {}
|
||||
backend_media: {}
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
build: ./backend
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
postgres: &healthy-dependency
|
||||
condition: service_healthy
|
||||
rabbitmq: *healthy-dependency
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
command: /start.sh
|
||||
entrypoint: /entrypoint.sh
|
||||
- backend_media:/app/media
|
||||
command: /app/scripts/start.sh
|
||||
restart: on-failure
|
||||
env_file:
|
||||
env_file: &backend-env-files
|
||||
- .env/dev/pg
|
||||
- .env/dev/back
|
||||
- .env/dev/rmq
|
||||
|
@ -24,44 +24,31 @@ services:
|
|||
ports:
|
||||
- '8000:8000'
|
||||
|
||||
postgres:
|
||||
image: postgres:14.5-alpine
|
||||
postgres: &pg-conf
|
||||
image: postgres:17-alpine
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
env_file:
|
||||
- .env/dev/pg
|
||||
ports:
|
||||
- '5432:5432'
|
||||
user: postgres
|
||||
healthcheck: &pg-healthcheck
|
||||
test: [ "CMD-SHELL", "pg_isready" ]
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 5
|
||||
|
||||
celery:
|
||||
build: ./backend
|
||||
command: celery -A clicker worker -l info
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
env_file:
|
||||
- .env/dev/back
|
||||
- .env/dev/rmq
|
||||
- .env/dev/pg
|
||||
- .env/dev/bot
|
||||
- .env/dev/web
|
||||
command: /app/scripts/start_celery.sh
|
||||
env_file: *backend-env-files
|
||||
environment:
|
||||
- CELERY_WORKER_COUNT=1
|
||||
depends_on:
|
||||
- backend
|
||||
- rabbitmq
|
||||
|
||||
celery-beat:
|
||||
build: ./backend
|
||||
command: celery -A clicker beat -l info
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
env_file:
|
||||
- .env/dev/back
|
||||
- .env/dev/rmq
|
||||
- .env/dev/pg
|
||||
- .env/dev/bot
|
||||
- .env/dev/web
|
||||
depends_on:
|
||||
- backend
|
||||
- rabbitmq
|
||||
backend:
|
||||
condition: service_started
|
||||
rabbitmq: *healthy-dependency
|
||||
|
||||
rabbitmq:
|
||||
container_name: 'rabbitmq'
|
||||
|
@ -71,6 +58,11 @@ services:
|
|||
ports:
|
||||
- '5672:5672'
|
||||
- '15672:15672'
|
||||
healthcheck:
|
||||
<<: *pg-healthcheck
|
||||
test: rabbitmq-diagnostics -q ping
|
||||
interval: 10s
|
||||
timeout: 2s
|
||||
|
||||
redis:
|
||||
env_file:
|
||||
|
@ -81,13 +73,16 @@ services:
|
|||
- '6379:6379'
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
<<: *pg-healthcheck
|
||||
test: "[ $$(redis-cli -a $$REDIS_PASSWORD ping) = 'PONG' ]"
|
||||
|
||||
batcher:
|
||||
build:
|
||||
context: ./batcher
|
||||
build: ./batcher
|
||||
depends_on:
|
||||
- redis
|
||||
- batcher-postgres
|
||||
redis: *healthy-dependency
|
||||
batcher-postgres: *healthy-dependency
|
||||
rabbitmq: *healthy-dependency
|
||||
env_file:
|
||||
- .env/dev/rmq
|
||||
- .env/dev/redis
|
||||
|
@ -99,7 +94,7 @@ services:
|
|||
- '8080:8080'
|
||||
|
||||
batcher-postgres:
|
||||
image: postgres:14.5-alpine
|
||||
<<: *pg-conf
|
||||
volumes:
|
||||
- batcher_db_data:/var/lib/postgresql/data
|
||||
env_file:
|
||||
|
|
|
@ -13,7 +13,11 @@ RUN npm run build
|
|||
|
||||
# stage 2 - nginx
|
||||
FROM nginx:stable
|
||||
|
||||
COPY nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
COPY backend/static /static
|
||||
|
||||
COPY --from=build-deps /app/dist/ /dist/
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
|
|
@ -42,33 +42,11 @@ http {
|
|||
access_log /var/log/nginx/access.log upstreamlog;
|
||||
error_log /var/log/nginx/error.log;
|
||||
listen 80;
|
||||
# listen 443 ssl http2;
|
||||
charset utf-8;
|
||||
# server_name kyc_clicker.ru www.kyc_clicker.ru;
|
||||
|
||||
root /dist/;
|
||||
index index.html;
|
||||
|
||||
# ssl_certificate /etc/letsencrypt/live/kyc_clicker.ru/fullchain.pem;
|
||||
# ssl_certificate_key /etc/letsencrypt/live/kyc_clicker.ru/privkey.pem;
|
||||
|
||||
# include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
# if ($server_port = 80) {
|
||||
# set $https_redirect 1;
|
||||
# }
|
||||
# if ($host ~ '^www\.') {
|
||||
# set $https_redirect 1;
|
||||
# }
|
||||
# if ($https_redirect = 1) {
|
||||
# return 301 https://crowngame.ru$request_uri;
|
||||
# }
|
||||
|
||||
# location /.well-known/acme-challenge/ {
|
||||
# root /var/www/certbot;
|
||||
# }
|
||||
|
||||
# frontend
|
||||
location / {
|
||||
try_files $uri $uri/ @rewrites;
|
||||
|
@ -79,7 +57,8 @@ http {
|
|||
}
|
||||
|
||||
# batcher
|
||||
location ~ ^/api/v1/(batch\-click|click|energy|coefficient)(/(.*))? {
|
||||
location ~ ^/api/v1/batcher(/?.*) {
|
||||
rewrite ^(/api/v1)/batcher(/?.*)$ $1/$2 last;
|
||||
proxy_pass http://batcher;
|
||||
proxy_pass_header Authorization;
|
||||
}
|
||||
|
@ -98,29 +77,12 @@ http {
|
|||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
if ($uri ~* \.(?:ico|js|css|gif|jpe?g|png|webp)/?$) {
|
||||
expires max;
|
||||
add_header Pragma public;
|
||||
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
|
||||
}
|
||||
}
|
||||
|
||||
# bot
|
||||
location ~ ^/bot {
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://bot;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
# backend static
|
||||
|
|
Loading…
Reference in New Issue
Block a user