# syntax=docker/dockerfile:1.7
# -------------------------------------------------------------------------------------
# Samba 4.22 Active Directory Domain Controller on Debian 13 (trixie)
#
# One `samba` process serves the whole DC role:
#   DNS 53          LDAP 389 / LDAPS 636      Global Catalog 3268 / 3269
#   Kerberos 88     kpasswd 464               RPC epmapper 135     SMB 445 (SYSVOL/NETLOGON)
#   MS-SNTP 123  (Windows clients sync time from the DC after domain join)
#
# Build:   docker build -t local/samba-ad-dc:4.22-debian13 -f image/Dockerfile .
# -------------------------------------------------------------------------------------
FROM debian:trixie-slim

# Pin every Samba-built package to the SAME version string (they carry exact-version
# depends on each other, so pinning only `samba` produces unsatisfiable deps once the
# archive carries two point releases). Empty => whatever trixie+security currently offer.
ARG SAMBA_VERSION=2:4.22.11+dfsg-0+deb13u1

LABEL org.opencontainers.image.title="samba-ad-dc" \
      org.opencontainers.image.description="Samba AD Domain Controller (Windows 11 join compatible) on Debian 13" \
      org.opencontainers.image.source="https://github.com/local/samba-ad-dc" \
      org.opencontainers.image.licenses="GPL-3.0-or-later"

ENV DEBIAN_FRONTEND=noninteractive

# Package postinsts must never try to start services during an image build.
RUN printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d && chmod 0755 /usr/sbin/policy-rc.d

RUN set -eux; \
    pin=""; \
    if [ -n "${SAMBA_VERSION}" ]; then pin="=${SAMBA_VERSION}"; fi; \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        "samba${pin}" \
        "samba-ad-dc${pin}" \
        "samba-common${pin}" \
        "samba-common-bin${pin}" \
        "samba-dsdb-modules${pin}" \
        "samba-ad-provision${pin}" \
        "python3-samba${pin}" \
        "winbind${pin}" \
        python3-setproctitle \
        krb5-user \
        libsasl2-modules-gssapi-mit \
        ldap-utils \
        smbclient \
        bind9-dnsutils \
        python3-dnspython \
        ca-certificates \
        openssl \
        iproute2 \
        procps \
        tzdata; \
    rm -f /usr/sbin/policy-rc.d; \
    rm -rf /var/lib/apt/lists/*; \
    # The stock smb.conf/krb5.conf shipped by the packages must NOT exist:
    # the entrypoint uses their absence to detect a virgin data volume, and named
    # volumes would otherwise be seeded with the stock (non-AD) config.
    rm -f /etc/samba/smb.conf /etc/krb5.conf; \
    mkdir -p /etc/samba /var/backups/ad-dc /run/ad-secrets; \
    # Leave the AD state dir EMPTY. Docker seeds named volumes from the image's content,
    # and `samba-tool domain backup restore` refuses a non-empty target dir. Provisioning
    # creates these directories itself.
    rm -rf /var/lib/samba; \
    mkdir -p /var/lib/samba; \
    # sanity: this image is useless without the AD DC bits
    test -x /usr/sbin/samba; \
    /usr/bin/samba-tool --help >/dev/null; \
    # the AD schema lives in a separate Debian package (samba-ad-provision) - fail the
    # build here rather than at first-run provisioning
    ls /usr/share/samba/setup/ad-schema/AD_DS_Attributes_Windows_Server_v1903.ldf >/dev/null; \
    # ldap-client GSSAPI and smbclient are used by the verification scripts
    ls /usr/lib/*/sasl2/libgssapiv2.so >/dev/null; \
    command -v smbclient >/dev/null; \
    command -v kvno >/dev/null; \
    samba -V

COPY image/ad-entrypoint.sh /usr/local/bin/ad-entrypoint
COPY image/ad-healthcheck.sh /usr/local/bin/ad-healthcheck
COPY image/ad-dnsupdate.sh /usr/local/bin/ad-dnsupdate
RUN chmod 0755 /usr/local/bin/ad-entrypoint /usr/local/bin/ad-healthcheck /usr/local/bin/ad-dnsupdate

# Documentation only (real ports come from the network mode you choose).
EXPOSE 53/tcp 53/udp 88/tcp 88/udp 123/udp 135/tcp 137/udp 138/udp 139/tcp \
       389/tcp 445/tcp 464/tcp 464/udp 636/tcp 3268/tcp 3269/tcp

# start_period is generous: first-run provisioning takes ~30-90s.
HEALTHCHECK --interval=30s --timeout=20s --start-period=120s --retries=4 \
    CMD ["/usr/local/bin/ad-healthcheck"]

ENTRYPOINT ["/usr/local/bin/ad-entrypoint"]
