Skip to content

Commit

Permalink
Project improvement
Browse files Browse the repository at this point in the history
  - revamp project structure for easy manage
  - add SSL support
  - add DB_PORT for support non standard port
  - update README to address new changes
  • Loading branch information
mr-ssd authored and Sida Say committed Jun 29, 2022
1 parent 61f04c4 commit 07983da
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 73 deletions.
58 changes: 18 additions & 40 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,22 @@ FROM python:3.8.13-bullseye

LABEL maintainer="Sida Say <sida.say@khalibre.com>"

ARG REQUIRED_PACKAGE="ca-certificates git supervisor gettext-base nginx"
COPY prebuildfs /

RUN set -xe; \
apt-get -y update && \
apt-get install -y ${REQUIRED_PACKAGE}
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN install_packages ca-certificates git supervisor gettext-base nginx

RUN mkdir -p mkdir /etc/privacyidea/data/keys \
/opt/privacyidea \
/var/log/privacyidea && \
adduser --gecos "PrivacyIdea User" --disabled-password --home /home/privacyidea privacyidea --uid 1001 && \
addgroup privacyidea privacyidea && \
usermod -g 1001 privacyidea && \
chown -R privacyidea:privacyidea /opt/privacyidea /etc/privacyidea /var/log/privacyidea
chown -R privacyidea:privacyidea /etc/privacyidea /var/log/privacyidea

# apt-get remove --purge --auto-remove -y ca-certificates && rm -rf /var/lib/apt/lists/*

# COPY PI configuration
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

COPY --chown=privacyidea:privacyidea ./configs/app /app

COPY scripts/* /usr/local/bin/

RUN chmod +x /usr/local/bin/*.sh \
&& apt-get clean autoclean \
&& apt-get autoremove --yes \
&& rm -rf /var/lib/{apt,dpkg,cache,log}/ \
&& rm -rf /tmp/*
COPY rootfs /

# Which uWSGI .ini file should be used, to make it customizable
ENV UWSGI_INI /app/uwsgi.ini
ENV UWSGI_INI /etc/uwsgi/uwsgi.ini

# By default, run 2 processes
ENV UWSGI_CHEAPER 2
Expand All @@ -68,28 +42,32 @@ 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
ENV NGINX_LISTEN_PORT 80
ENV NGINX_LISTEN_SSL_PORT 443

ENV NGINX_SSL_ENABLED true

ENV PI_SKIP_BOOTSTRAP=false \
DB_VENDOR=sqlite \
PI_HOME=/opt/privacyidea

ARG PI_VERSION=3.7.1
PI_HOME=/opt/privacyidea \
VIRTUAL_ENV=/opt/privacyidea

ENV VIRTUAL_ENV=/opt/privacyidea
RUN python3 -m venv $VIRTUAL_ENV

ENV PATH="$VIRTUAL_ENV/bin:$PATH"

ARG PI_VERSION=3.7.1

RUN pip3 install wheel && \
pip3 install supervisor uwsgi pymysql-sa PyMySQL psycopg2-binary && \
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}

EXPOSE 80/tcp
EXPOSE 443/tcp


ENTRYPOINT ["/usr/local/bin/privacyidea_entrypoint.sh"]

WORKDIR /app
WORKDIR /opt/privacyidea

VOLUME [ "/data/privacyidea" ]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ push:
docker push michimau/privacyidea

run: cleanup create_volume secretkey pipepper
docker run -v $(LOCAL_DATA_VOLUME):/data/privacyidea -p 80:80 -ti --name=privacyidea-dev --env-file=secretkey --env-file=pipepper khalibre/privacyidea:dev
docker run -p 80:80 -p 443:443 -ti --name=privacyidea-dev --env-file=secretkey --env-file=pipepper khalibre/privacyidea:dev

create_volume:
mkdir $(LOCAL_DATA_VOLUME)
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# PrivacyIdea Docker Image

This is a build environment to build a docker image for privacyIDEA base on [official NGINX image](https://hub.docker.com/_/nginx) and [PrivacyIDEA](https://github.com/privacyidea/privacyidea)
This is a build environment to build a docker image for privacyIDEA base on [official Python image](https://hub.docker.com/_/python) and [PrivacyIDEA](https://github.com/privacyidea/privacyidea)

**Disclaimer**: The respective trademarks mentioned in the offering are owned by the respective companies. We do not provide commercial license of any of these products. This listing has an open source license. privacyIDEA is run and maintained by NetKnights, that is a completely and separate project from Khalibre.

## The image
The docker image is a self contained Debain with privacyIDEA installed, which will run on every distribution.
The docker image is a self contained Debain with privacyIDEA and NGINX installed, which will run on every distribution.

## Building

Expand Down Expand Up @@ -40,19 +40,23 @@ The Khalibre privacyIDEA container can create a default admin user by setting th

The Khalibre privacyIDEA requires a database to work. This is configured with the following environment variables:

- `DB_VENDOR`: Database vendor (support mysql or posgresql) No defaults.
- `DB_VENDOR`: Database vendor (support mysql, mariadb or posgresql) No defaults.
- `DB_USER`: Database user. No defaults.
- `DB_PASSWORD`: Database. No defaults.
- `DB_NAME`: Database name. No defaults.
- `DB_HOST`: Database host. No defaults.

### NGINX configuration

- `NGINX_LISTEN_PORT`: Get the listen port for Nginx, default to 80
- `NGINX_LISTEN_SSL_PORT`: Get the secured listen port for Nginx, default to 443
- `NGINX_MAX_UPLOAD`: Get the maximum upload file size for Nginx, default to 100Mb
- `NGINX_WORKER_PROCESSES`: Get the number of workers for Nginx, default to 1
- `NGINX_WORKER_CONNECTIONS`: Set the max number of connections per worker for Nginx, if requested.
- `NGINX_SERVER_TOKENS`: Hide Nginx server version on error pages and in the “Server HTTP” response header field
- `USE_LISTEN_PORT`: Get the listen port for Nginx, default to 80
- `NGINX_SSL_CERT`: Path to SSL certificate, default to **/etc/nginx/certs/pi-server-cert.pem**
- `NGINX_SSL_ENABLED`: Set to true to enable SSL, default **false**
- `NGINX_SSL_KEY`: Path to SSL key, default **/etc/nginx/certs/pi-server-key.pem**
- `NGINX_WORKER_CONNECTIONS`: Set the max number of connections per worker for Nginx, if requested.
- `NGINX_WORKER_PROCESSES`: Get the number of workers for Nginx, default to 1

