diff --git a/cts.sh b/cts.sh index df4ebcd..d53cf2e 100755 --- a/cts.sh +++ b/cts.sh @@ -1,65 +1,48 @@ -#!/bin/bash +#!/bin/sh SOURCE_DIR=$(realpath $(dirname "${0}"))/cts -# Install packages -apt-get -y --no-install-recommends install build-essential libpq-dev python-dev python-virtualenv virtualenv zlib1g-dev - -# Clone CTS git repository -git clone --depth 1 https://github.com/theirc/CTS /srv/cts - -# Install CTS python virtual environment -virtualenv --no-site-packages --python=/usr/bin/python2.7 /srv/cts -/srv/cts/bin/pip install -r /srv/cts/requirements/production.txt +# Build Docker container +docker build -t cts ${SOURCE_DIR} # Create database export CTS_PWD=$(head -c 18 /dev/urandom | base64) -envsubst <${SOURCE_DIR}/tmp/cts-createdb.sql >/tmp/cts-createdb.sql -sudo -u postgres psql -f /tmp/cts-createdb.sql -rm -f /tmp/cts-createdb.sql +envsubst <${SOURCE_DIR}/createdb.sql | docker exec -i postgres psql + +# Copy existing config files into persistent storage +mkdir -p /srv/cts/conf +chown 8006:8006 /srv/cts/conf +docker run --rm -v /srv/cts/conf:/mnt/conf cts cp -rp /srv/cts/cts/settings/. /mnt/conf +chown -R root:root /srv/cts/conf # Configure CTS export CTS_SECRET=$(head -c 26 /dev/urandom | base64) -envsubst <${SOURCE_DIR}/srv/cts/cts/settings/spotter.py >/srv/cts/cts/settings/spotter.py -ln -s /srv/cts/lib/python2.7/site-packages/django/contrib/admin/static/admin /srv/cts/cts/static/admin -ln -s /srv/cts/lib/python2.7/site-packages/django_extensions/static/django_extensions /srv/cts/cts/static/django_extensions -ln -s /srv/cts/lib/python2.7/site-packages/django_tables2/static/django_tables2 /srv/cts/cts/static/django_tables2 -ln -s /srv/cts/lib/python2.7/site-packages/leaflet/static/leaflet /srv/cts/cts/static/leaflet -ln -s /srv/cts/lib/python2.7/site-packages/rest_framework/static/rest_framework /srv/cts/cts/static/rest_framework -ln -s /srv/cts/lib/python2.7/site-packages/rest_framework_swagger/static/rest_framework_swagger /srv/cts/cts/static/rest_framework_swagger -ln -s /srv/cts/lib/python2.7/site-packages/selectable/static/selectable /srv/cts/cts/static/selectable -ln -s /srv/cts/lib/python2.7/site-packages/session_security/static/session_security /srv/cts/cts/static/session_security +envsubst <${SOURCE_DIR}/srv/cts/conf/spotter.py >/srv/cts/conf/spotter.py # Set "production values" (increases performance) only if the DEBUG environment variable is not set if [ ${DEBUG:-0} -eq 0 ]; then - sed -i 's/DEBUG = True/DEBUG = False/' /srv/cts/cts/settings/spotter.py + sed -i 's/DEBUG = True/DEBUG = False/' /srv/cts/conf/spotter.py fi # Populate database -DJANGO_SETTINGS_MODULE=cts.settings.spotter /srv/cts/bin/python /srv/cts/manage.py migrate +docker run --rm --link=postgres -v /srv/cts/conf:/srv/cts/cts/settings cts manage.py migrate # Create admin account export CTS_ADMIN_EMAIL=admin@example.com export CTS_ADMIN_PWD=$(head -c 12 /dev/urandom | base64) -export CTS_ADMIN_HASH=$(cd /srv/cts && DJANGO_SETTINGS_MODULE=cts.settings.spotter /srv/cts/bin/python -c "from django.contrib.auth.hashers import make_password; print make_password('${CTS_ADMIN_PWD}')") +export CTS_ADMIN_HASH=$(docker run --rm -v /srv/cts/conf:/srv/cts/cts/settings cts python -c "from django.contrib.auth.hashers import make_password; print make_password('${CTS_ADMIN_PWD}')") export CTS_ADMIN_SECRET=$(head -c 12 /dev/urandom | sha256sum | cut -c1-13) -envsubst <${SOURCE_DIR}/tmp/cts-adminpwd.sql >/tmp/cts-adminpwd.sql -sudo -u postgres psql -f /tmp/cts-adminpwd.sql cts -rm -f /tmp/cts-adminpwd.sql +envsubst <${SOURCE_DIR}/adminpwd.sql | docker exec -i postgres psql cts -# Create CTS OS user -adduser --system --group --home /srv/cts --shell /bin/false cts -chown -R cts:cts /srv/cts +# Create CTS service +cp ${SOURCE_DIR}/etc/init.d/cts /etc/init.d/cts +rc-update add cts boot +service cts start -# Create uwsgi and nginx app definition -cp ${SOURCE_DIR}/etc/uwsgi/apps-available/cts.ini /etc/uwsgi/apps-available/cts.ini -ln -s /etc/uwsgi/apps-available/cts.ini /etc/uwsgi/apps-enabled/cts.ini -cp ${SOURCE_DIR}/etc/nginx/sites-available/cts /etc/nginx/sites-available/cts -ln -s /etc/nginx/sites-available/cts /etc/nginx/sites-enabled/cts - -# Restart services -systemctl restart uwsgi -systemctl restart nginx +# Create nginx app definition +cp ${SOURCE_DIR}/etc/nginx/apps/cts /etc/nginx/apps/cts +cp ${SOURCE_DIR}/etc/nginx/conf.d/cts.conf /etc/nginx/conf.d/cts.conf +service nginx reload # Add portal application definition -portal-app-manager cts "https://{host}:8004/" "${CTS_ADMIN_EMAIL}" "${CTS_ADMIN_PWD}" +portal-app-manager cts "https://{host}:8406/" "${CTS_ADMIN_EMAIL}" "${CTS_ADMIN_PWD}" diff --git a/cts/Dockerfile b/cts/Dockerfile new file mode 100644 index 0000000..3faaec2 --- /dev/null +++ b/cts/Dockerfile @@ -0,0 +1,42 @@ +FROM alpine:3.7 +MAINTAINER Disassembler + +RUN \ + # Install Python2 runtime + apk --no-cache add python2 + +RUN \ + # Install runtime dependencies + apk --no-cache add libpq zlib \ + # Install build dependencies + && apk --no-cache add --virtual .deps git build-base postgresql-dev python2-dev py2-pip zlib-dev \ + # Add edge/testing repository for postgis (geos) support + && echo 'http://repository.fit.cvut.cz/mirrors/alpine/edge/testing' >>/etc/apk/repositories \ + && apk --no-cache add geos \ + # Install CTS + && git clone --depth 1 https://github.com/theirc/CTS /srv/cts \ + # Force psycopg2 version update for compatibility with PostgreSQL 10 + && sed -i 's/psycopg2==2.5.2/psycopg2==2.7.1/' /srv/cts/requirements/base.txt \ + && pip install -r /srv/cts/requirements/production.txt \ + # Hackfix geos version detection + && sed -i 's/\$//' /usr/lib/python2.7/site-packages/django/contrib/gis/geos/libgeos.py \ + # Make manage.py globally executable + && chmod +x /srv/cts/manage.py \ + && ln -s /srv/cts/manage.py /usr/local/bin/manage.py \ + # Create OS user + && addgroup -S -g 8006 cts \ + && adduser -S -u 8006 -h /srv/cts -s /bin/false -g cts -G cts cts \ + && chown -R cts:cts /srv/cts \ + # Cleanup + && apk del .deps \ + && find /srv/cts -name '.git*' -exec rm -rf {} + \ + && rm -rf /root \ + && mkdir /root + +VOLUME ["/srv/cts/cts/settings"] +EXPOSE 8006 + +USER cts +ENV DJANGO_SETTINGS_MODULE cts.settings.spotter +WORKDIR /srv/cts +CMD ["manage.py", "runserver", "0.0.0.0:8006"] diff --git a/cts/tmp/cts-adminpwd.sql b/cts/adminpwd.sql similarity index 100% rename from cts/tmp/cts-adminpwd.sql rename to cts/adminpwd.sql diff --git a/cts/tmp/cts-createdb.sql b/cts/createdb.sql similarity index 100% rename from cts/tmp/cts-createdb.sql rename to cts/createdb.sql diff --git a/cts/etc/init.d/cts b/cts/etc/init.d/cts new file mode 100755 index 0000000..249d081 --- /dev/null +++ b/cts/etc/init.d/cts @@ -0,0 +1,17 @@ +#!/sbin/openrc-run + +description="CTS docker container" + +depend() { + need docker net + use dns logger netmount + after postgres +} + +start() { + /usr/bin/docker run -d --rm --name cts --link=postgres -p 127.0.0.1:9006:8006 -v /srv/cts/conf:/srv/cts/cts/settings cts +} + +stop() { + /usr/bin/docker stop cts +} diff --git a/cts/etc/nginx/apps/cts b/cts/etc/nginx/apps/cts new file mode 100644 index 0000000..211fd9f --- /dev/null +++ b/cts/etc/nginx/apps/cts @@ -0,0 +1,9 @@ +access_log /var/log/nginx/cts.access.log; +error_log /var/log/nginx/cts.error.log; + +location / { + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Host $host:$server_port; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://127.0.0.1:9006; +} diff --git a/cts/etc/nginx/conf.d/cts.conf b/cts/etc/nginx/conf.d/cts.conf new file mode 100644 index 0000000..590f57c --- /dev/null +++ b/cts/etc/nginx/conf.d/cts.conf @@ -0,0 +1,11 @@ +server { + listen 8006; + listen [::]:8006; + include apps/cts; +} + +server { + listen 8406 ssl http2; + listen [::]:8406 ssl http2; + include apps/cts; +} diff --git a/cts/etc/nginx/sites-available/cts b/cts/etc/nginx/sites-available/cts deleted file mode 100644 index 3b116a8..0000000 --- a/cts/etc/nginx/sites-available/cts +++ /dev/null @@ -1,44 +0,0 @@ -server { - listen 8004 ssl http2; - listen [::]:8004 ssl http2; - - root /srv/cts/cts; - - access_log /var/log/nginx/cts.access.log; - error_log /var/log/nginx/cts.error.log; - - location /robots.txt { - alias /srv/cts/cts/static/robots.txt; - } - - location /media { - alias /srv/cts/cts/media; - } - - location /static { - gzip on; - alias /srv/cts/cts/static; - expires max; - add_header Cache-Control public; - - location /static/protected { - return 401; - } - } - - location /protected { - internal; - root /srv/cts/cts/static; - } - - error_page 502 503 504 /502.html; - - location /502.html { - alias /srv/cts/cts/static/502.html; - } - - location / { - uwsgi_pass unix:///run/uwsgi/app/cts/socket; - include uwsgi_params; - } -} diff --git a/cts/etc/uwsgi/apps-available/cts.ini b/cts/etc/uwsgi/apps-available/cts.ini deleted file mode 100644 index a895e93..0000000 --- a/cts/etc/uwsgi/apps-available/cts.ini +++ /dev/null @@ -1,9 +0,0 @@ -[uwsgi] -uid = cts -gid = cts -chown-socket = www-data:www-data -chdir = /srv/cts -home = /srv/cts -disable-logging = true -module = cts.wsgi:application -env = DJANGO_SETTINGS_MODULE=cts.settings.spotter diff --git a/cts/srv/cts/cts/settings/spotter.py b/cts/srv/cts/conf/spotter.py similarity index 94% rename from cts/srv/cts/cts/settings/spotter.py rename to cts/srv/cts/conf/spotter.py index c4c983f..fdd9143 100644 --- a/cts/srv/cts/cts/settings/spotter.py +++ b/cts/srv/cts/conf/spotter.py @@ -18,8 +18,8 @@ DATABASES = { 'NAME': 'cts', 'USER': 'cts', 'PASSWORD': '${CTS_PWD}', - 'HOST': '', - 'PORT': '', + 'HOST': 'postgres', + 'PORT': '5432', } } SECRET_KEY = '${CTS_SECRET}'