From 7c686f68f3ce96a9443e37ee0bcde038d1d9c948 Mon Sep 17 00:00:00 2001 From: Squ1reX Date: Fri, 29 May 2026 17:55:53 +0300 Subject: [PATCH 1/6] feat(docker): Isolate services by separating docker networks --- docker-compose.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7b68220..a3cf35b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,8 @@ services: - postgres_data:/var/lib/postgresql/data # стандартное мето хранения файлов postgres (имя_volume:путь внутри контейнера) mem_limit: 512m mem_reservation: 256m + networks: + - api_db_net api: image: ghcr.io/fl1rix/steeltime-api:latest @@ -35,6 +37,9 @@ services: restart: unless-stopped mem_limit: 1g # Лимиты ресурсов cpus: 0.5 + networks: + - api_bot_net + - api_db_net bot: @@ -49,6 +54,8 @@ services: condition: service_healthy mem_limit: 256m cpus: 0.25 + networks: + - api_bot_net watchtower: image: containrrr/watchtower @@ -61,6 +68,9 @@ volumes: driver: local networks: - default: + api_db_net: driver: bridge - name: steeltime_network \ No newline at end of file + internal: true + + api_bot_net: + driver: bridge \ No newline at end of file From 1dc9165558f16529e31c66e2a40c02f0df05400c Mon Sep 17 00:00:00 2001 From: Squ1reX Date: Fri, 29 May 2026 19:46:55 +0300 Subject: [PATCH 2/6] feat(docker): Add a system user app. Remove buffering and .pyc, __pycache__ files. --- .dockerignore | 8 +++++++- Dockerfile.api | 6 ++++++ Dockerfile.bot | 15 ++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index ea7e79c..7d6764a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,6 +4,12 @@ __pycache__/ .venv/ .vscode/ .mypy_cache/ +.pytest_cache/ +.ruff_cache/ +.coverage +coverage.xml +TODO.md tests/ db_test_data.py -LICENSE \ No newline at end of file +LICENSE +.env \ No newline at end of file diff --git a/Dockerfile.api b/Dockerfile.api index 97154a8..7ab531d 100644 --- a/Dockerfile.api +++ b/Dockerfile.api @@ -5,6 +5,9 @@ FROM python:3.13-slim # создаем папку /app. Весь код будет тут WORKDIR /app +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + # Копируем только requrements.txt(кэшируется) COPY requirements.txt . @@ -18,6 +21,9 @@ COPY . . RUN rm -rf /app/src/bot RUN chmod +x entrypoint.sh +RUN useradd -m -r app +USER app + # Открываем порт EXPOSE 8000 diff --git a/Dockerfile.bot b/Dockerfile.bot index e46e5f8..095b258 100644 --- a/Dockerfile.bot +++ b/Dockerfile.bot @@ -3,9 +3,13 @@ FROM python:3.13-slim WORKDIR /app +#Отключаем создание файлов .pyc и __pycache__ +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + # Установка системных зависимостей RUN apt-get update && apt-get install -y \ - gcc \ + gcc \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt . @@ -14,6 +18,15 @@ COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt +# Создаем пользователя +# -m создает домашнюю директорию пользователя. +# -r - создает системного пользователя(служебная учетка с ограниченными правами) +# через chown рекурсивно(-R) меняем права доступа на файлах каталога для пользователя app, группы app (app:app) +RUN useradd -m -r app && \ + chown -R app:app /app + +USER app + COPY src/presentation/bot ./src/presentation/bot COPY src/logger.py ./src/ COPY src/domain/services ./src/domain/services From 8fbbdeb42b8eb0476247f85252385869c5a3eaf6 Mon Sep 17 00:00:00 2001 From: Squ1reX Date: Fri, 29 May 2026 22:15:38 +0300 Subject: [PATCH 3/6] feat(docker): Remove root privileges. Add cap_drop to disable root privileges. Enable write access to the /tmp folder. --- docker-compose.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index a3cf35b..7555290 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,8 @@ services: mem_reservation: 256m networks: - api_db_net + security_opt: + - no-new-privileges:true # Запрет на повышение прав до root api: image: ghcr.io/fl1rix/steeltime-api:latest @@ -40,8 +42,14 @@ services: networks: - api_bot_net - api_db_net + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + tmpfs: + - /tmp - bot: image: ghcr.io/fl1rix/steeltime-bot:latest restart: unless-stopped @@ -56,12 +64,23 @@ services: cpus: 0.25 networks: - api_bot_net + read_only: true + security_opt: + - no-new-privileges:true + cap_drop: # Забирает все доступные привелегии у root пользователя. + - ALL + tmpfs: # Папко, доступная длоя записи инфорамции, ы случае надобности. + - /tmp watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock command: --interval 300 + security_opt: + - no-new-privileges:true + tmpfs: + - /tmp volumes: postgres_data: From 629c64d04c6f6dc182a1e6c628e1960558a72755 Mon Sep 17 00:00:00 2001 From: Squ1reX Date: Fri, 29 May 2026 22:16:21 +0300 Subject: [PATCH 4/6] feat(logger): Remove logging to a file --- src/logger.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/logger.py b/src/logger.py index 2036122..493e140 100644 --- a/src/logger.py +++ b/src/logger.py @@ -9,8 +9,4 @@ console_handler = logging.StreamHandler() # вывод логов в консоль console_handler.setFormatter(formatter) -handler = logging.FileHandler(filename="SteelTime.log", encoding="utf-8") # файл для записи логов -handler.setFormatter(formatter) - -logger.addHandler(handler) logger.addHandler(console_handler) \ No newline at end of file From f46d2ae7415b2864b43e0f3bef5bce05c20cb96b Mon Sep 17 00:00:00 2001 From: Squ1reX Date: Fri, 29 May 2026 22:17:44 +0300 Subject: [PATCH 5/6] feat(docker): Write a user creation command in the api container and transfer the user change to the bot container --- Dockerfile.api | 3 ++- Dockerfile.bot | 9 +++++---- src/presentation/api/v1/auth/tg_link.py | 2 -- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Dockerfile.api b/Dockerfile.api index 7ab531d..f6dd8d7 100644 --- a/Dockerfile.api +++ b/Dockerfile.api @@ -21,7 +21,8 @@ COPY . . RUN rm -rf /app/src/bot RUN chmod +x entrypoint.sh -RUN useradd -m -r app +RUN useradd -m -r app \ + chown -R app:app /app USER app # Открываем порт diff --git a/Dockerfile.bot b/Dockerfile.bot index 095b258..4b70a78 100644 --- a/Dockerfile.bot +++ b/Dockerfile.bot @@ -22,10 +22,6 @@ RUN pip install --no-cache-dir --upgrade pip && \ # -m создает домашнюю директорию пользователя. # -r - создает системного пользователя(служебная учетка с ограниченными правами) # через chown рекурсивно(-R) меняем права доступа на файлах каталога для пользователя app, группы app (app:app) -RUN useradd -m -r app && \ - chown -R app:app /app - -USER app COPY src/presentation/bot ./src/presentation/bot COPY src/logger.py ./src/ @@ -33,4 +29,9 @@ COPY src/domain/services ./src/domain/services COPY src/shared/ ./src/shared/ COPY src/config.py ./src/ +RUN useradd -m -r app && \ + chown -R app:app /app + +USER app + CMD ["python", "-m", "src.presentation.bot.handlers.bot"] diff --git a/src/presentation/api/v1/auth/tg_link.py b/src/presentation/api/v1/auth/tg_link.py index 90381cc..f706913 100644 --- a/src/presentation/api/v1/auth/tg_link.py +++ b/src/presentation/api/v1/auth/tg_link.py @@ -51,8 +51,6 @@ async def create_telegram_magic_link( token = secrets.token_urlsafe(32) expires = datetime.now(timezone.utc) + timedelta(minutes=10) - #! TODO: Добавить изоляцию на уровне docker - logger.info("Сохранение magic токена...") await TgLinkService.save_link_token(token=token, expires_at=expires, db=db, telegram_id=telegram_id) logger.info("Токен успешно сохранен!") From 22fb43df4b17ae38371774ff797972dfa776ecbc Mon Sep 17 00:00:00 2001 From: Squ1reX Date: Fri, 29 May 2026 22:22:42 +0300 Subject: [PATCH 6/6] docs: Correct syntax errors --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7555290..6270bf2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -67,9 +67,9 @@ services: read_only: true security_opt: - no-new-privileges:true - cap_drop: # Забирает все доступные привелегии у root пользователя. + cap_drop: # Забирает все доступные привилегии у root пользователя. - ALL - tmpfs: # Папко, доступная длоя записи инфорамции, ы случае надобности. + tmpfs: # Папка, доступная для записи инфорамции, в случае надобности. - /tmp watchtower: