Два образи замість пʼяти: серверні команди їдуть з одного модуля й мусять ходити в схему БД однією версією, а зонд лишається окремо — у чужій мережі йому не місце з DSN і ключами шифрування. Стек піднімає БД, кеш, міграції, API, колектор і Caddy з автоматичним TLS. Міграції окремою службою, бо API піднімається в кількох примірниках і гонка за схему нікому не потрібна. deploy/README.md описує бекап як три речі: дамп, DEK і JWT-ключ. Без DEK дамп не відновлюється — у БД лише шифротекст. Дорогою виправлено .gitignore: голі "netpulse-agent" і "netpulse-server" ігнорували ще й каталоги cmd/ з кодом команд. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
68 lines
2.8 KiB
Text
68 lines
2.8 KiB
Text
# syntax=docker/dockerfile:1.7
|
||
#
|
||
# Образ зонда NetPulse.
|
||
#
|
||
# Окремий образ, а не спільний із сервером: зонд їде до клієнта в чужу
|
||
# мережу, і все, чого там бути не має — DSN, ключі шифрування, команди
|
||
# заведення користувачів — не повинно потрапити в образ навіть як
|
||
# невикористаний файл.
|
||
#
|
||
# Контекст збірки — корінь репозиторію (replace на ../gen/go).
|
||
|
||
FROM golang:1.25-alpine AS build
|
||
WORKDIR /src
|
||
|
||
RUN apk add --no-cache git
|
||
|
||
COPY gen/go/go.mod gen/go/go.sum gen/go/
|
||
COPY agent/go.mod agent/go.sum agent/
|
||
WORKDIR /src/agent
|
||
RUN --mount=type=cache,target=/go/pkg/mod go mod download
|
||
|
||
WORKDIR /src
|
||
COPY gen/ gen/
|
||
COPY agent/ agent/
|
||
|
||
ARG VERSION=dev
|
||
ARG COMMIT=none
|
||
|
||
WORKDIR /src/agent
|
||
RUN --mount=type=cache,target=/go/pkg/mod \
|
||
--mount=type=cache,target=/root/.cache/go-build \
|
||
CGO_ENABLED=0 go build -trimpath \
|
||
-ldflags "-s -w -X main.version=${VERSION} -X main.commit=${COMMIT}" \
|
||
-o /out/netpulse-agent ./cmd/netpulse-agent
|
||
|
||
FROM alpine:3.20
|
||
|
||
RUN apk add --no-cache ca-certificates tzdata \
|
||
&& adduser -D -u 10001 netpulse
|
||
|
||
COPY --from=build /out/netpulse-agent /usr/local/bin/netpulse-agent
|
||
|
||
# Право на сирі сокети замість запуску від root: ICMP інакше не
|
||
# надіслати, але решті зонда root не потрібен.
|
||
#
|
||
# Docker при цьому має віддати контейнеру CAP_NET_RAW (він є в наборі
|
||
# за замовчуванням) — див. cap_add у compose для середовищ, де набір
|
||
# урізали.
|
||
RUN apk add --no-cache libcap \
|
||
&& setcap cap_net_raw+ep /usr/local/bin/netpulse-agent \
|
||
&& apk del libcap
|
||
|
||
# Каталог створюємо в образі й віддаємо його зонду.
|
||
#
|
||
# Том, оголошений на неіснуючому шляху, docker створює власністю root, і
|
||
# зонд під непривілейованим користувачем не може записати посвідчення —
|
||
# реєстрація проходить, а після перезапуску зонд знову просить
|
||
# запрошення, ніби нічого не було.
|
||
RUN mkdir -p /var/lib/netpulse && chown netpulse:netpulse /var/lib/netpulse
|
||
|
||
USER netpulse
|
||
|
||
# Посвідчення зонда переживає перезапуск контейнера: без тому кожен
|
||
# старт вимагав би нового запрошення з інтерфейсу.
|
||
VOLUME ["/var/lib/netpulse"]
|
||
ENV NETPULSE_IDENTITY=/var/lib/netpulse/agent.json
|
||
|
||
ENTRYPOINT ["netpulse-agent"]
|