# Target machine with Docker pre-installed.
# Used for app-zone machines that run Docker Compose workloads (e.g. authentik).
# Docker itself is baked in; application images are pulled at deploy time by each module.

FROM ubuntu:22.04@sha256:b8b6ee6aa931ecd9d0d952abc34dc0e5f7c6a30c6bb71b079fe399fde0329c02

ENV DEBIAN_FRONTEND=noninteractive

# Make apt resilient to flaky upstream (no apt-cacher-ng masking transient errors)
COPY config/apt/99retries.conf /etc/apt/apt.conf.d/99retries.conf

RUN apt-get update && apt-get install -y \
    systemd \
    systemd-sysv \
    openssh-server \
    iproute2 \
    iputils-ping \
    net-tools \
    dnsutils \
    procps \
    python3 \
    python3-apt \
    sqlite3 \
    jq \
    sudo \
    curl \
    ca-certificates \
    gnupg \
    lsb-release \
    && rm -rf /var/lib/apt/lists/*

# Trust the E2E forward proxy CA (for transparent HTTPS interception)
COPY config/proxy/squid-ca.crt /usr/local/share/ca-certificates/e2e-proxy-ca.crt
# Trust Pebble's test CA (so Caddy/ACME clients trust the simulated Let's Encrypt)
COPY config/pebble/pebble-ca.crt /usr/local/share/ca-certificates/pebble-ca.crt
RUN update-ca-certificates

# Node/npm ignore the OS trust store; point them at the bundle that now includes
# the e2e CAs (mirrors Dockerfile.management), in both the image env and
# /etc/environment so Ansible's SSH-invoked npm picks it up via pam_env.
# (openspec/specs/event-driven-hook-subscriptions/spec.md L6.)
ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
RUN echo 'NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt' >> /etc/environment

RUN mkdir -p /run/sshd && \
    sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config && \
    sed -i 's/#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config

# Enable SSH service
RUN systemctl enable ssh

# E2E network setup service
COPY config/routing/target-setup.sh /usr/local/bin/target-setup.sh
RUN chmod +x /usr/local/bin/target-setup.sh

COPY config/routing/target-setup.service /etc/systemd/system/target-setup.service
RUN systemctl enable target-setup

# Clean up unnecessary systemd services
RUN (cd /lib/systemd/system/sysinit.target.wants/ && \
    ls | grep -v systemd-tmpfiles-setup | xargs rm -f 2>/dev/null); \
    rm -f /lib/systemd/system/multi-user.target.wants/*; \
    rm -f /etc/systemd/system/*.wants/*; \
    rm -f /lib/systemd/system/local-fs.target.wants/*; \
    rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
    rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
    rm -f /lib/systemd/system/basic.target.wants/*; \
    true

# Re-enable the services we actually need
RUN systemctl enable ssh target-setup

# --- Docker pre-installation ---
# Install Docker (same steps as the Ansible role, but at image build time)
RUN install -m 0755 -d /etc/apt/keyrings && \
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc && \
    chmod a+r /etc/apt/keyrings/docker.asc && \
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list && \
    apt-get update && \
    apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin && \
    rm -rf /var/lib/apt/lists/*

# Configure Docker for nested operation (vfs storage driver)
# Must match Ansible's exact content to avoid a Docker restart that wipes cached images
# Ansible copy module writes: '{"storage-driver": "vfs"}\n'
RUN mkdir -p /etc/docker && \
    echo '{"storage-driver": "vfs"}' > /etc/docker/daemon.json

RUN systemctl enable docker

# Pre-load cached Docker images on startup (e2e acceleration)
# /docker-image-cache is bind-mounted from the host by the compose generator.
# The service is a no-op if the directory is absent or empty.
COPY config/routing/docker-image-preload.sh /usr/local/bin/docker-image-preload.sh
RUN chmod +x /usr/local/bin/docker-image-preload.sh
COPY config/routing/docker-image-preload.service /etc/systemd/system/docker-image-preload.service
RUN systemctl enable docker-image-preload


# Bake complete apt indexes into the image. target-setup used to run
# `apt-get update` at boot for this, which put a third party's latency inside
# the 60s readiness budget (#560). Doing it here gives Ansible the same
# guarantee — populated lists on first connect — off the readiness path.
RUN apt-get update

STOPSIGNAL SIGRTMIN+3
ENTRYPOINT ["/sbin/init"]
