diff --git a/Dockerfile b/Dockerfile index 6f88a60..304e15f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,31 +3,31 @@ FROM fedora LABEL maintainer="Jens Kleineheismann " ARG APPLICATION_NAME=django-test -ARG APPLICATION_SRC=src/${APPLICATION_NAME} +ARG APPLICATION_SRC=src/django-test RUN dnf -y update && \ dnf -y install procps-ng iproute net-tools && \ dnf -y install httpd && \ + dnf -y install mod_ssl certbot && \ dnf -y install python3-mod_wsgi && \ dnf clean all -RUN chown apache: /etc/httpd/run && \ - setcap 'cap_net_bind_service=+ep' /usr/sbin/httpd && \ - sed -i -e 's:^\(\s.*\)\(CustomLog\s.*\)$:\1#\2:' \ - /etc/httpd/conf/httpd.conf +RUN sed -i -e 's:^\(\s.*\)\(CustomLog\s.*\)$:\1#\2:' \ + /etc/httpd/conf/httpd.conf COPY container-filesystem/ / -COPY ${APPLICATION_SRC} /srv/${APPLICATION_NAME}/src/${APPLICATION_NAME} +RUN echo 'test -f /etc/bashrc.local && source /etc/bashrc.local' >> /etc/bashrc -RUN ln -s ${APPLICATION_NAME} /srv/application && \ - /setup-application.sh /srv/${APPLICATION_NAME} \ - /srv/${APPLICATION_NAME}/src/${APPLICATION_NAME} && \ - rm /setup-application.sh +COPY src/django-test /srv/app/src +RUN /setup-app.sh /srv/app/src /srv/app/wsgi && \ + rm /setup-app.sh EXPOSE 80/tcp +EXPOSE 443/tcp +VOLUME /srv/etc ENV LOG_LEVEL error - -USER apache +ENV ENABLE_STATUS_ENDPOINTS false +ENV DJANGO_SYNCDB false ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["--"] diff --git a/Makefile b/Makefile index a6a9a5a..ff4a45b 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ APPLICATION_NAME := django-test -REPO_URL := https://heinzelwelt.de/vcs/python/django-test +REPO_URL := https://dev.heinzelwerk.de/git/python/django-test REPO_DIR := src/$(APPLICATION_NAME) IMAGE_NAME := $(APPLICATION_NAME) +IMAGE_LABEL := latest -HOST_PORT := 80 -CONTAINER_PORT := 80 +HTTP_HOST_PORT := 80 +HTTP_CONTAINER_PORT := 80 +HTTPS_HOST_PORT := 443 +HTTPS_CONTAINER_PORT := 443 DOCKER := docker DGOSS := dgoss @@ -21,18 +24,18 @@ $(REPO_DIR): $(GIT) clone $(REPO_URL) $@ $(IMAGE_NAME): $(REPO_DIR) - $(DOCKER) build --build-arg APPLICATION_NAME=$(APPLICATION_NAME) -t $(IMAGE_NAME) . + $(DOCKER) build --build-arg APPLICATION_NAME=$(APPLICATION_NAME) -t $(IMAGE_NAME):$(IMAGE_LABEL) . image: $(IMAGE_NAME) test: - $(DGOSS) run $(IMAGE_NAME) + $(DGOSS) run $(IMAGE_NAME):$(IMAGE_LABEL) test-run: - $(DOCKER) run -ti --rm -p $(HOST_PORT):$(CONTAINER_PORT) $(IMAGE_NAME) + $(DOCKER) run -ti --rm -p $(HTTP_HOST_PORT):$(HTTP_CONTAINER_PORT) -p $(HTTPS_HOST_PORT):$(HTTPS_CONTAINER_PORT) $(IMAGE_NAME):$(IMAGE_LABEL) enter: - $(DOCKER) run -ti --rm -p $(HOST_PORT):$(CONTAINER_PORT) --entrypoint /bin/bash $(IMAGE_NAME) + $(DOCKER) run -ti --rm -p $(HTTP_HOST_PORT):$(HTTP_CONTAINER_PORT) -p $(HTTPS_HOST_PORT):$(HTTPS_CONTAINER_PORT) --entrypoint /bin/bash $(IMAGE_NAME):$(IMAGE_LABEL) dist-clean: -rm -rf $(REPO_DIR) diff --git a/README.rst b/README.rst index 53ad9f3..984793c 100644 --- a/README.rst +++ b/README.rst @@ -16,8 +16,10 @@ This docker image is derivated from the official Fedora image It will contain and run - apache httpd +- mod_ssl +- certbot - python3 mod_wsgi -- django-test django application +- django-test django project BUILD @@ -27,28 +29,68 @@ BUILD or alternatively the *long* way: -- ``git clone https://heinzelwelt.de/vcs/python/django-test src/django-test`` +- ``git clone https://dev.heinzelwerk.de/git/python/django-test src/django-test`` - ``docker build -t django-test .`` - ``dgoss run django-test`` USAGE ===== -- ``docker run -d -p 80:80 django-test`` +- ``docker run -ti --rm -v $(pwd)/conf:/srv/etc:Z -e DJANGO_SYNCDB=true django-test django-createsuperuser`` +- ``docker run -ti --rm -v $(pwd)/conf:/srv/etc:Z -v $(pwd)/conf/letsencrypt:/etc/letsencrypt:Z -p 80:80 django-test certbot`` +- ``docker run -d --name django-test -v $(pwd)/conf:/srv/etc:Z -p 80:80 -p 443:443 django-test`` +Django settings +--------------- +The django project will read its settings from ``/srv/etc/django/settings.py`` +Note: this file will be read only upon container startup. + +If this settings file does not exist, the default settings will be installed +there. + +To provide your own settings file, you can mount a directory into the +container with the -v option of the ``docker run`` command. + +SELinux +------- +If your system is enforcing SELinux policies you have to set the correct +file contexts to mounted files and directories. +On recent docker versions, this can be done with the Z parameter of the +-v option (-v host_path:container_path:Z). + +HTTP Port +--------- The httpd process is listening on port 80/tcp. +Thus you probably want to publish this port with the -p option. -The httpd error log will be written to stderr, so it can be -obtained with ``docker logs`` +HTTPS Port / TLS / X.509 Certificates / certbot +----------------------------------------------- +To enable HTTPS on port 443/tcp you can either provide a key and +certificate chain as pem files, or you can use certbot to obtain a +*Let's Encrypt* certificate. +If you already have valid certificates for the domain, you can mount +the key as ``/srv/etc/certs/privkey.pem`` and the certificate +chain as ``/srv/etc/certs/fullchain.pem``. -CONFIGURATION -============= +For using certbot you have to mount a directory to ``/etc/letsencrypt``. +Then run the container once in interactive mode with the ``certbot`` command +argument to obtain a certificate from *Let's Encrypt*. The certificate will +be stored in the mounted directory. +If necessary the certificate will be renewed upon container startup. + +Environment variables +--------------------- The following **environment variables** are supported and can be set with the -e option of the ``docker run`` command: - LOG_LEVEL (default: error) -- to set the httpd LogLevel directive +- ENABLE_STATUS_ENDPOINTS (default: false) + -- if true, then the httpd status-handler is mapped to /.status + and the httpd info-handler is mapped to /.info +- DJANGO_SYNCDB (default: false) + -- if true, then apply django database migrations upon startup LICENCE diff --git a/container-filesystem/docker-entrypoint.sh b/container-filesystem/docker-entrypoint.sh index 7f7e719..36c1b3a 100755 --- a/container-filesystem/docker-entrypoint.sh +++ b/container-filesystem/docker-entrypoint.sh @@ -1,8 +1,89 @@ #!/bin/sh +PYTHON="python3" +APP_DIR="/srv/app/wsgi" +USER_CONF_DIR="/srv/etc" +CERTBOT_DIR="/etc/letsencrypt" +HTTPD_CERT_DIR="/etc/httpd/certs" + +# If user provide a django settings file, it will be copied to +# the django settings module. +# If no settings file is provided, the settings from djangos +# settings module will be copied to the users config dir, so +# he gets the defaults. +user_settings_file="${USER_CONF_DIR}/django/settings.py" +django_settings_file="${APP_DIR}/conf/settings.py" +if test -e "$user_settings_file" ; then + echo "Using django settings from $user_settings_file" + cp "$user_settings_file" "$django_settings_file" +else + echo "Installing default settings to $user_settings_file" + user_settings_dir=`dirname "$user_settings_file"` + mkdir -p "$user_settings_dir" + cp "$django_settings_file" "$user_settings_file" +fi + +# If user wants it, we apply django database migrations. +case "${DJANGO_SYNCDB:-false}" in +true|yes|1) + $PYTHON "${APP_DIR}/manage.py" migrate + ;; +false|no|0) + ;; +*) + echo "DJANGO_DB_MASTER must be either true or false" >&2 + exit 64 + ;; +esac + +# If user provided a supported command in argv, run it instead of httpd. +case "$1" in +certbot) + shift + echo "" + echo "Running certbot..." + certbot run --no-eff-email --standalone --installer null --deploy-hook /usr/local/sbin/certbot-set-default.sh + exit $? + ;; +django-createsuperuser) + echo "" + echo "Running djangos createsuperuser command..." + $PYTHON "${APP_DIR}/manage.py" createsuperuser + exit $? + ;; +esac + +# If user provide a ssl cert and key, it will be copied to +# the location were httpd looks for it. +# Or if certbot is managing certificates, use it. +certbot_cert_dir="${CERTBOT_DIR}/live/default" +if test -e "${USER_CONF_DIR}/certs/fullchain.pem" -a -e "${USER_CONF_DIR}/certs/privkey.pem" ; then + echo "Using X.509 certificate and key from $USER_CERT_DIR" + touch "${HTTPD_CERT_DIR}/privkey.pem" + chmod 600 "${HTTPD_CERT_DIR}/privkey.pem" + cat "${USER_CONF_DIR}/certs/privkey.pem" > "${HTTPD_CERT_DIR}/privkey.pem" + cat "${USER_CONF_DIR}/certs/fullchain.pem" > "${HTTPD_CERT_DIR}/fullchain.pem" +elif test -d "$certbot_cert_dir" ; then + echo "Using certbot" + certbot renew + /usr/local/sbin/certbot-deploy.sh +fi + # Remove left-overs from an incomplete shutdown previously. rm -rf /run/httpd/* /tmp/httpd* +# If user wants it, a flag will tell httpd to enable status endpoints. +if test "$ENABLE_STATUS_ENDPOINTS" == "true" ; then + echo "Enabling server status endpoints" + set -- -DENABLE_STATUS_ENDPOINTS "$@" +fi + +# If we have a ssl cert and key, a flag will tell httpd to enable HTTPS. +if test -e "${HTTPD_CERT_DIR}/fullchain.pem" -a -e "${HTTPD_CERT_DIR}/privkey.pem" ; then + echo "Enabling HTTPS" + set -- -DENABLE_HTTPS "$@" +fi + exec /usr/sbin/httpd \ -DFOREGROUND \ -c "LogLevel ${LOG_LEVEL:-error}" \ diff --git a/container-filesystem/etc/httpd/conf.d/app.conf b/container-filesystem/etc/httpd/conf.d/app.conf new file mode 100644 index 0000000..7bf9a59 --- /dev/null +++ b/container-filesystem/etc/httpd/conf.d/app.conf @@ -0,0 +1,21 @@ +# /etc/httpd/conf.d/app.conf + +WSGIDaemonProcess wsgi-daemon display-name=wsgi-daemon python-path=/srv/app/wsgi processes=3 threads=5 + +Alias /static/ "/srv/app/wsgi/var/www/static/" + + AllowOverride None + Require all granted + + +WSGIScriptAlias / "/srv/app/wsgi/conf/wsgi.py" + + WSGIProcessGroup wsgi-daemon + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowOverride None + Options FollowSymLinks + + Require all granted + + diff --git a/container-filesystem/etc/httpd/conf.d/application.conf b/container-filesystem/etc/httpd/conf.d/application.conf deleted file mode 100644 index 15623db..0000000 --- a/container-filesystem/etc/httpd/conf.d/application.conf +++ /dev/null @@ -1,20 +0,0 @@ -# /etc/httpd/conf.d/application.conf - -WSGIDaemonProcess wsgi-daemon display-name=wsgi-daemon python-home=/srv/application/python python-path=/srv/application/django - -Alias /static/ "/srv/application/django/var/www/static/" - - AllowOverride None - Require all granted - - -WSGIScriptAlias / "/srv/application/django/main/wsgi.py" - - WSGIProcessGroup wsgi-daemon - WSGIPassAuthorization On - AllowOverride None - Options FollowSymLinks - - Require all granted - - diff --git a/container-filesystem/etc/httpd/conf.d/mpm.conf b/container-filesystem/etc/httpd/conf.d/mpm.conf index 8cb3342..7a9f592 100644 --- a/container-filesystem/etc/httpd/conf.d/mpm.conf +++ b/container-filesystem/etc/httpd/conf.d/mpm.conf @@ -1,11 +1,11 @@ # /etc/httpd/conf.d/mpm.conf - ServerLimit 8 - ThreadLimit 32 - ThreadsPerChild 16 - MaxRequestWorkers 64 + ServerLimit 16 + ThreadLimit 64 + ThreadsPerChild 32 + MaxRequestWorkers 256 StartServers 2 - MinSpareThreads 16 - MaxSpareThreads 48 - MaxConnectionsPerChild 2000 + MinSpareThreads 32 + MaxSpareThreads 128 + #MaxConnectionsPerChild 2000 diff --git a/container-filesystem/etc/httpd/conf.d/ssl.conf b/container-filesystem/etc/httpd/conf.d/ssl.conf new file mode 100644 index 0000000..babcdc3 --- /dev/null +++ b/container-filesystem/etc/httpd/conf.d/ssl.conf @@ -0,0 +1,220 @@ + +# +# When we also provide SSL we have to listen to the +# standard HTTPS port in addition. +# +Listen 443 https + +## +## SSL Global Context +## +## All SSL configuration in this context applies both to +## the main server and all SSL-enabled virtual hosts. +## + +# Pass Phrase Dialog: +# Configure the pass phrase gathering process. +# The filtering dialog program (`builtin' is a internal +# terminal dialog) has to provide the pass phrase on stdout. +SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog + +# Inter-Process Session Cache: +# Configure the SSL Session Cache: First the mechanism +# to use and second the expiring timeout (in seconds). +SSLSessionCache shmcb:/run/httpd/sslcache(512000) +SSLSessionCacheTimeout 300 + +# Pseudo Random Number Generator (PRNG): +# Configure one or more sources to seed the PRNG of the +# SSL library. The seed data should be of good random quality. +# WARNING! On some platforms /dev/random blocks if not enough entropy +# is available. This means you then cannot use the /dev/random device +# because it would lead to very long connection times (as long as +# it requires to make more entropy available). But usually those +# platforms additionally provide a /dev/urandom device which doesn't +# block. So, if available, use this one instead. Read the mod_ssl User +# Manual for more details. +SSLRandomSeed startup file:/dev/urandom 256 +SSLRandomSeed connect builtin +#SSLRandomSeed startup file:/dev/random 512 +#SSLRandomSeed connect file:/dev/random 512 +#SSLRandomSeed connect file:/dev/urandom 512 + +# +# Use "SSLCryptoDevice" to enable any supported hardware +# accelerators. Use "openssl engine -v" to list supported +# engine names. NOTE: If you enable an accelerator and the +# server does not start, consult the error logs and ensure +# your accelerator is functioning properly. +# +SSLCryptoDevice builtin +#SSLCryptoDevice ubsec + +## +## SSL Virtual Host Context +## + + + +# General setup for the virtual host, inherited from global configuration +#DocumentRoot "/var/www/html" +#ServerName www.example.com:443 + +# Use separate log files for the SSL virtual host; note that LogLevel +# is not inherited from httpd.conf. +#ErrorLog /dev/stderr +#TransferLog logs/ssl_access_log +#LogLevel warn + +# SSL Engine Switch: +# Enable/Disable SSL for this virtual host. +SSLEngine on + +# List the protocol versions which clients are allowed to connect with. +# The OpenSSL system profile is configured by default. See +# update-crypto-policies(8) for more details. +SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +SSLProxyProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 + +# User agents such as web browsers are not configured for the user's +# own preference of either security or performance, therefore this +# must be the prerogative of the web server administrator who manages +# cpu load versus confidentiality, so enforce the server's cipher order. +SSLHonorCipherOrder on + +# SSL Cipher Suite: +# List the ciphers that the client is permitted to negotiate. +# See the mod_ssl documentation for a complete list. +# The OpenSSL system profile is configured by default. See +# update-crypto-policies(8) for more details. +SSLCipherSuite "DHE+aRSA+AESGCM:DHE+aRSA+AES+SHA384:DHE+aRSA+AES+SHA256:ECDHE+aRSA+AESGCM:ECDHE+aRSA+AES+SHA384:ECDHE+aRSA+AES+SHA256:DHE+aRSA+AES+SHA:ECDHE+aRSA+AES+SHA:!EXP:!LOW:!3DES:!MD5" +SSLProxyCipherSuite "DHE+aRSA+AESGCM:DHE+aRSA+AES+SHA384:DHE+aRSA+AES+SHA256:ECDHE+aRSA+AESGCM:ECDHE+aRSA+AES+SHA384:ECDHE+aRSA+AES+SHA256:DHE+aRSA+AES+SHA:ECDHE+aRSA+AES+SHA:!EXP:!LOW:!3DES:!MD5" + +# Point SSLCertificateFile at a PEM encoded certificate. If +# the certificate is encrypted, then you will be prompted for a +# pass phrase. Note that restarting httpd will prompt again. Keep +# in mind that if you have both an RSA and a DSA certificate you +# can configure both in parallel (to also allow the use of DSA +# ciphers, etc.) +# Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt) +# require an ECC certificate which can also be configured in +# parallel. +SSLCertificateFile /etc/httpd/certs/fullchain.pem + +# Server Private Key: +# If the key is not combined with the certificate, use this +# directive to point at the key file. Keep in mind that if +# you've both a RSA and a DSA private key you can configure +# both in parallel (to also allow the use of DSA ciphers, etc.) +# ECC keys, when in use, can also be configured in parallel +SSLCertificateKeyFile /etc/httpd/certs/privkey.pem + +# Server Certificate Chain: +# Point SSLCertificateChainFile at a file containing the +# concatenation of PEM encoded CA certificates which form the +# certificate chain for the server certificate. Alternatively +# the referenced file can be the same as SSLCertificateFile +# when the CA certificates are directly appended to the server +# certificate for convenience. +#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt + +# Certificate Authority (CA): +# Set the CA certificate verification path where to find CA +# certificates for client authentication or alternatively one +# huge file containing all of them (file must be PEM encoded) +#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt + +# Client Authentication (Type): +# Client certificate verification type and depth. Types are +# none, optional, require and optional_no_ca. Depth is a +# number which specifies how deeply to verify the certificate +# issuer chain before deciding the certificate is not valid. +#SSLVerifyClient require +#SSLVerifyDepth 10 + +# Access Control: +# With SSLRequire you can do per-directory access control based +# on arbitrary complex boolean expressions containing server +# variable checks and other lookup directives. The syntax is a +# mixture between C and Perl. See the mod_ssl documentation +# for more details. +# +#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \ +# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ +# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \ +# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \ +# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \ +# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +# + +# SSL Engine Options: +# Set various options for the SSL engine. +# o FakeBasicAuth: +# Translate the client X.509 into a Basic Authorisation. This means that +# the standard Auth/DBMAuth methods can be used for access control. The +# user name is the `one line' version of the client's X.509 certificate. +# Note that no password is obtained from the user. Every entry in the user +# file needs this password: `xxj31ZMTZzkVA'. +# o ExportCertData: +# This exports two additional environment variables: SSL_CLIENT_CERT and +# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the +# server (always existing) and the client (only existing when client +# authentication is used). This can be used to import the certificates +# into CGI scripts. +# o StdEnvVars: +# This exports the standard SSL/TLS related `SSL_*' environment variables. +# Per default this exportation is switched off for performance reasons, +# because the extraction step is an expensive operation and is usually +# useless for serving static content. So one usually enables the +# exportation for CGI and SSI requests only. +# o StrictRequire: +# This denies access when "SSLRequireSSL" or "SSLRequire" applied even +# under a "Satisfy any" situation, i.e. when it applies access is denied +# and no other module can change it. +# o OptRenegotiate: +# This enables optimized SSL connection renegotiation handling when SSL +# directives are used in per-directory context. +#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire + + SSLOptions +StdEnvVars + + + SSLOptions +StdEnvVars + + +# SSL Protocol Adjustments: +# The safe and default but still SSL/TLS standard compliant shutdown +# approach is that mod_ssl sends the close notify alert but doesn't wait for +# the close notify alert from client. When you need a different shutdown +# approach you can use one of the following variables: +# o ssl-unclean-shutdown: +# This forces an unclean shutdown when the connection is closed, i.e. no +# SSL close notify alert is sent or allowed to be received. This violates +# the SSL/TLS standard but is needed for some brain-dead browsers. Use +# this when you receive I/O errors because of the standard approach where +# mod_ssl sends the close notify alert. +# o ssl-accurate-shutdown: +# This forces an accurate shutdown when the connection is closed, i.e. a +# SSL close notify alert is sent and mod_ssl waits for the close notify +# alert of the client. This is 100% SSL/TLS standard compliant, but in +# practice often causes hanging connections with brain-dead browsers. Use +# this only for browsers where you know that their SSL implementation +# works correctly. +# Notice: Most problems of broken clients are also related to the HTTP +# keep-alive facility, so you usually additionally want to disable +# keep-alive for those clients, too. Use variable "nokeepalive" for this. +# Similarly, one has to force some clients to use HTTP/1.0 to workaround +# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and +# "force-response-1.0" for this. +BrowserMatch "MSIE [2-5]" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + +# Per-Server Logging: +# The home of a custom SSL log file. Use this when you want a +# compact non-error SSL logfile on a virtual host basis. +#CustomLog logs/ssl_request_log \ +# "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + + + diff --git a/container-filesystem/etc/httpd/conf.d/status.conf b/container-filesystem/etc/httpd/conf.d/status.conf new file mode 100644 index 0000000..e8fa964 --- /dev/null +++ b/container-filesystem/etc/httpd/conf.d/status.conf @@ -0,0 +1,11 @@ +# /etc/httpd/conf.d/status.conf + + + SetHandler server-status + Require all granted + + + SetHandler server-info + Require all granted + + diff --git a/container-filesystem/etc/httpd/conf.d/well-known.conf b/container-filesystem/etc/httpd/conf.d/well-known.conf new file mode 100644 index 0000000..6090545 --- /dev/null +++ b/container-filesystem/etc/httpd/conf.d/well-known.conf @@ -0,0 +1,6 @@ +# /etc/httpd/conf.d/well-known.conf + +Alias /.well-known /var/www/html/.well-known + + Require all granted + diff --git a/container-filesystem/etc/httpd/conf.modules.d/00-ssl.conf b/container-filesystem/etc/httpd/conf.modules.d/00-ssl.conf new file mode 100644 index 0000000..92764a0 --- /dev/null +++ b/container-filesystem/etc/httpd/conf.modules.d/00-ssl.conf @@ -0,0 +1,3 @@ + +LoadModule ssl_module modules/mod_ssl.so + diff --git a/container-filesystem/setup-app.sh b/container-filesystem/setup-app.sh new file mode 100755 index 0000000..455c74f --- /dev/null +++ b/container-filesystem/setup-app.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +### config ### +PYTHON="python3" +PIP="pip3" + +DJANGO_SETTINGS_FILE="conf/settings.py" + +### argv ### +if test $# -lt 2 ; then + echo "Usage: $0 " >&2 + exit 64 +fi +SOURCE_DIR="$1" +INSTALL_DIR="$2" + +### action ### +echo "Setup application in $INSTALL_DIR" +mkdir -p "$INSTALL_DIR" +echo "Install application code" +cd "$SOURCE_DIR" +$PYTHON setup.py sdist --dist-dir . --formats gztar +dist_name=`$PYTHON setup.py --name` +dist_version=`$PYTHON setup.py --version` +dist_file="${dist_name}-${dist_version}.tar.gz" +tar -xzf "$dist_file" --strip-components=1 -C "$INSTALL_DIR" +cd "$INSTALL_DIR" +echo "Install requirements" +$PIP install -r requirements.txt +echo "Setup django project" +$PYTHON setup.py django +echo "Collect static files" +$PYTHON manage.py collectstatic --noinput + +echo "Disable DEBUG mode" +cat <> "$DJANGO_SETTINGS_FILE" + +ALLOWED_HOSTS = ['*'] +DEBUG = False +E-O-H + +echo "Done" +### end ### diff --git a/container-filesystem/setup-application.sh b/container-filesystem/setup-application.sh deleted file mode 100755 index 3d15cc3..0000000 --- a/container-filesystem/setup-application.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh - -### config ### -PROJECT_REPO="git+https://heinzelwelt.de/vcs/python/django-test" -SETUP_COMMAND="django-test-admin" - -INSTALL_DIR="${HOME}" -VENV_DIR="python" -DJANGO_DIR="django" -DJANGO_MAIN_MODULE="main" - -### argv ### -if test "$1" != "" ; then - if test "$1" != "-" ; then - INSTALL_DIR="$1" - fi - shift -fi -if test "$1" != "" ; then - if test "$1" != "-" ; then - PROJECT_REPO="$1" - fi - shift -fi - -VENV_PATH="${INSTALL_DIR}/${VENV_DIR}" -DJANGO_PATH="${INSTALL_DIR}/${DJANGO_DIR}" -DJANGO_SETTINGS_FILE="${DJANGO_PATH}/${DJANGO_MAIN_MODULE}/settings.py" - -### action ### -echo "Setup application in $INSTALL_DIR" -mkdir -p "$INSTALL_DIR" -echo "Setup python environment" -python3 -m venv "${VENV_PATH}" -source "${VENV_PATH}/bin/activate" -pip install --upgrade pip -echo "Install application from $PROJECT_REPO" -pip install "$PROJECT_REPO" -echo "Setup django project" -$SETUP_COMMAND setup "${DJANGO_PATH}" -echo "Collect static files" -python3 "${DJANGO_PATH}/manage.py" collectstatic --noinput - -echo "Disable DEBUG mode" -cat <> "$DJANGO_SETTINGS_FILE" - -ALLOWED_HOSTS = ['*'] -DEBUG = False -E-O-H - -echo "Done" -### end ### diff --git a/container-filesystem/usr/local/sbin/certbot-deploy.sh b/container-filesystem/usr/local/sbin/certbot-deploy.sh new file mode 100644 index 0000000..af6e5ba --- /dev/null +++ b/container-filesystem/usr/local/sbin/certbot-deploy.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +LIVE_DIR="/etc/letsencrypt/live" +DEFAULT_LINK="${LIVE_DIR}/default" +DEST_DIR="/etc/httpd/certs" + +CERT_DIR="" +if test "$1" != "" ; then + CERT_DIR="$1" +elif test "$RENEWED_LINEAGE" != "" ; then + CERT_DIR="$RENEWED_LINEAGE" +elif test -d "$DEFAULT_LINK" ; then + CERT_DIR="$DEFAULT_LINK" +else + echo "You must name a certificate dir either as argument or via RENEWED_LINEAGE" >&2 + exit 64 +fi + +cert_name=`basename $CERT_DIR` +if test -d "$DEST_DIR" ; then + echo "Installing key and certs for $cert_name in $DEST_DIR" + + key_source_file="${CERT_DIR}/privkey.pem" + key_dest_file="${DEST_DIR}/privkey.pem" + + certs_source_file="${CERT_DIR}/fullchain.pem" + certs_dest_file="${DEST_DIR}/fullchain.pem" + + touch "$key_dest_file" + chmod 600 "$key_dest_file" + echo "Copy $key_source_file to $key_dest_file" + cat "$key_source_file" > "$key_dest_file" + + echo "Copy $certs_source_file to $certs_dest_file" + cat "$certs_source_file" > "$certs_dest_file" +fi diff --git a/container-filesystem/usr/local/sbin/certbot-set-default.sh b/container-filesystem/usr/local/sbin/certbot-set-default.sh new file mode 100644 index 0000000..76df302 --- /dev/null +++ b/container-filesystem/usr/local/sbin/certbot-set-default.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +LIVE_DIR="/etc/letsencrypt/live" +DEFAULT_LINK="${LIVE_DIR}/default" + +CERT_DIR="" +if test "$1" != "" ; then + CERT_DIR="$1" +elif test "$RENEWED_LINEAGE" != "" ; then + CERT_DIR="$RENEWED_LINEAGE" +else + echo "You must name a certificate dir either as argument or via RENEWED_LINEAGE" >&2 + exit 64 +fi + +cert_name=`basename $CERT_DIR` +echo "Setting $cert_name as default certificate name" +if test -L "$DEFAULT_LINK" ; then + rm "$DEFAULT_LINK" +elif test -e "$DEFAULT_LINK" ; then + echo "Not a symbolic link: $DEFAULT_LINK" >&2 + exit 78 +fi +ln -s "$cert_name" "$DEFAULT_LINK" diff --git a/goss.yaml b/goss.yaml index ee23036..b6e5e0d 100644 --- a/goss.yaml +++ b/goss.yaml @@ -10,11 +10,11 @@ file: owner: apache group: apache filetype: directory - /srv/application/django/main/wsgi.py: + /srv/app/django/main/wsgi.py: exists: true mode: "0644" - owner: root - group: root + owner: apache + group: apache filetype: file package: httpd: