ARG PYTHON_VERSION ARG SEMAPHORE_VERSION ARG OPENTOFU_VERSION ARG SPECTRE_VERSION # Python Wheel Build container # ================================= FROM docker.io/library/python:${PYTHON_VERSION} AS build_wheel RUN python -m pip install pip --upgrade RUN curl -sSL -o /install-poetry.py https://install.python-poetry.org RUN python /install-poetry.py --yes ADD . /build WORKDIR /build RUN /root/.local/bin/poetry self add poetry-plugin-export RUN /root/.local/bin/poetry export \ --format requirements.txt \ --output /build/requirements.txt \ --without-hashes RUN python -m pip wheel \ --wheel-dir /build/wheels \ --requirement /build/requirements.txt \ --disable-pip-version-check \ --no-cache-dir # Spectre Build container # ================================== FROM docker.io/library/debian:12 as build_spectre ARG SPECTRE_VERSION RUN apt-get update --yes RUN apt-get install --yes \ git \ build-essential \ libsodium-dev \ libjson-c-dev \ libxml2-dev RUN mkdir --parents /build RUN git -C /build clone https://gitlab.com/spectre.app/cli.git spectre WORKDIR /build/spectre RUN git checkout ${SPECTRE_VERSION} RUN git submodule update --init RUN bash ./build # Runtime container # ================================== # The semaphore project's official container is built on # alpine linux which uses musl instead of glibc. What does # that mean? I don't really know and I don't really care, but # the effect is that we can't build spectre/mpw on alpine # which makes them mutually exclusive. Since we need both, # we need a container to run both. And it's easier to repackage # semaphore under not-alpine than it is to get spectre to build # under alpine. So here we are. # FROM docker.io/library/python:${PYTHON_VERSION}-slim AS final ARG SEMAPHORE_VERSION ARG OPENTOFU_VERSION COPY --from=build_spectre /build/spectre/spectre /usr/local/bin/spectre COPY --from=build_wheel /build/wheels /tmp/wheels ADD --chmod=755 https://raw.githubusercontent.com/ansible-semaphore/semaphore/v${SEMAPHORE_VERSION}/deployment/docker/common/semaphore-wrapper /usr/local/bin/semaphore-wrapper # Symlink **special** binaries for backwards compatibility RUN ln -s /usr/local/bin/spectre /usr/local/bin/mpw RUN ln -s /usr/bin/tofu /usr/local/bin/terraform RUN apt-get update --yes RUN apt-get install --yes --no-install-recommends \ openssh-client \ apt-transport-https \ ca-certificates \ curl \ gnupg \ sshpass \ git \ tini \ zip \ unzip \ tar \ python3-aiohttp \ netcat-traditional RUN apt-get clean --yes RUN mkdir --parents /tmp/apt RUN curl -sSL -o /tmp/apt/opentofu.deb https://github.com/opentofu/opentofu/releases/download/v${OPENTOFU_VERSION}/tofu_${OPENTOFU_VERSION}_amd64.deb RUN dpkg --install /tmp/apt/opentofu.deb RUN curl -sSL -o /tmp/apt/semaphore.deb https://github.com/ansible-semaphore/semaphore/releases/download/v${SEMAPHORE_VERSION}/semaphore_${SEMAPHORE_VERSION}_linux_amd64.deb RUN dpkg --install /tmp/apt/semaphore.deb RUN rm -rf /tmp/apt RUN python -m pip install /tmp/wheels/*.whl \ --upgrade \ --pre \ --no-index \ --no-cache-dir \ --find-links /tmp/wheels \ --disable-pip-version-check RUN rm -rf /tmp/wheels # From here down we are adapting the prod deployment # container directly from the semaphore project RUN adduser semaphore \ --disabled-password \ --uid 1001 \ --gid 0 RUN mkdir --parents \ /etc/semaphore \ /tmp/semaphore \ /var/lib/semaphore RUN chown -R semaphore:root \ /etc/semaphore \ /tmp/semaphore \ /var/lib/semaphore WORKDIR /home/semaphore USER 1001 ENTRYPOINT ["tini", "--"] CMD ["/usr/local/bin/semaphore-wrapper", "semaphore", "server", "--config", "/etc/semaphore/config.json"]