Skip to content

Feature/docker security improvements#25

Merged
Fl1riX merged 6 commits into
mainfrom
feature/docker-security-improvements
May 29, 2026
Merged

Feature/docker security improvements#25
Fl1riX merged 6 commits into
mainfrom
feature/docker-security-improvements

Conversation

@Fl1riX
Copy link
Copy Markdown
Owner

@Fl1riX Fl1riX commented May 29, 2026

Summary by Sourcery

Усилить настройки безопасности контейнеров и упростить конфигурацию логирования за счёт ограничения возможностей сервисов, изоляции сетей и отказа от файлового логирования.

Улучшения:

  • Ужесточить безопасность Docker для сервисов postgres, api, bot и watchtower путём добавления изолированных сетей, отключения Linux‑способностей (capabilities), включения файловых систем только для чтения и запрета повышения привилегий.
  • Перестроить Docker‑сеть на отдельные внутренние сети для взаимодействия API–БД и API–bot, чтобы уменьшить перекрёстное воздействие между сервисами.
  • Упростить логирование, отказавшись от файлового логирования и полагаясь исключительно на вывод в консоль.
Original summary in English

Summary by Sourcery

Harden container security settings and simplify logging configuration by restricting service capabilities, isolating networks, and removing file-based logging.

Enhancements:

  • Tighten Docker security for postgres, api, bot, and watchtower services by adding isolated networks, dropping Linux capabilities, enabling read-only filesystems, and disallowing privilege escalation.
  • Restructure Docker networking into separate internal networks for API–DB communication and API–bot communication to reduce cross-service exposure.
  • Simplify logging by removing file-based logging and relying solely on console output.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 29, 2026

Руководство для рецензента

Усиливает безопасность контейнеров и изоляцию ресурсов в docker-compose, упрощает логирование до вывода только в консоль и удаляет устаревший TODO, поскольку теперь реализована изоляция на уровне Docker; также подразумеваются дополнительные изменения в Docker‑файлах, не показанные явно.

Изменения по файлам

Изменение Подробности Файлы
Усиление безопасности и изоляции для сервисов PostgreSQL, API, бота и watchtower в docker-compose.
  • Подключить postgres к выделенной внутренней сети api_db_net и запретить повышение привилегий с помощью no-new-privileges
  • Подключить сервис api к выделенным сетям api_bot_net и api_db_net, сделать файловую систему только для чтения, убрать все Linux capabilities, примонтировать /tmp как tmpfs и запретить повышение привилегий
  • Подключить сервис bot к api_bot_net, сделать файловую систему только для чтения, убрать все capabilities, примонтировать /tmp как tmpfs и запретить повышение привилегий
  • Ужесточить настройки watchtower, запретив повышение привилегий и используя примонтированный как tmpfs каталог /tmp
  • Заменить единственную сеть по умолчанию на две явные bridge‑сети (api_db_net как internal и api_bot_net)
docker-compose.yml
Ограничение логирования только выводом в консоль вместо записи в файл внутри контейнера.
  • Удалить конфигурацию FileHandler, которая записывала логи в SteelTime.log
  • Оставить только консольное логирование через StreamHandler
src/logger.py
Очистка устаревшего комментария TODO, связанного с Docker‑изоляцией в endpoint’е Telegram magic link.
  • Удалить TODO о добавлении изоляции на уровне Docker, поскольку меры безопасности в compose уже реализованы
src/presentation/api/v1/auth/tg_link.py
Корректировка Docker‑связанного build context и конфигурации образов (детали не полностью видны в diff).
  • Обновить или добавить шаблоны ignore для Docker build context в .dockerignore
  • Изменить Dockerfile сервиса API, вероятно, для согласования с новой конфигурацией безопасности/логирования
  • Изменить Dockerfile сервиса бота, вероятно, для согласования с новой конфигурацией безопасности/логирования
.dockerignore
Dockerfile.api
Dockerfile.bot

Подсказки и команды