### privacyIDEA configuration

Expand Down
3 changes: 0 additions & 3 deletions configs/app/uwsgi.ini

This file was deleted.

24 changes: 24 additions & 0 deletions prebuildfs/usr/sbin/install_packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh
set -e
set -u
export DEBIAN_FRONTEND=noninteractive
n=0
max=2
until [ $n -gt $max ]; do
set +e
(
apt-get update -qq &&
apt-get install -y --no-install-recommends "$@"
)
CODE=$?
set -e
if [ $CODE -eq 0 ]; then
break
fi
if [ $n -eq $max ]; then
exit $CODE
fi
echo "apt failed, retrying"
n=$(($n + 1))
done
rm -r /var/lib/apt/lists /var/cache/apt/archives
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[supervisord]
nodaemon=true
user=root

[program:uwsgi]
command=/opt/privacyidea/bin/uwsgi --ini /etc/uwsgi/uwsgi.ini
Expand Down
4 changes: 3 additions & 1 deletion configs/uwsgi.ini → rootfs/etc/uwsgi/uwsgi.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[uwsgi]
wsgi-file=/opt/privacyidea/etc/privacyidea/privacyideaapp.wsgi
buffer-size=8192
socket = /tmp/uwsgi.sock
chown-socket = nginx:nginx
chown-socket = www-data:www-data
chmod-socket = 664
# Graceful shutdown on SIGTERM, see https://github.com/unbit/uwsgi/issues/849#issuecomment-118869386
hook-master-start = unix_signal:15 gracefully_kill_them_all
Expand Down
22 changes: 22 additions & 0 deletions rootfs/opt/templates/nginx-pi-ssl.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
server {
listen $NGINX_LISTEN_SSL_PORT ssl;
listen [::]:$NGINX_LISTEN_SSL_PORT ssl;

ssl_certificate $NGINX_SSL_CERT;
ssl_certificate_key $NGINX_SSL_KEY;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

proxy_http_version 1.1;

client_max_body_size $NGINX_MAX_UPLOAD;
location / {

include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
server {
listen $LISTEN_PORT;
listen [::]:$LISTEN_PORT;
listen $NGINX_LISTEN_PORT;
listen [::]:$NGINX_LISTEN_PORT;

client_max_body_size $NGINX_MAX_UPLOAD;
proxy_http_version 1.1;
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
user nginx;
user www-data;
worker_processes $NGINX_WORKER_PROCESSES;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
Expand Down
File renamed without changes.
File renamed without changes.
97 changes: 97 additions & 0 deletions rootfs/usr/local/bin/configure_nginx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/bin/bash

set -e

function main {

envsubst < /opt/templates/nginx.conf.template > /etc/nginx/nginx.conf
envsubst < /opt/templates/nginx-pi.conf.template > /etc/nginx/conf.d/pi.conf
if [ "$NGINX_SSL_ENABLED" = true ]; then
if [ -z "$NGINX_SSL_CERT" ] && [ -z "$NGINX_SSL_CERT" ];
then
echo "SSL enabled but NGINX_SSL_CERT and NGINX_SSL_KEY are not defined, using generated certifiacate"
echo "Generate self signed certificate"
generate_cert
echo ""
echo "Finished generate certificates"

export NGINX_SSL_CERT=/etc/nginx/certs/pi-server-cert.pem
export NGINX_SSL_KEY=/etc/nginx/certs/pi-server-key.pem
fi
envsubst < /opt/templates/nginx-pi-ssl.conf.template > /etc/nginx/conf.d/pi-ssl.conf
fi

}

function generate_cert {

# Create certificate directory
mkdir -p /etc/nginx/certs

# [ global parameters ]
# certificate configuration
readonly CERT_DAYS=36500
readonly RSA_STR_LEN=4096
readonly PREFIX=pi-
readonly CERT_DIR=/etc/nginx/certs
readonly KEY_DIR=/etc/nginx/certs
# certificate content definition
readonly ADDRESS_COUNTRY_CODE=KH
readonly ADDRESS_PREFECTURE=PI
readonly ADDRESS_CITY='Phnom Penh'
readonly COMPANY_NAME=Khalibre
readonly COMPANY_SECTION=DevOps
readonly CERT_PASSWORD= # no password
# - ca
readonly CA_DOMAIN='Khalibre DevOps'
readonly CA_EMAIL=ca@email.address
# - server
readonly SERVER_DOMAIN=localhost
readonly SERVER_EMAIL=server@email.address

# [ functions ]
echo_cert_params() {
local company_domain="$1"
local company_email="$2"

echo $ADDRESS_COUNTRY_CODE
echo $ADDRESS_PREFECTURE
echo $ADDRESS_CITY
echo $COMPANY_NAME
echo $COMPANY_SECTION
echo $company_domain
echo $company_email
echo $CERT_PASSWORD # password
echo $CERT_PASSWORD # password (again)
}
echo_ca_cert_params() {
echo_cert_params "$CA_DOMAIN" "$CA_EMAIL"
}
echo_server_cert_params() {
echo_cert_params "$SERVER_DOMAIN" "$SERVER_EMAIL"
}

# [ main ]
# generate certificates
# - ca
openssl genrsa $RSA_STR_LEN > $KEY_DIR/${PREFIX}ca-key.pem
echo_ca_cert_params | \
openssl req -new -x509 -nodes -days $CERT_DAYS -key $KEY_DIR/${PREFIX}ca-key.pem -out $CERT_DIR/${PREFIX}ca-cert.pem
# - server
echo_server_cert_params | \
openssl req -newkey rsa:$RSA_STR_LEN -days $CERT_DAYS -nodes -keyout $KEY_DIR/${PREFIX}server-key.pem -out $CERT_DIR/${PREFIX}server-req.pem
openssl rsa -in $KEY_DIR/${PREFIX}server-key.pem -out $KEY_DIR/${PREFIX}server-key.pem
openssl x509 -req -in $CERT_DIR/${PREFIX}server-req.pem -days $CERT_DAYS -CA $CERT_DIR/${PREFIX}ca-cert.pem -CAkey $KEY_DIR/${PREFIX}ca-key.pem -set_serial 01 -out $CERT_DIR/${PREFIX}server-cert.pem

# clean up (before permission changed)
rm $KEY_DIR/${PREFIX}ca-key.pem
rm $CERT_DIR/${PREFIX}server-req.pem

# validate permission
chmod 400 $KEY_DIR/${PREFIX}server-key.pem

# verify relationship among certificates
openssl verify -CAfile $CERT_DIR/${PREFIX}ca-cert.pem $CERT_DIR/${PREFIX}server-cert.pem
}

main
File renamed without changes.
16 changes: 13 additions & 3 deletions scripts/start_privacyidea.sh → rootfs/usr/local/bin/start_privacyidea.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@ function generate_pi_config {
[ -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}
if [ -z "$DB_PORT" ]; then
echo DB_PORT is not defined using default port
export DB_PORT=3306
fi
export SQLALCHEMY_DATABASE_URI=pymysql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${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}
if [ -z "$DB_PORT" ]; then
echo DB_PORT is not defined using default port
export DB_PORT=5432
fi
export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}
else
echo "DB_VENDOR enviroment varaible is not set. Using default SQLite..."
echo ""
Expand All @@ -40,7 +48,7 @@ function generate_pi_config {
then
echo "SQLALCHEMY_DATABASE_URI is undefieded"
else
envsubst < /etc/privacyidea/pi-config.template > /etc/privacyidea/pi.cfg
envsubst < /opt/templates/pi-config.template > /etc/privacyidea/pi.cfg
fi
fi
}
Expand Down Expand Up @@ -77,6 +85,8 @@ function prestart_privacyidea {
fi

if [ "${PI_SKIP_BOOTSTRAP}" = false ]; then
ls -l /data
ls -l /data/privacyidea
if [ ! -f /etc/privacyidea/encfile ]; then
pi-manage create_enckey
fi
Expand Down
15 changes: 0 additions & 15 deletions scripts/configure_nginx.sh

This file was deleted.

0 comments on commit 07983da

Please sign in to comment.