# Stage 1: Build stage with necessary build dependencies FROM quay.io/fedora/python-312:20240814 AS prebuild LABEL \ name="python-312-with-rust" \ vendor="Fedora Infrastructure" \ license="MIT" USER root # Add RPM-only modules and build dependencies RUN dnf install -y \ python3-pyrpmmd \ python3-poetry \ poetry \ cargo \ logrotate \ git \ gcc \ gcc-c++ \ libffi-devel \ openssl-devel # Stage 2: Build mirrormanager2 python code FROM prebuild AS mirrormanager2-build # Clone MirrorManager2 source code from the Git repo RUN mkdir -p /opt/mirrormanager2 WORKDIR /opt/mirrormanager2 RUN git clone https://github.com/fedora-infra/mirrormanager2.git . RUN sed -e 's/signed_fpca/signed_rosca/' -i mirrormanager2/perms.py mirrormanager2/auth.py RUN pip install --prefix=/install . RUN pip install --prefix=/install flask_session psycopg2 # Stage 3: Build generate-mirrorlist-cache and mirrorlist-server FROM prebuild AS mirrorlist-build RUN mkdir -p /opt/mirrorlist-server WORKDIR /opt/mirrorlist-server RUN git clone https://github.com/adrianreber/mirrorlist-server.git . RUN echo -e '[profile.release-with-debug]\ninherits = "release"\ndebug = true\n' >> Cargo.toml # NOTE(neil): 20241217 #![deny(warnings)] causes deprecated/removed lints to be errors... RUN sed -i 's,#!\[deny(warnings)\],\#!\[allow(renamed_and_removed_lints)\],' src/bin/mirrorlist-server.rs src/bin/generate-mirrorlist-cache.rs RUN cargo build --profile=release-with-debug # Stage 4: Build scan-primary-mirror FROM prebuild AS scan-primary-mirror-build RUN mkdir -p /opt/scan-primary-mirror WORKDIR /opt/scan-primary-mirror RUN git clone https://github.com/adrianreber/scan-primary-mirror.git . RUN RUSTFLAGS=-g cargo build --release # Stage 5: Final stage with runtime dependencies FROM quay.io/fedora/python-312:20240814 AS runtime LABEL \ name="python-312-with-rust" \ vendor="Fedora Infrastructure" \ license="MIT" USER root # Add only runtime dependencies RUN dnf install -y \ python3-pyrpmmd \ uwsgi \ uwsgi-plugin-python3 \ logrotate # Copy installation of mirrormanager from it's build stage COPY --from=mirrormanager2-build /install /opt/app-root/ # Copy mirrorlist-server and generate-mirrorlist-cache from mirrorlist-server build COPY --from=mirrorlist-build /opt/mirrorlist-server/target/release-with-debug/generate-mirrorlist-cache /usr/local/bin/ COPY --from=mirrorlist-build /opt/mirrorlist-server/target/release-with-debug/mirrorlist-server /usr/local/bin/ # Copy scan-primary-mirror from its build step COPY --from=scan-primary-mirror-build /opt/scan-primary-mirror/target/release/scan-primary-mirror /usr/local/bin/ # Copy in the wsgi entry point ADD run.py /opt/mirrormanager2/ # Stage 6: flatten :) FROM runtime as final LABEL \ name="python-312-with-rust-mirrormanager" \ vendor="Rocky Linux Infrastructure" \ license="MIT" WORKDIR /opt/mirrormanager2 EXPOSE 5000 # @TODO(neil): probably this shouldn't be here? maybe SSM -> parse out in mm2.cfg? COPY client_secrets.json /etc/mirrormanager/ COPY mirrormanager2.cfg /etc/mirrormanager/ COPY static/rocky /opt/app-root/lib/python3.12/site-packages/mirrormanager2/static/rocky COPY templates/rocky /opt/app-root/lib/python3.12/site-packages/mirrormanager2/templates/rocky ENV MM2_CONFIG=/etc/mirrormanager/mirrormanager2.cfg ENV SETUP_DB=false RUN test "$SETUP_DB" || python -m flask -A mirrormanager2.app db sync # Define entrypoint script to start the application CMD [ "uwsgi", "--socket", "0.0.0.0:5000", \ "--uid", "uwsgi", \ "--plugins", "python3", \ "--protocol", "http", \ "--enable-threads", \ "--master", \ "-b", "65535", \ "-H", "/opt/app-root/", \ "--wsgi-file", "/opt/mirrormanager2/run.py" ]