# syntax=docker/dockerfile:1.7 # # awg-dash — единый образ: AmneziaWG gateway + policy routing + REST API + Web UI. # Задача: #18 (эпик #15). ADR: docs/adr/002-single-image-modular-monolith.md # # ВАЖНО: AMNEZIAWG_GO_REF / AMNEZIAWG_TOOLS_REF по умолчанию указывают на master # и должны быть запинены на проверенный тег/коммит перед релизом (см. #45). # Базовые образы и зависимости подняты под гейт image-scan (issue #61): # golang:1.26-alpine — закрывает CVE Go stdlib 1.25.14 (CRITICAL CVE-2026-56857 + HIGH) # golang.org/x/crypto v0.58.0 + golang.org/x/net v0.62.0 — закрывают CVE в ssh/* и http2/idna # alpine:3.23 — закрывает HIGH в пакетах alpine 3.21 ARG GO_IMAGE=golang:1.26-alpine ARG X_CRYPTO_VERSION=v0.58.0 ARG X_NET_VERSION=v0.62.0 # --- stage 1: сборка awg-утилит (Go) ----------------------------------------- FROM ${GO_IMAGE} AS go-build ARG AMNEZIAWG_GO_REPO=https://github.com/amnezia-vpn/amneziawg-go.git ARG AMNEZIAWG_GO_REF=master ARG AMNEZIAWG_TOOLS_REPO=https://github.com/amnezia-vpn/amneziawg-tools.git ARG AMNEZIAWG_TOOLS_REF=master ARG X_CRYPTO_VERSION ARG X_NET_VERSION RUN apk add --no-cache git make gcc musl-dev linux-headers WORKDIR /src RUN git clone --depth 1 --branch "${AMNEZIAWG_GO_REF}" "${AMNEZIAWG_GO_REPO}" amneziawg-go \ && cd amneziawg-go \ && go get "golang.org/x/crypto@${X_CRYPTO_VERSION}" "golang.org/x/net@${X_NET_VERSION}" \ && go mod tidy \ && go list -m golang.org/x/crypto golang.org/x/net \ && make \ && cp amneziawg-go /usr/local/bin/amneziawg-go RUN git clone --depth 1 --branch "${AMNEZIAWG_TOOLS_REF}" "${AMNEZIAWG_TOOLS_REPO}" amneziawg-tools \ && cd amneziawg-tools/src && make \ && cp wg /usr/local/bin/awg \ && if [ -f wg-quick ]; then cp wg-quick /usr/local/bin/awg-quick; fi # --- stage 2: runtime ------------------------------------------------------- FROM alpine:3.23 AS runtime # Пакеты базы обновляем на момент сборки: trivy --ignore-unfixed учитывает только исправимые CVE. RUN apk upgrade --no-cache LABEL org.opencontainers.image.title="awg-dash" \ org.opencontainers.image.description="AmneziaWG gateway with intelligent routing: REST API + Web UI + split-tunnel" \ org.opencontainers.image.source="http://192.168.1.111:3000/embeddevio/awg-dash" # Сетевые утилиты: iptables/ip6tables, ipset, iproute2 (policy routing), dnsmasq (ADR-005), # curl (HEALTHCHECK), tini (PID 1), su-exec (запуск API под непривилегированным пользователем). RUN apk add --no-cache \ bash curl iproute2 ipset iptables ip6tables dnsmasq \ python3 py3-pip tini su-exec \ && addgroup -S awg \ && adduser -S -G awg -h /app awg ENV PATH=/opt/venv/bin:$PATH \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH=/app/backend \ AWG_CONFIG_DIR=/config \ AWG_DATA_DIR=/data \ AWG_RUN_DIR=/run/awg \ AWG_API_HOST=0.0.0.0 \ AWG_API_PORT=8080 WORKDIR /app COPY requirements.txt /app/requirements.txt RUN apk add --no-cache --virtual .build-deps gcc musl-dev python3-dev libffi-dev \ && python3 -m venv /opt/venv \ && /opt/venv/bin/pip install --no-cache-dir --upgrade pip \ && /opt/venv/bin/pip install --no-cache-dir -r /app/requirements.txt \ && apk del .build-deps COPY backend/ /app/backend/ COPY --from=go-build /usr/local/bin/awg /usr/local/bin/awg COPY --from=go-build /usr/local/bin/amneziawg-go /usr/local/bin/amneziawg-go COPY deploy/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh \ && mkdir -p /config /data /run/awg \ && chown -R awg:awg /app /config /data /run/awg VOLUME ["/config", "/data"] EXPOSE 8080 # healthcheck ходит в /api/v1/health (задача #31). До реализации API контейнер # будет помечаться как unhealthy — это ожидаемое состояние до #31. HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD curl -fsS "http://127.0.0.1:${AWG_API_PORT}/api/v1/health" >/dev/null || exit 1 ENTRYPOINT ["/sbin/tini", "--", "/entrypoint.sh"]