From 030e49edb9a87bfcc4ef81787a9e2eb60faf4cc3 Mon Sep 17 00:00:00 2001 From: "e.kabarukhin" Date: Thu, 12 Feb 2026 04:58:41 +0300 Subject: [PATCH] Good luck with the assignment! --- Dockerfile | 17 ++++++++ README.md | 60 +++++++++++++++++++++++++++ docker-compose.yml | 6 +++ src/server.pas | 100 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 src/server.pas diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5a9a12e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM freepascal/fpc:3.2.2-focal-full AS build +WORKDIR /app +COPY src/server.pas . +RUN fpc -O2 -Xs server.pas + +FROM debian:bookworm-slim +RUN apt-get update && apt-get install -y --no-install-recommends libcap2-bin ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY --from=build /app/server /app/server + +RUN setcap 'cap_net_bind_service=+ep' /app/server + +USER 65534:65534 +EXPOSE 80 +CMD ["/app/server"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..dd7a47a --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# PROD 2026 - Backend + + +Используйте данный репозиторий для работы над задачей. + +> [!TIP] +> Задание можно найти в отдельном репозитории по ссылке – https://gitlab.prodcontest.com/2026-final-tasks/backend + + +## Что фиксируется как решение + +Проверяется состояние последнего коммита в ветке `main` на момент дедлайна. + + +## Технические требования + +Технические ограничения окружения где будет выполняться сборка и запуск решения + +| Параметр | Лимит | +|----------|-------| +| Время старта | < 180 секунд до готовности /ready | +| Память | < 8 GB | +| CPU | 4 ядра | +| Размер Docker-образа | < 4 GB | +| Сеть | Нет доступа в интернет при запуске и проверке | + +Технические требования к решению: + +* Приложение должно запускаться командой `docker compose up -d` в корне репозитория. +* Приложение слушает только порт `80`, все сервисы общаются между собой через docker-сеть (локально). + +## Академическая честность и культура общения + +Мы призываем всех участников соблюдать принципы академической честности и культуры общения, подходить к соревнованиям открыто и добросовестно.
+Цель олимпиады — не только продемонстрировать свои знания и навыки, но и развиваться как надёжные и ответственные специалисты в будущем. + +### Академическая честность и проверка на заимствования + +Мы проверяем самостоятельность решений: + +- внутренняя проверка организаторов; +- внешняя проверка через Codechecker (продукт компании «Антиплагиат»). + +Код из открытых источников использовать можно, но важно указать источник — в комментарии рядом с фрагментом или в `README`. + +Если вы используете LLM/нейросети (например, чтобы сгенерировать фрагменты кода, тесты или документацию), пожалуйста, помечайте это — где уместно, в комментарии рядом с фрагментом или отдельной заметкой в `README`.
+Важно: **ответственность за весь код в репозитории несёте вы**, включая сгенерированные фрагменты — вы должны понимать, что именно добавляете, уметь объяснить решение и проверять результат (корректность, безопасность, крайние случаи). + +Это позволит легко проверить и подтвердить самостоятельность вашей работы и снять возможные вопросы при проверке. + +### Культура общения и этика участия + +Олимпиада по промышленному программированию — это про профессиональный подход. Поэтому в репозитории (сообщения коммитов, названия веток, комментарии к коду и обсуждения) мы ожидаем уважительный и деловой тон. + +Мы не приемлем ненормативную лексику, оскорбления и токсичное поведение. + +## Меры при нарушениях + +Если мы фиксируем нарушение академической честности или культуры общения, мы можем аннулировать результат работы (включая дисквалификацию в рамках олимпиады).
+Решение принимается организаторами по совокупности признаков и результатов проверок. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..33a674f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +services: + api: + platform: linux/amd64 + build: . + ports: + - "80:80" diff --git a/src/server.pas b/src/server.pas new file mode 100644 index 0000000..4a86bd3 --- /dev/null +++ b/src/server.pas @@ -0,0 +1,100 @@ +program HealthServer; + +{$mode objfpc}{$H+} + +uses + cthreads, + fphttpserver, httpdefs, sysutils; + +const + LOTTY = +'╔═════════════════════════════════════════════════════════════════════╗' + LineEnding + +'║ ║' + LineEnding + +'║ ⠀⠀⠀⠀⢀⡀⣄⢀⡄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣴⡶⠶⠶⠖⠒⠒⠒⠲⠶⠶⢶⣤⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠰⣮⡿⠛⠻⠷⣯⣶⣀⡀⠀⠀⠀⠀⣀⣴⠾⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠶⣤⡀⠀⠀⠀⠀⠀⣀⣤⣾⣼⣿⣷⣿⣠⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⢛⣿⡄⠀⠀⠀⠀⠙⢿⣶⣂⣀⣤⡾⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠷⣄⠀⣀⣶⣿⠟⠋⠁⠀⠀⢹⣿⠆⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠾⣻⣦⡀⠀⠀⠀⠀⠙⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⠋⠁⠀⠀⠀⢀⣴⢿⡍⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠈⠸⢻⡷⣦⣄⡀⣰⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣦⣠⣤⣴⣾⢿⠝⠃⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⣀⢀⠀⡀⠀⠈⠋⠿⢹⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⠃⠋⠉⠀⢀⠀⡀⣀⠀⠀⠀ ║' + LineEnding + +'║ ⣴⣮⣷⣿⣾⣾⣧⣿⣼⣶⣆⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣴⣄⣷⣿⡾⠷⠿⠾⣾⣧⡄ ║' + LineEnding + +'║ ⠶⢿⡋⠀⠀⠀⠀⠀⠀⠉⠉⢻⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡟⠋⠁⠀⠀⠀⠀⠀⢀⣿⠶ ║' + LineEnding + +'║ ⠉⠽⣷⣦⣄⣀⣀⠀⠀⠀⣀⣸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⢀⣀⣤⣴⣿⡏⠁ ║' + LineEnding + +'║ ⠀⠀⠁⠋⠻⠹⠿⠟⡿⠻⠻⠟⣿⠀⠀⠀⠀⠀⣴⣾⣿⣶⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣷⣦⠀⠀⠀⠀⣾⢻⠟⡿⠻⠛⠏⠛⠈⠁⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣄⣤⣰⣿⣆⠀⠀⠀⠀⣿⣿⣿⣿⡇⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⢸⣿⣿⣿⣿⠃⠀⠀⣰⣿⣖⣴⢀⡀⡀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⣀⢰⣼⣷⠿⠛⠋⠉⠹⣦⡀⠀⠀⠈⠛⠛⠋⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠛⠉⠀⠀⠀⠀⠀⠉⠛⠛⠁⠀⠀⣴⠏⠉⠙⠛⠿⢾⣧⣶⣠⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⣰⣾⠟⠉⠀⠀⠀⠀⠀⣠⣾⡷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⢞⣷⣤⡀⠀⠀⠀⠀⠈⠙⢿⣄⡀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠈⣽⣯⡀⠀⠀⢀⣠⣴⣿⡝⠊⠀⠈⠙⠶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⠶⠋⠁⠀⠑⠋⣿⢶⣤⣤⣀⣀⣠⣼⢯⡅⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠐⠋⠿⢻⠿⡏⠷⠙⠁⠀⠀⠀⠀⠀⠀⠀⠉⠛⠳⠶⣤⣤⣄⣀⣀⣀⣀⣀⣀⣀⣠⣤⣤⠶⠚⠋⠉⠀⠀⠀⠀⠀⠀⠀⠈⠐⠃⠘⠋⠗⠙⠁⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡿⠁⠈⠉⠉⠉⠉⠉⠉⠉⠁⠀⢹⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠃⠉⠉⠙⣆⠀⠀⠀⢰⠋⠉⠉⠀⢿⡀⠀⠀⠀╭─────────────────────╮ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡏⠀⠐⠓⠒⠃⠀⠀⠀⠈⠓⠚⠂⠀⠸⣇⠀⠀⠀│ LOTTY says: │ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀│ "Теперь вы PROD!" │ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀╰─────────────────────╯ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡄⠀⣠⠚⠙⡆⠀⠀⠀⢰⠋⠑⣆⠀⢰⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣄⠀⠀⠰⠁⠀⠀⠀⠈⠃⠀⢀⣰⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢶⣤⣤⣤⣤⣤⣤⣤⡶⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢻⣇⠀⠀⠀⢸⡏⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⣿⠀⠀⢀⡿⢰⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡄⣿⠀⠀⣼⢇⡾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⣿⠀⢰⣿⡞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣤⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ║' + LineEnding + +'║ ║' + LineEnding + +'║ ██████╗ ██████╗ ██████╗ ██████╗ ║' + LineEnding + +'║ ██╔══██╗██╔══██╗██╔═══██╗██╔══██╗ ║' + LineEnding + +'║ ██████╔╝██████╔╝██║ ██║██║ ██║ ║' + LineEnding + +'║ ██╔═══╝ ██╔══██╗██║ ██║██║ ██║ ║' + LineEnding + +'║ ██║ ██║ ██║╚██████╔╝██████╔╝ ║' + LineEnding + +'║ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ║' + LineEnding + +'║ ║' + LineEnding + +'║ ║' + LineEnding + +'║ Status: HEALTHY ║' + LineEnding + +'║ ║' + LineEnding + +'║ ║' + LineEnding + +'║ ║' + LineEnding + +'║ ║' + LineEnding + +'║ © Powered by Watlon ║' + LineEnding + +'╚═════════════════════════════════════════════════════════════════════╝' + LineEnding; + +type + THandler = class + procedure HandleRequest(Sender: TObject; var Req: TFPHTTPConnectionRequest; + var Res: TFPHTTPConnectionResponse); + end; + +procedure THandler.HandleRequest(Sender: TObject; var Req: TFPHTTPConnectionRequest; + var Res: TFPHTTPConnectionResponse); +begin + Res.ContentType := 'text/plain; charset=utf-8'; + + if (Req.URI = '/ping') or (Req.URI = '/ready') or (Req.URI = '/health') then + begin + Res.Code := 200; + Res.Content := LOTTY; + end + else + begin + Res.Code := 404; + Res.Content := 'not found' + LineEnding; + end; +end; + +var + Server: TFPHTTPServer; + Handler: THandler; + +begin + Handler := THandler.Create; + Server := TFPHTTPServer.Create(nil); + try + Server.Port := 80; + Server.Threaded := True; + Server.OnRequest := @Handler.HandleRequest; + Server.Active := True; + + WriteLn('Listening on :80'); + while True do Sleep(3600 * 1000); + finally + Server.Free; + Handler.Free; + end; +end.