From 9965e4f19aada6e13153f6af5c6a42ba38363560 Mon Sep 17 00:00:00 2001 From: Ryan Campbell Date: Tue, 23 Jul 2024 00:29:38 +0000 Subject: [PATCH 1/6] adding pypi server to run next to registry --- Dockerfiles/Dockerfile | 74 ++++++++++++++++++++++++++++++++++++++---- README.md | 2 +- src/entrypoint.sh | 29 +++++++++++++++++ 3 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 src/entrypoint.sh diff --git a/Dockerfiles/Dockerfile b/Dockerfiles/Dockerfile index a70f5ae..05e1b19 100755 --- a/Dockerfiles/Dockerfile +++ b/Dockerfiles/Dockerfile @@ -1,6 +1,8 @@ ARG INSTALL_OCI_REGISTRY_VER="2.8.2" ARG DOTNET_CONTAINER_VARIANT="6.0-jammy" - +ARG PYPISERVER_PORT=8080 +ARG PYPI_SERVER_VERSION="2.1.1" +ARG OCI_REGISTRY_PORT=5000 FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${DOTNET_CONTAINER_VARIANT} AS downloader ARG INSTALL_OCI_REGISTRY_VER="2.8.2" ENV INSTALL_OCI_REGISTRY_VER=${INSTALL_OCI_REGISTRY_VER} @@ -20,10 +22,58 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ RUN mkdir -p /htpasswd/libs RUN ldd /usr/bin/htpasswd | grep "=> /" | awk '{print $3}' | xargs -I '{}' cp -v '{}' /htpasswd/libs -# FROM mcr.microsoft.com/cbl-mariner/distroless/minimal:2.0 -FROM mcr.microsoft.com/cbl-mariner/distroless/base:2.0 +# Setup PypiServer +FROM mcr.microsoft.com/devcontainers/python:1-3.9 as pypi_builder +ARG PYPI_SERVER_VERSION="2.1.1" +ENV PYPI_SERVER_VERSION=${PYPI_SERVER_VERSION} + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gnupg \ + wget \ + git \ + curl \ + tar \ + libffi-dev \ + tree + +RUN curl --silent --fail --create-dirs --output /code/pypiserver.tar.gz -L https://github.com/pypiserver/pypiserver/archive/refs/tags/v${PYPI_SERVER_VERSION}.tar.gz \ + && tar -xvzf /code/pypiserver.tar.gz -C /code/ + +WORKDIR /code/pypiserver-${PYPI_SERVER_VERSION} + +RUN python -m pip install \ + --no-warn-script-location \ + --prefix=/pypi-server \ + --requirement docker/docker-requirements.txt +RUN python -m pip install \ + --no-warn-script-location \ + --prefix=/pypi-server \ + . + +RUN mkdir -p /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data/packages \ + && cp /code/pypiserver-${PYPI_SERVER_VERSION}/docker/gunicorn.conf.py /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data/gunicorn.conf.py + +FROM mcr.microsoft.com/cbl-mariner/base/python:3.9 as final +ARG OCI_REGISTRY_PORT=5000 ARG INSTALL_OCI_REGISTRY_VER="2.8.2" +ARG PYPI_SERVER_VERSION="2.1.1" +ARG PYPISERVER_PORT=8080 + +ENV OCI_REGISTRY_PORT=${OCI_REGISTRY_PORT} +ENV PYPI_SERVER_VERSION=${PYPI_SERVER_VERSION} +ENV PYPISERVER_PORT=${PYPISERVER_PORT} + +# Flush logs immediately to stdout +ENV PYTHONUNBUFFERED=t + +ENV PYTHONPATH=/pypi-server/lib/python3.9/site-packages/ + +RUN ln -s /usr/bin/python3 /usr/bin/python \ + && ln -s /usr/bin/python3 /usr/local/bin/python + +# Copy the registry binaries and the configuration file COPY src/registry-config.yml /etc/docker/registry/config.yml COPY --from=downloader /registry /bin/registry @@ -31,8 +81,18 @@ COPY --from=downloader /registry /bin/registry COPY --from=downloader /usr/bin/htpasswd /usr/bin/htpasswd COPY --from=downloader /htpasswd/libs/* /usr/lib/ +# Copy the built pypi-server files +COPY --from=pypi_builder /pypi-server /pypi-server +COPY --from=pypi_builder /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data /data +COPY --chmod=0755 src/entrypoint.sh /entrypoint.sh + + +VOLUME "/var/lib/registry" +VOLUME "/data/packages" +EXPOSE ${OCI_REGISTRY_PORT} ${PYPISERVER_PORT} + +USER root + +ENTRYPOINT ["/entrypoint.sh"] + -VOLUME ["/var/lib/registry"] -EXPOSE 5000 -ENTRYPOINT ["registry"] -CMD ["serve", "/etc/docker/registry/config.yml"] \ No newline at end of file diff --git a/README.md b/README.md index baa89e6..d282ee3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![coresvc-registry-build](https://github.com/microsoft/azure-orbital-space-sdk-coresvc-registry/actions/workflows/coresvc-registry-build.yml/badge.svg)](https://github.com/microsoft/azure-orbital-space-sdk-coresvc-registry/actions/workflows/coresvc-registry-build.yml) -Provides an on-vehicle container image repository to use for the Space SDK. This is a fork from https://github.com/distribution/distribution with updates to source images to pullfrom the Microsoft Container Registry. +Provides an on-vehicle container image repository to use for the Space SDK. This is a fork from https://github.com/distribution/distribution with updates to source images to pullfrom the Microsoft Container Registry. It has combined with https://github.com/pypiserver/pypiserver. ## Build diff --git a/src/entrypoint.sh b/src/entrypoint.sh new file mode 100644 index 0000000..cd19433 --- /dev/null +++ b/src/entrypoint.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# This will start the OCI Registry and the PyPI server in the background and listen for the +# SIGTERM and SIGINT signals to stop the processes gracefully. + +# Function to handle termination signal +terminate_processes() { + echo "Termination signal received. Stopping processes..." + kill $REGISTRY_PID $PYPI_PID + wait $REGISTRY_PID $PYPI_PID + echo "Processes stopped." + exit 0 +} + +# Trap SIGTERM and SIGINT signals and call the termination function +trap terminate_processes SIGTERM SIGINT + + +# Run the OCI_Registry in the background first +registry serve /etc/docker/registry/config.yml & +REGISTRY_PID=$! + +# Run the pypi server in the background +mkdir -p /data/packages +/pypi-server/bin/pypi-server run -p ${PYPISERVER_PORT:-$PORT} --server gunicorn --backend cached-dir /data/packages & +PYPI_PID=$! + +# Wait for the background processes to complete +wait $REGISTRY_PID $PYPI_PID \ No newline at end of file From a48a2d27ec4db479bcc4ce523e3bc2a52abb34b8 Mon Sep 17 00:00:00 2001 From: Ryan Campbell Date: Tue, 23 Jul 2024 00:40:54 +0000 Subject: [PATCH 2/6] adding SSL --- Dockerfiles/Dockerfile | 5 +++-- src/gunicorn.conf.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/gunicorn.conf.py diff --git a/Dockerfiles/Dockerfile b/Dockerfiles/Dockerfile index 05e1b19..40fed00 100755 --- a/Dockerfiles/Dockerfile +++ b/Dockerfiles/Dockerfile @@ -52,8 +52,9 @@ RUN python -m pip install \ --prefix=/pypi-server \ . -RUN mkdir -p /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data/packages \ - && cp /code/pypiserver-${PYPI_SERVER_VERSION}/docker/gunicorn.conf.py /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data/gunicorn.conf.py +RUN mkdir -p /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data/packages + +COPY src/gunicorn.conf.py /code/pypiserver-${PYPI_SERVER_VERSION}/docker/data/gunicorn.conf.py FROM mcr.microsoft.com/cbl-mariner/base/python:3.9 as final ARG OCI_REGISTRY_PORT=5000 diff --git a/src/gunicorn.conf.py b/src/gunicorn.conf.py new file mode 100644 index 0000000..c2bf9e6 --- /dev/null +++ b/src/gunicorn.conf.py @@ -0,0 +1,12 @@ +# Enable to log every request +accesslog = "-" +errorlog = "-" +preload_app = True +workers = 1 +worker_class = "gevent" + +# SSL Certs +keyfile = "/certs/registry.spacefx.local.key" # Path to your private key file +certfile = "/certs/registry.spacefx.local.crt" # Path to your certificate file + +bind = "0.0.0.0:8080" \ No newline at end of file From 8f51724cc5ed6dc37667413fbf424ee9be1ca2b8 Mon Sep 17 00:00:00 2001 From: Ryan Campbell Date: Tue, 23 Jul 2024 00:41:17 +0000 Subject: [PATCH 3/6] removing bind from config --- src/gunicorn.conf.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gunicorn.conf.py b/src/gunicorn.conf.py index c2bf9e6..2253967 100644 --- a/src/gunicorn.conf.py +++ b/src/gunicorn.conf.py @@ -7,6 +7,4 @@ # SSL Certs keyfile = "/certs/registry.spacefx.local.key" # Path to your private key file -certfile = "/certs/registry.spacefx.local.crt" # Path to your certificate file - -bind = "0.0.0.0:8080" \ No newline at end of file +certfile = "/certs/registry.spacefx.local.crt" # Path to your certificate file \ No newline at end of file From ad1ace381addc4008fff570837d664c807a45185 Mon Sep 17 00:00:00 2001 From: Ryan Campbell Date: Tue, 23 Jul 2024 13:20:40 +0000 Subject: [PATCH 4/6] updating to selectively enable registry and pypiserver --- src/entrypoint.sh | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/entrypoint.sh b/src/entrypoint.sh index cd19433..806823e 100644 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -3,11 +3,23 @@ # This will start the OCI Registry and the PyPI server in the background and listen for the # SIGTERM and SIGINT signals to stop the processes gracefully. +REGISTRY_ENABLED="${REGISTRY_ENABLED:-"true"}" +PYPISERVER_ENABLED="${PYPISERVER_ENABLED:-"true"}" + # Function to handle termination signal terminate_processes() { echo "Termination signal received. Stopping processes..." - kill $REGISTRY_PID $PYPI_PID - wait $REGISTRY_PID $PYPI_PID + if [[ "${REGISTRY_ENABLED}" == "true" ]] && [[ "${PYPISERVER_ENABLED}" == "true" ]]; then + kill $REGISTRY_PID $PYPI_PID + wait $REGISTRY_PID $PYPI_PID + elif [[ "${REGISTRY_ENABLED}" == "true" ]]; then + kill $REGISTRY_PID + wait $REGISTRY_PID + elif [[ "${PYPISERVER_ENABLED}" == "true" ]]; then + kill $PYPI_PID + wait $PYPI_PID + fi + echo "Processes stopped." exit 0 } @@ -15,15 +27,26 @@ terminate_processes() { # Trap SIGTERM and SIGINT signals and call the termination function trap terminate_processes SIGTERM SIGINT +if [[ "${REGISTRY_ENABLED}" == "true" ]]; then + # Run the OCI_Registry in the background + registry serve /etc/docker/registry/config.yml 2>&1 | tee -a /var/log/registry.log & + REGISTRY_PID=$! +fi -# Run the OCI_Registry in the background first -registry serve /etc/docker/registry/config.yml & -REGISTRY_PID=$! +if [[ "${PYPISERVER_ENABLED}" == "true" ]]; then + # Run the pypi server in the background + mkdir -p /data/packages + /pypi-server/bin/pypi-server run -p ${PYPISERVER_PORT:-$PORT} --server gunicorn --backend cached-dir /data/packages 2>&1 | tee -a /var/log/pypiserver.log & + PYPI_PID=$! +fi -# Run the pypi server in the background -mkdir -p /data/packages -/pypi-server/bin/pypi-server run -p ${PYPISERVER_PORT:-$PORT} --server gunicorn --backend cached-dir /data/packages & -PYPI_PID=$! -# Wait for the background processes to complete -wait $REGISTRY_PID $PYPI_PID \ No newline at end of file +if [[ "${REGISTRY_ENABLED}" == "true" ]] && [[ "${PYPISERVER_ENABLED}" == "true" ]]; then + # Wait for the background processes to complete + wait $REGISTRY_PID $PYPI_PID +elif [[ "${REGISTRY_ENABLED}" == "true" ]]; then + wait $REGISTRY_PID +elif [[ "${PYPISERVER_ENABLED}" == "true" ]]; then + wait $PYPI_PID +fi + From 253ba3cc2165f978cac22cb1060fa9caad5addeb Mon Sep 17 00:00:00 2001 From: Ryan Campbell Date: Tue, 23 Jul 2024 13:50:14 +0000 Subject: [PATCH 5/6] adjusting logs --- src/entrypoint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 806823e..bdeab94 100644 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -29,14 +29,14 @@ trap terminate_processes SIGTERM SIGINT if [[ "${REGISTRY_ENABLED}" == "true" ]]; then # Run the OCI_Registry in the background - registry serve /etc/docker/registry/config.yml 2>&1 | tee -a /var/log/registry.log & + registry serve /etc/docker/registry/config.yml & REGISTRY_PID=$! fi if [[ "${PYPISERVER_ENABLED}" == "true" ]]; then # Run the pypi server in the background mkdir -p /data/packages - /pypi-server/bin/pypi-server run -p ${PYPISERVER_PORT:-$PORT} --server gunicorn --backend cached-dir /data/packages 2>&1 | tee -a /var/log/pypiserver.log & + /pypi-server/bin/pypi-server run -p ${PYPISERVER_PORT:-$PORT} --server gunicorn --backend cached-dir /data/packages --verbose --log-file /var/log/pypiserver.log & PYPI_PID=$! fi From 5636fac1685514155f2ffacbb9bc5595838d1772 Mon Sep 17 00:00:00 2001 From: Ryan Campbell Date: Tue, 23 Jul 2024 14:04:51 +0000 Subject: [PATCH 6/6] updating for logging --- src/entrypoint.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/entrypoint.sh b/src/entrypoint.sh index bdeab94..87c401a 100644 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -28,16 +28,20 @@ terminate_processes() { trap terminate_processes SIGTERM SIGINT if [[ "${REGISTRY_ENABLED}" == "true" ]]; then + echo "REGISTRY_ENABLED='true'. Starting the OCI Registry..." # Run the OCI_Registry in the background registry serve /etc/docker/registry/config.yml & REGISTRY_PID=$! + echo "...OCI Registry successfully started." fi if [[ "${PYPISERVER_ENABLED}" == "true" ]]; then + echo "PYPISERVER_ENABLED='true'. Starting the PyPiServer..." # Run the pypi server in the background mkdir -p /data/packages /pypi-server/bin/pypi-server run -p ${PYPISERVER_PORT:-$PORT} --server gunicorn --backend cached-dir /data/packages --verbose --log-file /var/log/pypiserver.log & PYPI_PID=$! + echo "...PyPiServer started." fi