Взаимодействие с Sourcery

  • Запустить новый обзор: Оставьте комментарий @sourcery-ai review в pull request’е.
  • Продолжить обсуждения: Отвечайте напрямую на комментарии обзора от Sourcery.
  • Создать задачу GitHub из комментария обзора: Попросите Sourcery создать
    issue из комментария обзора, ответив на него. Также можно ответить на
    комментарий обзора командой @sourcery-ai issue, чтобы создать issue.
  • Сгенерировать заголовок pull request’а: Напишите @sourcery-ai где угодно
    в заголовке pull request’а, чтобы сгенерировать заголовок в любой момент.
    Также можно оставить комментарий @sourcery-ai title в pull request’е,
    чтобы (пере)сгенерировать заголовок в любой момент.
  • Сгенерировать краткое описание pull request’а: Напишите @sourcery-ai summary
    где угодно в теле pull request’а, чтобы сгенерировать краткое описание (PR summary)
    именно в том месте, где вы его хотите видеть. Также можно оставить комментарий
    @sourcery-ai summary в pull request’е, чтобы (пере)сгенерировать summary в любой момент.
  • Сгенерировать руководство для рецензента: Оставьте комментарий
    @sourcery-ai guide в pull request’е, чтобы (пере)сгенерировать руководство
    для рецензента в любой момент.
  • Пометить все комментарии Sourcery как решённые: Оставьте комментарий
    @sourcery-ai resolve в pull request’е, чтобы пометить все комментарии Sourcery
    как решённые. Полезно, если вы уже учли все замечания и больше не хотите их видеть.
  • Отклонить все обзоры Sourcery: Оставьте комментарий @sourcery-ai dismiss
    в pull request’е, чтобы отклонить все существующие обзоры Sourcery. Особенно полезно,
    если вы хотите начать с чистого листа с новым обзором — не забудьте затем
    оставить комментарий @sourcery-ai review, чтобы запустить новый обзор!

Настройка работы сервиса

Перейдите в свою панель управления, чтобы:

  • Включить или отключить функции обзора, такие как автоматически
    сгенерированное Sourcery краткое описание pull request’а, руководство
    для рецензента и другие.
  • Изменить язык обзора.
  • Добавлять, удалять или редактировать пользовательские инструкции для обзора.
  • Настроить другие параметры обзора.

Получение помощи

Original review guide in English

Reviewer's Guide

Tightens container security and resource isolation in docker-compose, simplifies logging to console-only, and removes an obsolete TODO now that Docker-level isolation is in place, with additional Docker-related file changes implied but not shown.

File-Level Changes

Change Details Files
Strengthen security and isolation for PostgreSQL, API, bot, and watchtower services in docker-compose.
  • Attach postgres to a dedicated internal api_db_net network and forbid privilege escalation via no-new-privileges
  • Attach api service to dedicated api_bot_net and api_db_net networks, make filesystem read-only, drop all Linux capabilities, mount /tmp as tmpfs, and forbid privilege escalation
  • Attach bot service to api_bot_net, make filesystem read-only, drop all capabilities, mount /tmp as tmpfs, and forbid privilege escalation
  • Harden watchtower by forbidding privilege escalation and using a tmpfs-mounted /tmp
  • Replace the single default network with two explicit bridge networks (api_db_net as internal and api_bot_net)
docker-compose.yml
Restrict logging to console output only instead of writing to a file inside the container.
  • Remove FileHandler configuration that wrote logs to SteelTime.log
  • Keep only console-based logging through StreamHandler
src/logger.py
Clean up an obsolete TODO comment related to Docker isolation in the Telegram magic link endpoint.
  • Remove the TODO about adding Docker-level isolation since compose security controls are now implemented
src/presentation/api/v1/auth/tg_link.py
Adjust Docker-related build context and image configuration (details not fully visible in diff).
  • Update or add ignore patterns for Docker build context in .dockerignore
  • Modify API service Dockerfile, likely to align with new security/logging setup
  • Modify bot service Dockerfile, likely to align with new security/logging setup
.dockerignore
Dockerfile.api
Dockerfile.bot

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет — я нашёл 3 проблемы и оставил несколько общих комментариев:

  • Удаление FileHandler из logger.py переводит логирование в режим только консольного вывода; если в продакшене по‑прежнему нужны постоянные логи, имеет смысл направлять их в файл на примонтированный том или в централизованную систему логирования, а не полностью отказываться от файлового логирования.
  • Пометка api_db_net как internal: true и разделение сетей на api_db_net / api_bot_net усиливает изоляцию сервисов; перепроверьте, что любые внешние инструменты (например, миграции, админ‑клиенты), которым нужен доступ к Postgres или API, либо подключены к этим сетям, либо корректно выставлены наружу, иначе можно случайно потерять коннект.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Удаление `FileHandler` из `logger.py` переводит логирование в режим только консольного вывода; если в продакшене по‑прежнему нужны постоянные логи, имеет смысл направлять их в файл на примонтированный том или в централизованную систему логирования, а не полностью отказываться от файлового логирования.
- Пометка `api_db_net` как `internal: true` и разделение сетей на `api_db_net` / `api_bot_net` усиливает изоляцию сервисов; перепроверьте, что любые внешние инструменты (например, миграции, админ‑клиенты), которым нужен доступ к Postgres или API, либо подключены к этим сетям, либо корректно выставлены наружу, иначе можно случайно потерять коннект.

