# Пісочниця NetPulse — накладка на docker-compose.yml. # # Це НЕ окремий стек і не спрощена копія. Це той самий docker-compose.yml, # накритий рівно тими правками, без яких повна установка на робочій # машині або конфліктує з наявною, або з'їдає машину. Усе інше — # порядок служб, міграції, ролі під RLS, зонд — лишається тим самим, бо # інакше пісочниця перевіряла б не установку, а власну вигадку. # # Запускати руками не треба: `./netpulse sandbox` підставляє і цей файл, # і ім'я проєкту, і окремий .env.sandbox. # # docker compose -p netpulse-sandbox \ # -f docker-compose.yml -f deploy/docker-compose.sandbox.yml \ # --env-file .env.sandbox <команда> # # --------------------------------------------------------------------- # ЩО САМЕ ТУТ МІНЯЄТЬСЯ І ЧОМУ # # 1. Порти. Базовий файл публікує 80, 443, 9443 і 162/udp числами. Друга # інсталяція на тій самій машині впирається в них першою ж командою # `up`, і виглядає це як «пісочниця поклала бойову систему» — рівно та # шкода, від якої вона мала захистити. Тому проксі публікується на # зсунуті порти І ЛИШЕ на 127.0.0.1: пісочниця не має бути видною з # мережі навіть випадково, у ній стоїть відомий пароль і самопідписаний # сертифікат. # # 2. Трапи. Зонд у пісочниці піднімається (без нього не перевірити # реєстрацію в колекторі — а це єдиний шлях, якого HTTP-перевірки не # бачать зовсім), але 162/udp назовні не виставляє взагалі. Порт без # автентифікації, відкритий заради перевірки, — це не перевірка. # # 3. Стелі пам'яті. Без них пісочниця конкурує з рештою машини на рівних # і виграє: Postgres резервує буфери одразу, а ядро вбиває не того, # хто попросив забагато, а того, хто підвернувся. Стеля перетворює # «машина стала» на «контейнер пісочниці впав», і друге видно одразу. # Цифри взяті з запасом: стеля тут — запобіжник, а не режим економії, # і впертись у неї на порожній базі не має ніщо. Якщо все ж уперлось, # `./netpulse sandbox status` це називає прямо, щоб причину не шукали # в коді. # # 4. restart: "no". У бойовому стеку `unless-stopped` правильний: служба # має пережити перезавантаження хоста. Для пісочниці це протилежність # потрібного — забута пісочниця не має воскресати після ребуту й # мовчки тримати порт і том. Побічний наслідок корисний: контейнер, # який падає в циклі, тут одразу видно як мертвий, а не як «щось # довго стартує». # # --------------------------------------------------------------------- # ЧОМУ ПОТРІБЕН COMPOSE 2.24.4 # # Списки `ports` при накладанні файлів compose ДОДАЄ, а не замінює: без # явного тега `!override` базові «80:80» лишилися б на місці поруч зі # зсунутими, і пісочниця все одно вчепилась би в порт бойового проксі. # Тег `!override` з'явився у docker compose 2.24.4. # # Ця вимога зникає одним рядком у docker-compose.yml — якщо базові порти # зробити змінними зі значенням за замовчуванням: # # ports: # - "${NETPULSE_BIND:-0.0.0.0}:${NETPULSE_PORT_HTTP:-80}:80" # - "${NETPULSE_BIND:-0.0.0.0}:${NETPULSE_PORT_HTTPS:-443}:443" # - "${NETPULSE_BIND:-0.0.0.0}:${NETPULSE_PORT_GRPC:-9443}:9443" # # Тоді пісочниці вистачить .env.sandbox, накладка портів стає не # потрібна, а мінімальна версія compose лишається 2.0 — як у решті # установника. Поки цього немає, `./netpulse sandbox` перевіряє версію і # відмовляється працювати на старішій, а не мовчки бере не ті порти. # Ім'я проєкту продубльовано тут навмисно. `./netpulse sandbox` і так # передає -p, але якщо цей файл колись запустять руками без -p, ізоляція # має лишитись: інше ім'я проєкту — це інші контейнери, інша мережа й, # найголовніше, ІНШІ ТОМИ. Без нього `down -v` у пісочниці знищив би # базу бойової інсталяції. name: netpulse-sandbox services: db: mem_limit: 768m restart: "no" cache: mem_limit: 320m restart: "no" migrate: mem_limit: 256m cli: mem_limit: 256m api: mem_limit: 384m restart: "no" collector: mem_limit: 256m restart: "no" proxy: mem_limit: 128m restart: "no" # Порти пише установник у .env.sandbox, попередньо переконавшись, що # вони вільні. Значення за замовчуванням тут — щоб файл не був # непрацездатним сам по собі, а не щоб на них покладатись. ports: !override - "127.0.0.1:${NETPULSE_SB_HTTP:-18080}:80" - "127.0.0.1:${NETPULSE_SB_HTTPS:-18081}:443" - "127.0.0.1:${NETPULSE_SB_GRPC:-18082}:9443" agent: mem_limit: 192m restart: "no" # Порожньо, а не інший порт: 162/udp не має автентифікації, і # відкривати його заради перевірки означало б купити перевірку ціною # дірки. Усе, що перевіряє зонд — обмін запрошення на токен, gRPC до # колектора, поява рядка в core.agents, — відбувається вихідними # з'єднаннями й публікації порту не потребує. ports: !override []