From 51964a2e2b6cd7e94c418a73667f1030943629ae Mon Sep 17 00:00:00 2001 From: Sida Say Date: Fri, 24 Jun 2022 21:42:42 +0700 Subject: [PATCH] fix when run pi-manage using sqlite not config db --- Dockerfile | 22 ++++----- configs/nginx/nginx.conf.template | 20 ++++++++ configs/nginx/pi.conf.template | 8 +++ configs/{config.py => pi-config.template} | 2 +- docker-compose.yml | 2 +- scripts/configure_nginx.sh | 60 +---------------------- scripts/privacyidea_entrypoint.sh | 12 ++--- scripts/start_privacyidea.sh | 53 ++++++++++++++------ 8 files changed, 85 insertions(+), 94 deletions(-) create mode 100644 configs/nginx/nginx.conf.template create mode 100644 configs/nginx/pi.conf.template rename configs/{config.py => pi-config.template} (92%) diff --git a/Dockerfile b/Dockerfile index eebf6e6..491a15f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM nginx:1.21 +FROM nginx:1.22.0 LABEL maintainer="Sida Say " @@ -23,18 +23,19 @@ RUN mkdir -p mkdir /etc/privacyidea/data/keys \ # apt-get remove --purge --auto-remove -y ca-certificates && rm -rf /var/lib/apt/lists/* # COPY PI configuration -COPY --chown=privacyidea:privacyidea ./configs/config.py /etc/privacyidea/pi.cfg +COPY --chown=privacyidea:privacyidea ./configs/pi-config.template /etc/privacyidea/pi-config.template # Remove default configuration from Nginx RUN rm /etc/nginx/conf.d/default.conf +COPY ./configs/nginx /etc/nginx/templates + # Copy the base uWSGI ini file to enable default dynamic uwsgi process number COPY --chown=privacyidea:privacyidea ./configs/uwsgi.ini /etc/uwsgi/ # Custom Supervisord config COPY --chown=privacyidea:privacyidea ./configs/supervisord-debian.conf /etc/supervisor/supervisord.conf -# Add demo app COPY --chown=privacyidea:privacyidea ./configs/app /app COPY scripts/* /usr/local/bin/ @@ -57,7 +58,7 @@ ENV UWSGI_PROCESSES 16 # By default, allow unlimited file sizes, modify it to limit the file sizes # To have a maximum of 1 MB (Nginx's default) change the line to: # ENV NGINX_MAX_UPLOAD 1m -ENV NGINX_MAX_UPLOAD 0 +ENV NGINX_MAX_UPLOAD 100m # By default, Nginx will run a single worker process, setting it to auto # will create a worker for each CPU core @@ -66,18 +67,19 @@ ENV NGINX_WORKER_PROCESSES 1 # By default, NGINX show NGINX version on error page and HTTP header ENV NGINX_SERVER_TOKENS 'off' +ENV NGINX_WORKER_CONNECTIONS 1024 + # By default, Nginx listens on port 80. # To modify this, change LISTEN_PORT environment variable. # (in a Dockerfile or with an option for `docker run`) ENV LISTEN_PORT 80 -#USER privacyidea - ENV PI_SKIP_BOOTSTRAP=false \ DB_VENDOR=sqlite \ - PI_VERSION=3.7.1 \ PI_HOME=/opt/privacyidea +ARG PI_VERSION=3.7.1 + ENV VIRTUAL_ENV=/opt/privacyidea RUN python3 -m venv $VIRTUAL_ENV ENV PATH="$VIRTUAL_ENV/bin:$PATH" @@ -87,14 +89,10 @@ RUN pip install wheel && \ pip install -r https://raw.githubusercontent.com/privacyidea/privacyidea/v${PI_VERSION}/requirements.txt && \ pip install git+https://github.com/privacyidea/privacyidea.git@v${PI_VERSION} -# Copy start.sh script that will check for a /app/prestart.sh script and run it before starting the app -# Copy the entrypoint that will generate Nginx additional configs -# Make sure scripts can be executed and do some cleanup - EXPOSE 80/tcp EXPOSE 443/tcp -#USER privacyidea + ENTRYPOINT ["/usr/local/bin/privacyidea_entrypoint.sh"] WORKDIR /app diff --git a/configs/nginx/nginx.conf.template b/configs/nginx/nginx.conf.template new file mode 100644 index 0000000..05b2519 --- /dev/null +++ b/configs/nginx/nginx.conf.template @@ -0,0 +1,20 @@ +user nginx; +worker_processes $NGINX_WORKER_PROCESSES; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; +events { + worker_connections $NGINX_WORKER_CONNECTIONS; +} +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + keepalive_timeout 65; + server_tokens $NGINX_SERVER_TOKENS; + include /etc/nginx/conf.d/*.conf; +} +daemon off; diff --git a/configs/nginx/pi.conf.template b/configs/nginx/pi.conf.template new file mode 100644 index 0000000..768610a --- /dev/null +++ b/configs/nginx/pi.conf.template @@ -0,0 +1,8 @@ +server { + listen $LISTEN_PORT; + client_max_body_size $NGINX_MAX_UPLOAD; + location / { + include uwsgi_params; + uwsgi_pass unix:///tmp/uwsgi.sock; + } +} diff --git a/configs/config.py b/configs/pi-config.template similarity index 92% rename from configs/config.py rename to configs/pi-config.template index 5a988d2..314f1c7 100644 --- a/configs/config.py +++ b/configs/pi-config.template @@ -13,7 +13,7 @@ sys.exit(1) # The realm, where users are allowed to login as administrators SUPERUSER_REALM = os.environ.get('SUPERUSER_REALM', ['administrator']) -SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI', 'sqlite:////etc/privacyidea/data/privacyidea.db') +SQLALCHEMY_DATABASE_URI = "$SQLALCHEMY_DATABASE_URI" PI_ENCFILE = os.environ.get("PI_ENCFILE", "/data/privacyidea/encfile") PI_HSM = os.environ.get("PI_HSM", "default") PI_AUDIT_MODULE = os.environ.get("PI_AUDIT_MODULE", "privacyidea.lib.auditmodules.sqlaudit") diff --git a/docker-compose.yml b/docker-compose.yml index 0b1f801..7cc8eec 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,7 @@ services: - MARIADB_USER=privacyidea - MARIADB_PASSWORD=privacyidea privacyidea: - image: 'docker.io/khalibre/privacyidea:latest' + image: 'khalibre/privacyidea:dev' ports: - '80:80' environment: diff --git a/scripts/configure_nginx.sh b/scripts/configure_nginx.sh index 7524198..72323d8 100644 --- a/scripts/configure_nginx.sh +++ b/scripts/configure_nginx.sh @@ -3,68 +3,12 @@ set -e function main { - # Get the maximum upload file size for Nginx, default to 0: unlimited - USE_NGINX_MAX_UPLOAD=${NGINX_MAX_UPLOAD:-0} - - # Get the number of workers for Nginx, default to 1 - USE_NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-1} - - # Set the max number of connections per worker for Nginx, if requested - # Cannot exceed worker_rlimit_nofile, see NGINX_WORKER_OPEN_FILES below - NGINX_WORKER_CONNECTIONS=${NGINX_WORKER_CONNECTIONS:-1024} - - # Hide Nginx server version on error pages and in the “Server HTTP” response header field - NGINX_SERVER_TOKENS=${NGINX_SERVER_TOKENS:-off} - - # Get the listen port for Nginx, default to 80 - USE_LISTEN_PORT=${LISTEN_PORT:-80} if [ -f /app/nginx.conf ]; then cp /app/nginx.conf /etc/nginx/nginx.conf else - content='user nginx;\n' - # Set the number of worker processes in Nginx - content=$content"worker_processes ${USE_NGINX_WORKER_PROCESSES};\n" - content=$content'error_log /var/log/nginx/error.log warn;\n' - content=$content'pid /var/run/nginx.pid;\n' - content=$content'events {\n' - content=$content" worker_connections ${NGINX_WORKER_CONNECTIONS};\n" - content=$content'}\n' - content=$content'http {\n' - content=$content' include /etc/nginx/mime.types;\n' - content=$content' default_type application/octet-stream;\n' - content=$content' log_format main '"'\$remote_addr - \$remote_user [\$time_local] \"\$request\" '\n" - content=$content' '"'\$status \$body_bytes_sent \"\$http_referer\" '\n" - content=$content' '"'\"\$http_user_agent\" \"\$http_x_forwarded_for\"';\n" - content=$content' access_log /var/log/nginx/access.log main;\n' - content=$content' sendfile on;\n' - content=$content' keepalive_timeout 65;\n' - content=$content" server_tokens ${NGINX_SERVER_TOKENS};\n" - content=$content' include /etc/nginx/conf.d/*.conf;\n' - content=$content'}\n' - content=$content'daemon off;\n' - # Set the max number of open file descriptors for Nginx workers, if requested - if [ -n "${NGINX_WORKER_OPEN_FILES}" ] ; then - content=$content"worker_rlimit_nofile ${NGINX_WORKER_OPEN_FILES};\n" - fi - # Save generated /etc/nginx/nginx.conf - printf "$content" > /etc/nginx/nginx.conf - - content_server='server {\n' - content_server=$content_server" listen ${USE_LISTEN_PORT};\n" - content_server=$content_server' location / {\n' - content_server=$content_server' include uwsgi_params;\n' - content_server=$content_server' uwsgi_pass unix:///tmp/uwsgi.sock;\n' - content_server=$content_server' }\n' - content_server=$content_server'}\n' - # Save generated server /etc/nginx/conf.d/nginx.conf - printf "$content_server" > /etc/nginx/conf.d/nginx.conf - - # Generate Nginx config for maximum upload file size - printf "client_max_body_size $USE_NGINX_MAX_UPLOAD;\n" > /etc/nginx/conf.d/upload.conf - - # Remove default Nginx config from Alpine - printf "" > /etc/nginx/conf.d/default.conf + envsubst < /etc/nginx/templates/nginx.conf.template > /etc/nginx/nginx.conf + envsubst < /etc/nginx/templates/pi.conf.template > /etc/nginx/conf.d/pi.conf fi } diff --git a/scripts/privacyidea_entrypoint.sh b/scripts/privacyidea_entrypoint.sh index 2f82f6d..45c3cc2 100644 --- a/scripts/privacyidea_entrypoint.sh +++ b/scripts/privacyidea_entrypoint.sh @@ -4,14 +4,14 @@ source /usr/local/bin/_privacyidea_common.sh function main { echo "[PrivacyIDEA] To SSH into this container, run: \"docker exec -it ${HOSTNAME} /bin/bash\"." - echo "" + echo "" if [ -d /etc/privacyidea/mount ] - then - PI_MOUNT_DIR=/etc/privacyidea/mount - else - PI_MOUNT_DIR=/mnt/privacyidea - fi + then + PI_MOUNT_DIR=/etc/privacyidea/mount + else + PI_MOUNT_DIR=/mnt/privacyidea + fi export PI_MOUNT_DIR diff --git a/scripts/start_privacyidea.sh b/scripts/start_privacyidea.sh index 82a1dd5..9410eb8 100644 --- a/scripts/start_privacyidea.sh +++ b/scripts/start_privacyidea.sh @@ -8,11 +8,45 @@ function main { 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 } +function generate_pi_config { + + if { [ "${DB_VENDOR}" = "mariadb" ] || [ "${DB_VENDOR}" = "mysql" ]; } then + echo "Using $DB_VENDOR..." + [ -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 + export SQLALCHEMY_DATABASE_URI=pymysql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME} + elif { [ "${DB_VENDOR}" = "postgresql" ]; } then + [ -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 + export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://${DB_USER}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME} + else + echo "DB_VENDOR enviroment varaible is not set. Using default SQLite..." + echo "" + export SQLALCHEMY_DATABASE_URI=sqlite:////etc/privacyidea/data/privacyidea.db + fi + + if [ ! -f /etc/privacyidea/pi.cfg ]; + then + if [ -z "$SQLALCHEMY_DATABASE_URI" ]; + then + echo "SQLALCHEMY_DATABASE_URI is undefieded" + else + envsubst < /etc/privacyidea/pi-config.template > /etc/privacyidea/pi.cfg + fi + fi +} + function prestart_privacyidea { + if [ -d "${PI_MOUNT_DIR}"/files ] then if [[ $(ls -A "${PI_MOUNT_DIR}"/files) ]] @@ -30,30 +64,18 @@ function prestart_privacyidea { echo "" fi else - echo "[privacyIDEA] The directory /mnt/konakart/files does not exist. Create the directory \$(pwd)/xyz123/files on the host operating system to create the directory ${PI_MOUNT_DIR}/files on the container. Files in ${PI_MOUNT_DIR}/files will be copied to ${PI_HOME} before privacyIDEA starts." + echo "[privacyIDEA] The directory /mnt/privacyidea/files does not exist. Create the directory \$(pwd)/xyz123/files on the host operating system to create the directory ${PI_MOUNT_DIR}/files on the container. Files in ${PI_MOUNT_DIR}/files will be copied to ${PI_HOME} before privacyIDEA starts." echo "" - fi + fi if [ -d "${PI_MOUNT_DIR}"/scripts ] then execute_scripts "${PI_MOUNT_DIR}"/scripts else - echo "[privacyIDEA] The directory /mnt/konakart/scripts does not exist. Create the directory \$(pwd)/xyz123/scripts on the host operating system to create the directory ${PI_MOUNT_DIR}/scripts on the container. Files in ${PI_MOUNT_DIR}/scripts will be executed, in alphabetical order, before privacyIDEA starts." + echo "[privacyIDEA] The directory /mnt/privacyidea/scripts does not exist. Create the directory \$(pwd)/xyz123/scripts on the host operating system to create the directory ${PI_MOUNT_DIR}/scripts on the container. Files in ${PI_MOUNT_DIR}/scripts will be executed, in alphabetical order, before privacyIDEA starts." echo "" fi - if { [ "${DB_VENDOR}" = "mariadb" ] || [ "${DB_VENDOR}" = "mysql" ]; } then - echo "Using $DB_VENDOR..." - [ -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 - export SQLALCHEMY_DATABASE_URI=pymysql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME} - elif { [ "${DB_VENDOR}" = "postgresql" ]; } then - export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://${DB_USER}:${DB_PASSWORD}@${DB_HOST}/${DB_NAME} - else - echo "DB_VENDOR enviroment varaible is not set. Using default SQLite..." - fi if [ "${PI_SKIP_BOOTSTRAP}" = false ]; then if [ ! -f /etc/privacyidea/encfile ]; then pi-manage create_enckey @@ -66,7 +88,6 @@ function prestart_privacyidea { fi pi-manage createdb pi-manage db stamp head -d /opt/privacyidea/lib/privacyidea/migrations/ - #pi-manage db stamp head -d /usr/local/lib/privacyidea/migrations/ if { [ "${PI_SKIP_BOOTSTRAP}" = false ] && [ -z ${PI_ADMIN_USER} ] && [ -z ${PI_ADMIN_PASSWORD} ]; } then echo "Create deafult admin user. Not recommented in production. Please set PI_ADMIN_USER and PI_ADMIN_PASSWORD in production enviroment." pi-manage admin add admin -p privacyidea