## Individual Comments

### Comment 1
<location path="docker-compose.yml" line_range="94" />
<code_context>
\ No newline at end of file
+    internal: true
+  
+  api_bot_net: 
+    driver: bridge
\ No newline at end of file
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Рассмотрите возможность отметить `api_bot_net` как `internal: true`, если эта сеть используется только для внутреннего взаимодействия API и бота.

Поскольку `api_db_net` уже помечена как `internal` для изоляции, применение того же флага к `api_bot_net` (если она не должна быть доступна извне) сделает конфигурацию более последовательной и ещё сильнее ограничит непреднамеренное раскрытие сервисов наружу.
</issue_to_address>

### Comment 2
<location path="src/logger.py" line_range="12-15" />
<code_context>
 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
</code_context>
<issue_to_address>
**suggestion:** Вместо полного удаления файлового логирования лучше сделать его настраиваемым.

Удаление `FileHandler` хорошо подходит для контейнеризованных развёртываний, которые используют stdout, но снижает гибкость для окружений, где файловые логи по‑прежнему полезны (например, bare metal или локальная разработка). Рассмотрите вариант спрятать `FileHandler` за переменной окружения или конфигурационным флагом, чтобы stdout оставался значением по умолчанию, а при необходимости можно было включить логирование в файл.

Suggested implementation:

```python
import os

console_handler = logging.StreamHandler()  # вывод логов в консоль
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

# Optional file logging, controlled via environment variable
if os.getenv("ENABLE_FILE_LOGGING", "false").lower() in ("1", "true", "yes"):
    log_file = os.getenv("LOG_FILE", "SteelTime.log")
    file_handler = logging.FileHandler(filename=log_file, encoding="utf-8")
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)

```

1. Если в `src/logger.py` модуль `os` уже импортируется в начале файла, удалите дублирующий `import os` из этого блока и оставьте один импорт.
2. Если `formatter` или `logger` не определены ранее в `src/logger.py`, убедитесь, что они создаются до этого блока (например, `logger = logging.getLogger(__name__)` и соответствующее объявление форматтера).
3. Обновите конфигурацию деплоя или документацию, чтобы упомянуть:
   - `ENABLE_FILE_LOGGING` (установить в `true`/`1`/`yes` для включения файловых логов),
   - `LOG_FILE` (необязательный путь/имя файла логов).
</issue_to_address>

### Comment 3
<location path="docker-compose.yml" line_range="70-72" />
<code_context>
+    read_only: true
+    security_opt:
+      - no-new-privileges:true
+    cap_drop: # Забирает все доступные привелегии у root пользователя.
+      - ALL
+    tmpfs: # Папко, доступная длоя записи инфорамции, ы случае надобности.
+      - /tmp

</code_context>
<issue_to_address>
**nitpick (typo):** Исправьте небольшие опечатки в русскоязычных комментариях, чтобы конфигурация выглядела понятно и профессионально.

В этих комментариях есть несколько орфографических ошибок (например, `привелегии``привилегии`, `Папко``Папка`, `длоя``для`, `инфорамции``информации`). Пожалуйста, исправьте их, чтобы комментарии к конфигурации оставались понятными для других.

Suggested implementation:

```
    cap_drop: # Забирает все доступные привилегии у root пользователя.
      - ALL

```

```
    tmpfs: # Папка, доступная для записи информации, в случае необходимости.
      - /tmp

```

Если в этом файле есть другие русские комментарии с похожими опечатками, примените тот же подход:
1. Исправьте орфографию ("привелегии" → "привилегии", "Папко" → "Папка", "длоя" → "для", "инфорамции" → "информации", "ы случае" → "в случае").
2. Сохраните исходный смысл и тон каждого комментария, исправляя только орфографию и лёгкие грамматические ошибки.
</issue_to_address>

Sourcery бесплатно для open source — если вам нравятся наши ревью, пожалуйста, поделитесь ими ✨
Помогите мне стать полезнее! Пожалуйста, нажимайте 👍 или 👎 на каждом комментарии — я буду использовать этот фидбек, чтобы улучшать ревью.
Original comment in English

Hey - I've found 3 issues, and left some high level feedback:

  • Removing the FileHandler from logger.py switches logging to console-only; if persistent logs are still needed in production, consider routing logs to a volume-mounted file or a centralized logging system instead of dropping file logging entirely.
  • Marking api_db_net as internal: true and splitting networks into api_db_net / api_bot_net isolates services more strictly; double-check that any external tools (e.g., migrations, admin clients) that need to reach Postgres or the API are either attached to these networks or exposed appropriately, otherwise connectivity may be unintentionally broken.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Removing the `FileHandler` from `logger.py` switches logging to console-only; if persistent logs are still needed in production, consider routing logs to a volume-mounted file or a centralized logging system instead of dropping file logging entirely.
- Marking `api_db_net` as `internal: true` and splitting networks into `api_db_net` / `api_bot_net` isolates services more strictly; double-check that any external tools (e.g., migrations, admin clients) that need to reach Postgres or the API are either attached to these networks or exposed appropriately, otherwise connectivity may be unintentionally broken.

## Individual Comments

### Comment 1
<location path="docker-compose.yml" line_range="94" />
<code_context>
\ No newline at end of file
+    internal: true
+  
+  api_bot_net: 
+    driver: bridge
\ No newline at end of file
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Consider marking `api_bot_net` as `internal: true` if it’s only used for internal API–bot communication.

Since `api_db_net` is already internal for isolation, applying the same setting to `api_bot_net` (if it’s not meant to be externally reachable) would keep the configuration consistent and further limit unintended exposure.
</issue_to_address>

### Comment 2
<location path="src/logger.py" line_range="12-15" />
<code_context>
 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
</code_context>
<issue_to_address>
**suggestion:** Consider making file logging configurable instead of removing it entirely.

Removing `FileHandler` works well for containerized deployments using stdout, but it removes flexibility for environments that still benefit from file logs (e.g., bare metal or local dev). Consider guarding the `FileHandler` behind an environment variable or config flag so stdout remains the default, with an option to enable file logging when needed.

Suggested implementation:

```python
import os

console_handler = logging.StreamHandler()  # вывод логов в консоль
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

# Optional file logging, controlled via environment variable
if os.getenv("ENABLE_FILE_LOGGING", "false").lower() in ("1", "true", "yes"):
    log_file = os.getenv("LOG_FILE", "SteelTime.log")
    file_handler = logging.FileHandler(filename=log_file, encoding="utf-8")
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)

```

1. If `src/logger.py` already imports `os` at the top of the file, remove the duplicate `import os` from this block and keep a single import.
2. If `formatter` or `logger` are not defined earlier in `src/logger.py`, ensure they are created before this block (e.g. `logger = logging.getLogger(__name__)` and the corresponding formatter definition).
3. Update any deployment or documentation to mention:
   - `ENABLE_FILE_LOGGING` (set to `true`/`1`/`yes` to enable file logs),
   - `LOG_FILE` (optional custom log file path/name).
</issue_to_address>

### Comment 3
<location path="docker-compose.yml" line_range="70-72" />
<code_context>
+    read_only: true
+    security_opt:
+      - no-new-privileges:true
+    cap_drop: # Забирает все доступные привелегии у root пользователя.
+      - ALL
+    tmpfs: # Папко, доступная длоя записи инфорамции, ы случае надобности.
+      - /tmp

</code_context>
<issue_to_address>
**nitpick (typo):** Fix minor typos in Russian comments to keep configuration clear and professional.

There are several spelling errors in these comments (e.g. `привелегии``привилегии`, `Папко``Папка`, `длоя``для`, `инфорамции``информации`). Please correct them to keep the configuration comments clear for others.

Suggested implementation:

```
    cap_drop: # Забирает все доступные привилегии у root пользователя.
      - ALL

```

```
    tmpfs: # Папка, доступная для записи информации, в случае необходимости.
      - /tmp

```

If there are any other Russian comments in this file with similar typos, apply the same approach:
1. Correct spelling ("привелегии" → "привилегии", "Папко" → "Папка", "длоя" → "для", "инфорамции" → "информации", "ы случае" → "в случае").
2. Keep the original meaning and tone of each comment intact while fixing only orthography and minor grammar.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread docker-compose.yml
Comment thread src/logger.py
Comment thread docker-compose.yml Outdated
@coveralls
Copy link
Copy Markdown

coveralls commented May 29, 2026

Coverage Report for CI Build 26657510954

Coverage decreased (-0.2%) to 27.887%

Details

  • Coverage decreased (-0.2%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 2 coverage regressions across 1 file.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

2 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
presentation/api/v1/auth/tg_link.py 2 0.0%

Coverage Stats

Coverage Status
Relevant Lines: 1169
Covered Lines: 326
Line Coverage: 27.89%
Coverage Strength: 0.56 hits per line

💛 - Coveralls

@Fl1riX Fl1riX merged commit e578423 into main May 29, 2026
4 checks passed
@Fl1riX Fl1riX deleted the feature/docker-security-improvements branch May 29, 2026 19:27
@Fl1riX Fl1riX restored the feature/docker-security-improvements branch May 30, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants