diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2c7d170..d48adbf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,7 @@ updates: directory: "/" schedule: interval: "daily" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "daily" diff --git a/Dockerfile b/Dockerfile index 34389f1..7c03f38 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ -FROM python:3.8.16-bullseye +FROM python:3.8.18-bookworm LABEL maintainer="Sida Say " COPY prebuildfs / SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN install_packages ca-certificates git supervisor gettext-base nginx tree +RUN install_packages ca-certificates gettext-base nginx tini tree # Create directories and user for PrivacyIdea and set ownership RUN mkdir -p /data/privacyidea/keys \ @@ -16,7 +16,6 @@ RUN mkdir -p /data/privacyidea/keys \ --home /home/privacyidea \ --uid 1001 \ privacyidea && \ - addgroup privacyidea privacyidea && \ usermod -g 1001 privacyidea && \ chown -R privacyidea:privacyidea /var/log/privacyidea /data/privacyidea /etc/privacyidea @@ -44,10 +43,7 @@ ARG PI_VERSION=3.8.1 # Create a virtual environment for PrivacyIdea and install its dependencies RUN python3 -m venv $VIRTUAL_ENV && \ - pip3 install wheel && \ - pip3 install uwsgi pymysql-sa PyMySQL psycopg2-binary && \ - pip3 install -r https://raw.githubusercontent.com/privacyidea/privacyidea/v${PI_VERSION}/requirements.txt && \ - pip3 install git+https://github.com/privacyidea/privacyidea.git@v${PI_VERSION} + pip3 install -r /opt/requirements.txt # Copy the rootfs directory to the root of the container filesystem COPY rootfs / @@ -57,7 +53,7 @@ EXPOSE 80/tcp EXPOSE 443/tcp # Set the entrypoint to the privacyidea_entrypoint.sh script -ENTRYPOINT ["/usr/local/bin/privacyidea_entrypoint.sh"] +ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/privacyidea_entrypoint.sh"] WORKDIR /opt/privacyidea diff --git a/prebuildfs/opt/requirements.txt b/prebuildfs/opt/requirements.txt new file mode 100644 index 0000000..f4a14be --- /dev/null +++ b/prebuildfs/opt/requirements.txt @@ -0,0 +1,4 @@ +uWSGI==2.0.22 +psycopg2-binary==2.9.7 +privacyIDEA==3.9 +supervisor==4.2.5 diff --git a/rootfs/etc/uwsgi/uwsgi.ini b/rootfs/etc/uwsgi/uwsgi.ini index bd3f872..a822ad1 100644 --- a/rootfs/etc/uwsgi/uwsgi.ini +++ b/rootfs/etc/uwsgi/uwsgi.ini @@ -7,6 +7,7 @@ hook-master-start = unix_signal:15 gracefully_kill_them_all need-app = true die-on-term = true # For debugging and testing +# For debugging and testing show-config = false # enable thread disable-logging = true diff --git a/rootfs/usr/local/bin/_privacyidea_common.sh b/rootfs/usr/local/bin/_privacyidea_common.sh index cb75832..e378714 100755 --- a/rootfs/usr/local/bin/_privacyidea_common.sh +++ b/rootfs/usr/local/bin/_privacyidea_common.sh @@ -11,7 +11,8 @@ execute_scripts() { local script_name=$(basename "$script_path") echo "" echo "[PrivacyIDEA] Executing $script_name." - source "$script_path" || { echo "[PrivacyIDEA] Error: Failed to execute $script_name."; return 1; } + echo "" + source "$script_path" || { echo "[ERROR]: Failed to execute $script_name."; return 1; } done echo "" diff --git a/rootfs/usr/local/bin/configure_nginx.sh b/rootfs/usr/local/bin/configure_nginx.sh index d86fe39..8b9b6fa 100755 --- a/rootfs/usr/local/bin/configure_nginx.sh +++ b/rootfs/usr/local/bin/configure_nginx.sh @@ -67,10 +67,13 @@ function main { if [ "$NGINX_SSL_ENABLED" = true ]; then if [ -z "$NGINX_SSL_CERT" ] && [ -z "$NGINX_SSL_KEY" ]; then - echo "SSL enabled but NGINX_SSL_CERT and NGINX_SSL_KEY are not defined, using generated certificate" + echo "[WARNING] SSL enabled but NGINX_SSL_CERT and NGINX_SSL_KEY are not defined, using seflf-signed certificate" + echo "" generate_cert export NGINX_SSL_CERT=/etc/nginx/certs/pi-server-cert.pem export NGINX_SSL_KEY=/etc/nginx/certs/pi-server-key.pem + echo "[INFO] A seflf-signed certificate has been generated at $NGINX_SSL_CERT and $NGINX_SSL_KEY" + echo "" fi envsubst < /opt/templates/nginx-pi-ssl.conf.template > /etc/nginx/conf.d/pi-ssl.conf fi diff --git a/rootfs/usr/local/bin/start_privacyidea.sh b/rootfs/usr/local/bin/start_privacyidea.sh index c1860ec..1504f34 100755 --- a/rootfs/usr/local/bin/start_privacyidea.sh +++ b/rootfs/usr/local/bin/start_privacyidea.sh @@ -4,26 +4,32 @@ set -e source /usr/local/bin/_privacyidea_common.sh function main { + echo "" + echo " _ _______ _______ " + echo " ___ ____(_) _____ _______ __/ _/ _ \/ __/ _ |" + echo ' / _ \/ __/ / |/ / _ `/ __/ // // // // / _// __ |' + echo " / .__/_/ /_/|___/\_,_/\__/\_, /___/____/___/_/ |_|" + echo "/_/ /___/ " echo "" echo "[PrivacyIDEA] Starting ${PrivacyIDEA}. To stop the container with CTRL-C, run this container with the option \"-it\"." echo "" generate_pi_config prestart_privacyidea - exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf + exec supervisord -c /etc/supervisor/supervisord.conf } function generate_pi_config { # Check the selected database vendor if [ "${DB_VENDOR}" = "mariadb" ] || [ "${DB_VENDOR}" = "mysql" ]; then - echo "Using $DB_VENDOR..." + echo "[INFO] Using $DB_VENDOR ..." # Ensure that the necessary variables are defined - [ -z "$DB_HOST" ] && echo "DB_HOST should be defined" && return 1 - [ -z "$DB_USER" ] && echo "DB_USER should be defined" && return 1 - [ -z "$DB_PASSWORD" ] && echo "DB_PASSWORD should be defined" && return 1 - [ -z "$DB_NAME" ] && echo "DB_NAME should be defined" && return 1 + [ -z "$DB_HOST" ] && echo "[ERROR] DB_HOST should be defined" && return 1 + [ -z "$DB_USER" ] && echo "[ERROR] DB_USER should be defined" && return 1 + [ -z "$DB_PASSWORD" ] && echo "[ERROR] DB_PASSWORD should be defined" && return 1 + [ -z "$DB_NAME" ] && echo "[ERROR] DB_NAME should be defined" && return 1 # Set the default port if it is not defined if [ -z "$DB_PORT" ]; then @@ -38,14 +44,15 @@ function generate_pi_config { echo "Using $DB_VENDOR..." # Ensure that the necessary variables are defined - [ -z "$DB_HOST" ] && echo "DB_HOST should be defined" && return 1 - [ -z "$DB_USER" ] && echo "DB_USER should be defined" && return 1 - [ -z "$DB_PASSWORD" ] && echo "DB_PASSWORD should be defined" && return 1 - [ -z "$DB_NAME" ] && echo "DB_NAME should be defined" && return 1 + [ -z "$DB_HOST" ] && echo "[ERROR] DB_HOST should be defined" && return 1 + [ -z "$DB_USER" ] && echo "[ERROR] DB_USER should be defined" && return 1 + [ -z "$DB_PASSWORD" ] && echo "[ERROR] DB_PASSWORD should be defined" && return 1 + [ -z "$DB_NAME" ] && echo "[ERROR] DB_NAME should be defined" && return 1 # Set the default port if it is not defined if [ -z "$DB_PORT" ]; then - echo DB_PORT is not defined using default port + echo "[INFO] DB_PORT is not defined using default port 5432" + echo "" export DB_PORT=5432 fi @@ -53,7 +60,8 @@ function generate_pi_config { export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} else - echo "DB_VENDOR environment variable is not set. Using default SQLite..." + echo "" + echo "[WARNING] DB_VENDOR environment variable is not set. Using default SQLite..." echo "" # Define the SQLAlchemy database URI for SQLite @@ -65,7 +73,9 @@ function generate_pi_config { # Check if SQLALCHEMY_DATABASE_URI is defined if [ -z "$SQLALCHEMY_DATABASE_URI" ]; then - echo "SQLALCHEMY_DATABASE_URI is undefined" + echo "" + echo "[WARNING] SQLALCHEMY_DATABASE_URI is undefined" + echo "" else # Use the pi-config.template file as a template and substitute the necessary variables envsubst < /opt/templates/pi-config.template > /etc/privacyidea/pi.cfg @@ -78,6 +88,7 @@ function prestart_privacyidea { # Copy files from mounted directory to PI_HOME if [ -d "${PI_MOUNT_DIR}/files" ] && [ "$(ls -A "${PI_MOUNT_DIR}/files")" ]; then + echo "" echo "[privacyIDEA] Copying files from ${PI_MOUNT_DIR}/files:" echo "" tree --noreport "${PI_MOUNT_DIR}/files" @@ -86,6 +97,7 @@ function prestart_privacyidea { cp -r "${PI_MOUNT_DIR}/files"/* "${PI_HOME}" echo "" else + echo "" echo "[privacyIDEA] The directory ${PI_MOUNT_DIR}/files does not exist or is empty. Copy any files to this directory to have them copied to ${PI_HOME} before privacyIDEA starts." echo "" fi @@ -94,6 +106,7 @@ function prestart_privacyidea { if [ -d "${PI_MOUNT_DIR}/scripts" ]; then execute_scripts "${PI_MOUNT_DIR}/scripts" else + echo "" echo "[privacyIDEA] The directory ${PI_MOUNT_DIR}/scripts does not exist. Copy any scripts to this directory to have them executed, in alphabetical order, before privacyIDEA starts." echo "" fi @@ -103,38 +116,51 @@ function prestart_privacyidea { # Create keys directory if not exists if [ ! -d /data/privacyidea/keys ]; then - echo "Creating keys directory..." + echo "" + echo "[INFO] Creating keys directory..." + echo "" mkdir /data/privacyidea/keys fi # Create encryption key file if not exists if [ ! -f /data/privacyidea/keys/encfile ]; then - echo "Encryption key file not found, creating a new one..." + echo "" + echo "[INFO] Encryption key file not found, creating a new one..." + echo "" pi-manage create_enckey fi # Create audit keys if not exists if [ ! -f /data/privacyidea/keys/private.pem ]; then - echo "Creating audit keys..." + echo "" + echo "[INFO] Creating audit keys..." + echo "" pi-manage create_audit_keys fi # Create database tables - echo "Generating privacyIDEA database tables..." + echo "" + echo "[INFO] Generating privacyIDEA database tables..." + echo "" pi-manage create_tables # Create admin user if not specified through environment variables if [ -z "${PI_ADMIN_USER}" ] || [ -z "${PI_ADMIN_PASSWORD}" ]; then - echo "Creating default admin user. WARNING: This is not recommended for production environments. Please set PI_ADMIN_USER and PI_ADMIN_PASSWORD environment variables to specify the admin user in production." + echo "" + echo "[INFO] Creating default admin user. [WARNING]: This is not recommended for production environments. Please set PI_ADMIN_USER and PI_ADMIN_PASSWORD environment variables to specify the admin user in production." + echo "" pi-manage admin add admin -p privacyidea else - echo "Creating admin user from specified environment variables..." + echo "" + echo "[INFO] Creating admin user from specified environment variables..." + echo "" pi-manage admin add "${PI_ADMIN_USER}" -p "${PI_ADMIN_PASSWORD}" fi else - echo "Skipping key generation, table creation, and admin user creation." + echo "" + echo "[INFO] Skipping key generation, table creation, and admin user creation." + echo "" fi } - main diff --git a/structure-tests.yaml b/structure-tests.yaml index 3baf1ea..ef74a85 100644 --- a/structure-tests.yaml +++ b/structure-tests.yaml @@ -31,7 +31,7 @@ metadataTest: - key: VIRTUAL_ENV value: "/opt/privacyidea" workdir: "/opt/privacyidea" - entrypoint: ["/usr/local/bin/privacyidea_entrypoint.sh"] + entrypoint: ["/usr/bin/tini", "--", "/usr/local/bin/privacyidea_entrypoint.sh"] exposedPorts: ["80", "443"] fileExistenceTests: