From 237ea992f2597c036ec39787dfdf2c955345cb86 Mon Sep 17 00:00:00 2001 From: Marko Bocevski Date: Tue, 9 May 2017 18:22:04 +0200 Subject: [PATCH] Migrate from gunicorn to uwsgi and remove nginx dependency for http basicauth --- rootfs/Dockerfile | 28 ++++++++++++++-------- rootfs/setup/{ => app}/prerun.py | 0 rootfs/setup/app/start_ckan.sh | 29 ++++++++++++++++++++++ rootfs/setup/app/uwsgi.conf | 2 ++ rootfs/setup/nginx.conf | 41 -------------------------------- rootfs/setup/start_ckan.sh | 22 ----------------- 6 files changed, 49 insertions(+), 73 deletions(-) rename rootfs/setup/{ => app}/prerun.py (100%) create mode 100755 rootfs/setup/app/start_ckan.sh create mode 100644 rootfs/setup/app/uwsgi.conf delete mode 100644 rootfs/setup/nginx.conf delete mode 100755 rootfs/setup/start_ckan.sh diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile index def0b6a..f9073e7 100644 --- a/rootfs/Dockerfile +++ b/rootfs/Dockerfile @@ -1,6 +1,6 @@ -FROM keitaro/base:0.1 +FROM keitaro/base:0.2 -MAINTAINER Keitaro Inc +MAINTAINER Keitaro Inc ENV APP_DIR=/srv/app ENV SRC_DIR=/srv/app/src @@ -15,16 +15,19 @@ WORKDIR ${APP_DIR} ######################### ### Base docker layer ### ######################### +# Create a local user and group to run the app +RUN addgroup -g 92 -S ckan && \ + adduser -u 92 -h /srv/app -H -D -S -G ckan ckan # Install necessary packages to run CKAN RUN apk add --no-cache git \ gettext \ postgresql-client \ python \ - nginx \ apache2-utils && \ # Packages to build CKAN requirements and plugins apk add --no-cache --virtual .build-deps \ postgresql-dev \ + linux-headers \ gcc \ make \ g++ \ @@ -32,15 +35,14 @@ RUN apk add --no-cache git \ automake \ libtool \ musl-dev \ + pcre-dev \ python-dev && \ # Create SRC_DIR mkdir -p ${SRC_DIR} && \ - # Create nginx run dir - mkdir -p /run/nginx && \ - # Install pip and gunicorn + # Install pip and uwsgi curl -o ${SRC_DIR}/get-pip.py https://bootstrap.pypa.io/get-pip.py && \ python ${SRC_DIR}/get-pip.py && \ - pip install gunicorn gevent && \ + pip install --no-cache-dir uwsgi gevent && \ rm -rf ${SRC_DIR}/get-pip.py ############################ @@ -64,15 +66,21 @@ RUN pip install -e git+${GIT_URL}@${GIT_BRANCH}#egg=ckan && \ cp who.ini ${APP_DIR} && \ pip install -r requirements.txt && \ # Install CKAN envvars to support loading config from environment variables - pip install -e git+https://github.com/okfn/ckanext-envvars.git#egg=ckanext-envvars && \ + pip install -e git+https://github.com/okfn/ckanext-envvars.git@0.0.1#egg=ckanext-envvars && \ # Create and update CKAN config paster --plugin=ckan make-config ckan ${APP_DIR}/production.ini && \ - paster --plugin=ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" + paster --plugin=ckan config-tool ${APP_DIR}/production.ini "ckan.plugins = ${CKAN__PLUGINS}" && \ + # Change ownership to app user + chown -R ckan:ckan /srv/app && \ + # Clear the .git directory + rm -rf /srv/app/src/ckan/.git -COPY setup ${APP_DIR} +COPY setup/app ${APP_DIR} EXPOSE 5000 HEALTHCHECK --interval=10s --timeout=5s --retries=5 CMD curl --fail http://localhost:5000/api/3/action/status_show || exit 1 +USER ckan + CMD ["/srv/app/start_ckan.sh"] diff --git a/rootfs/setup/prerun.py b/rootfs/setup/app/prerun.py similarity index 100% rename from rootfs/setup/prerun.py rename to rootfs/setup/app/prerun.py diff --git a/rootfs/setup/app/start_ckan.sh b/rootfs/setup/app/start_ckan.sh new file mode 100755 index 0000000..d9fb405 --- /dev/null +++ b/rootfs/setup/app/start_ckan.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Run the prerun script to init CKAN and create the default admin user +python prerun.py + +# Set the common uwsgi options +UWSGI_OPTS="--socket /tmp/uwsgi.sock --thunder-lock --uid 92 --gid 92 --http :5000 --master --single-interpreter --enable-threads --paste config:/srv/app/production.ini --gevent 2000 -p 4 -L" + +# Check whether http basic auth password protection is enabled and enable basicauth routing on uwsgi respecfully +if [ $? -eq 0 ] +then + if [ "$PASSWORD_PROTECT" = true ] + then + if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ] + then + # Generate htpasswd file for basicauth + htpasswd -d -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD + # Start uwsgi with basicauth + uwsgi --ini /srv/app/uwsgi.conf --pcre-jit $UWSGI_OPTS + else + echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..." + exit 1 + fi + else + # Start uwsgi + uwsgi $UWSGI_OPTS + fi +else + echo "[prerun] failed...not starting CKAN." +fi diff --git a/rootfs/setup/app/uwsgi.conf b/rootfs/setup/app/uwsgi.conf new file mode 100644 index 0000000..6321d6d --- /dev/null +++ b/rootfs/setup/app/uwsgi.conf @@ -0,0 +1,2 @@ +[uwsgi] +route = ^(?!/api).*$ basicauth:Restricted,/srv/app/.htpasswd diff --git a/rootfs/setup/nginx.conf b/rootfs/setup/nginx.conf deleted file mode 100644 index ca21636..0000000 --- a/rootfs/setup/nginx.conf +++ /dev/null @@ -1,41 +0,0 @@ -worker_processes 4; - -events { - worker_connections 1024; -} - -http { - include mime.types; - default_type application/octet-stream; - - sendfile on; - client_max_body_size 100m; - keepalive_timeout 65; - - server { - listen 5000; - server_name localhost; - - auth_basic "Restricted"; - auth_basic_user_file /srv/app/.htpasswd; - - location / { - auth_basic "Restricted"; - auth_basic_user_file /srv/app/.htpasswd; - proxy_pass http://127.0.0.1:4000/; - proxy_redirect off; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - } - - location /api/3/action/status_show { - auth_basic "off"; - proxy_pass http://127.0.0.1:4000/api/3/action/status_show; - proxy_redirect off; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - } - } -} diff --git a/rootfs/setup/start_ckan.sh b/rootfs/setup/start_ckan.sh deleted file mode 100755 index 4c76d16..0000000 --- a/rootfs/setup/start_ckan.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -python prerun.py -if [ $? -eq 0 ] -then - if [ "$PASSWORD_PROTECT" = true ] - then - if [ "$HTPASSWD_USER" ] || [ "$HTPASSWD_PASSWORD" ] - then - cp -a /srv/app/nginx.conf /etc/nginx/nginx.conf - htpasswd -b -c /srv/app/.htpasswd $HTPASSWD_USER $HTPASSWD_PASSWORD - nginx - gunicorn --log-file=- -k gevent -w 4 -b 127.0.0.1:4000 --paste production.ini - else - echo "Missing HTPASSWD_USER or HTPASSWD_PASSWORD environment variables. Exiting..." - exit 1 - fi - else - gunicorn --log-file=- -k gevent -w 4 -b 0.0.0.0:5000 --paste production.ini - fi -else - echo "[prerun] failed...not starting CKAN." -fi