Files
stun/dockerfile
T
2026-09-29 20:20:26 +03:00

71 lines
5.3 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ==============================================================================
# ЭТАП СБОРКИ (BUILDER)
# ==============================================================================
# Используем официальный образ Go на базе легковесного дистрибутива Alpine Linux.
# Именуем этот этап как "builder", чтобы позже забрать из него скомпилированный файл.
FROM golang:1.27-alpine AS builder
# Устанавливаем Git без сохранения кэша пакетов (уменьшает размер слоя).
# Он необходим Go для скачивания внешних зависимостей (например, golang.org/x/sys).
RUN apk add --no-cache git
# Объявляем переменные окружения для создания изолированного системного пользователя.
ENV USER=stunuser
ENV UID=10001
# Создаем безопасного пользователя внутри сборочного контейнера:
# --disabled-password: без пароля (вход по паролю заблокирован)
# --gecos "": отключает заполнение анкетных данных (имя, телефон и т.д.)
# --home "/nonexistent": без домашней папки
# --shell "/sbin/nologin": запрещает пользователю выполнять bash/sh команды в системе
# --no-create-home: принудительно запрещает создавать домашний каталог
RUN adduser --disabled-password --gecos "" --home "/nonexistent" --shell "/sbin/nologin" --no-create-home --uid "${UID}" "${USER}"
# Устанавливаем рабочую директорию, где будет происходить сборка кода
WORKDIR /app
# Шаг оптимизации кэша Docker: сначала копируем только файлы зависимостей go.mod и go.sum.
# Звездочка * защищает от ошибки сборки, если файла go.sum еще физически не существует.
COPY go.mod* go.sum* ./
# Если файл go.mod существует, скачиваем все внешние библиотеки и проверяем их хэш-суммы.
# Благодаря этому шагу зависимости будут кэшироваться и не будут скачиваться заново при изменении кода.
RUN if [ -f go.mod ]; then go mod download && go mod verify; fi
# Копируем весь оставшийся исходный код проекта (main.go и другие файлы) в рабочую директорию
COPY . .
# Компилируем высокопроизводительный бинарник:
# CGO_ENABLED=0: отключаем зависимости от C-библиотек (делает бинарник полностью автономным)
# GOOS=linux: жестко указываем целевую операционную систему Linux
# -ldflags="-s -w": отключает генерацию отладочной информации (символов) и таблиц DWARF.
# Это уменьшает размер итогового файла почти в 2 раза без потери скорости.
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/stun_server .
# ==============================================================================
# ФИНАЛЬНЫЙ ЭТАП (PRODUCTION)
# ==============================================================================
# FROM scratch — это пустой слой. В нем нет Linux, нет bash, нет пакетных менеджеров.
# Это гарантирует минимальный размер контейнера и максимальную безопасность (его невозможно взломать).
FROM scratch
# Переносим файлы пользователей и групп, созданные на этапе сборки.
# Без этого контейнер scratch не узнает, кто такой "stunuser".
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
# Копируем единственный скомпилированный исполняемый файл STUN-сервера из этапа builder
COPY --from=builder /app/stun_server /stun_server
# Переключаем контекст выполнения. Сервер будет работать от имени stunuser, а не root.
# Если в коде сервера найдут уязвимость, злоумышленник все равно не получит права root на хосте.
USER stunuser:stunuser
# Документируем, что контейнер слушает порт 3478 по протоколу UDP
EXPOSE 3478/udp
# Точка входа: при старте контейнера автоматически запускается наш STUN-сервер.
# Использование квадратных скобок [строгий JSON] запускает процесс напрямую (PID 1) без лишней оболочки sh.
ENTRYPOINT ["/stun_server"]