From cfe8b7cd46aa7410859be93aa153f17e5aa8d378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Laurent?= Date: Mon, 25 Oct 2021 15:46:47 +0200 Subject: [PATCH] dockerfile and configuration --- .gitignore | 2 +- docker/Dockerfile | 80 ++++++++++++++++++++++++++++++++ docker/README.md | 47 +++++++++++++++++++ docker/docker-compose.yml | 28 +++++++++++ docker/entrypoint.sh | 20 ++++++++ docker/etc/DocumentRoot.htaccess | 3 ++ docker/etc/app_local.php | 44 ++++++++++++++++++ docker/etc/webroot.htaccess | 3 ++ 8 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 docker/Dockerfile create mode 100644 docker/README.md create mode 100644 docker/docker-compose.yml create mode 100755 docker/entrypoint.sh create mode 100644 docker/etc/DocumentRoot.htaccess create mode 100644 docker/etc/app_local.php create mode 100644 docker/etc/webroot.htaccess diff --git a/.gitignore b/.gitignore index f370d3e..cdb86ef 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ config/app_local.php logs tmp vendor - +docker/run/ diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..7e2035e --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,80 @@ +ARG COMPOSER_VERSION +ARG PHP_VERSION +ARG DEBIAN_RELEASE + +FROM php:${PHP_VERSION}-apache-${DEBIAN_RELEASE} + +# we need some extra libs to be installed in the runtime +RUN apt-get update && \ + apt-get install -y --no-install-recommends curl git zip unzip && \ + apt-get install -y --no-install-recommends libicu-dev libxml2-dev && \ + docker-php-ext-install intl pdo pdo_mysql mysqli simplexml && \ + apt-get remove -y --purge libicu-dev libxml2-dev && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +COPY composer.json composer.json + +# install composer as root +ARG COMPOSER_VERSION +RUN curl -sL https://getcomposer.org/installer | \ + php -- --install-dir=/usr/bin/ --filename=composer --version=${COMPOSER_VERSION} + +# switch back to unprivileged user for composer install +USER www-data + +RUN composer install \ + --ignore-platform-reqs \ + --no-interaction \ + --no-plugins \ + --no-scripts \ + --prefer-dist + +# web server configuration +USER root + +# allow .htaccess overrides and push them +RUN a2enmod rewrite +RUN sed -i -r '/DocumentRoot/a \\t\n\t\tAllowOverride all\n\t' /etc/apache2/sites-available/000-default.conf +COPY --chown=www-data docker/etc/DocumentRoot.htaccess /var/www/html/.htaccess +COPY --chown=www-data docker/etc/webroot.htaccess /var/www/html/webroot/.htaccess + +# passing environment variables through apache +RUN a2enmod env +RUN echo 'PassEnv CEREBRATE_DB_HOST' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_DB_NAME' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_DB_PASSWORD' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_DB_PORT' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_DB_SCHEMA' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_DB_USERNAME' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_EMAIL_HOST' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_EMAIL_PASSWORD' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_EMAIL_PORT' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_EMAIL_TLS' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_EMAIL_USERNAME' >> /etc/apache2/conf-enabled/environment.conf +RUN echo 'PassEnv CEREBRATE_SECURITY_SALT' >> /etc/apache2/conf-enabled/environment.conf + +# entrypoint +COPY docker/entrypoint.sh /entrypoint.sh +RUN chmod 755 /entrypoint.sh + +# copy actual codebase +COPY --chown=www-data . /var/www/html + +# last checks with unprivileged user +USER www-data + +# CakePHP seems to not handle very well externally installed components +# this will chown/chmod/symlink all in place for its own good +RUN composer install --no-interaction + +# app config override making use of environment variables +COPY --chown=www-data docker/etc/app_local.php /var/www/html/config/app_local.php +# version 1.0 addition requires a config/config.json file +# can still be overriden by a docker volume +RUN cp -a /var/www/html/config/config.example.json /var/www/html/config/config.json + +# also can be overridin by a docker volume +RUN mkdir -p /var/www/html/logs + +ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..1074c0c --- /dev/null +++ b/docker/README.md @@ -0,0 +1,47 @@ +# Database init + +For the `docker-compose` setup to work you must initialize database with +what is in `../INSTALL/mysql.sql` + +``` +mkdir -p run/dbinit/ +cp ../INSTALL/mysql.sql run/dbinit/ +``` + +The MariaDB container has a volume mounted as follow +`- ./run/dbinit:/docker-entrypoint-initdb.d/:ro` + +So that on startup the container will source files in this directory to seed +the database. Once it's done the container will run normally and Cerebrate will +be able to roll its database migration scripts + +# Actual data and volumes + +The actual database will be located in `./run/database` exposed with the +following volume `- ./run/database:/var/lib/mysql` + +Application logs (CakePHP / Cerebrate) will be stored in `./run/logs`, +volume `- ./run/logs:/var/www/html/logs` + +You're free to change those parameters if you're using Swarm, Kubernetes or +your favorite config management tool to deploy this stack + +# Building yourself + +You can create the following Makefile in basedir of this repository +and issue `make image` + +``` +COMPOSER_VERSION?=2.1.5 +PHP_VERSION?=7.4 +DEBIAN_RELEASE?=buster +IMAGE_NAME?=cerebrate:latest + +image: + docker build -t $(IMAGE_NAME) \ + -f docker/Dockerfile \ + --build-arg COMPOSER_VERSION=$(COMPOSER_VERSION) \ + --build-arg PHP_VERSION=$(PHP_VERSION) \ + --build-arg DEBIAN_RELEASE=$(DEBIAN_RELEASE) \ + . +``` diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..e36c8c5 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,28 @@ +version: "3" +services: + database: + image: mariadb:10.6 + restart: always + volumes: + - ./run/database:/var/lib/mysql + - ./run/dbinit:/docker-entrypoint-initdb.d/:ro + environment: + MARIADB_RANDOM_ROOT_PASSWORD: "yes" + MYSQL_DATABASE: "cerebrate" + MYSQL_USER: "cerebrate" + MYSQL_PASSWORD: "etarberec" + www: + image: $IMAGE_NAME + ports: + - "8080:80" + volumes: + - ./run/logs:/var/www/html/logs + environment: + DEBUG: "true" + CEREBRATE_DB_USERNAME: "cerebrate" + CEREBRATE_DB_PASSWORD: "etarberec" + CEREBRATE_DB_NAME: "cerebrate" + CEREBRATE_DB_HOST: database + CEREBRATE_SECURITY_SALT: supersecret + depends_on: + - database diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 0000000..35ef6dd --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +set -e + + +run_all_migrations() { + ./bin/cake migrations migrate + ./bin/cake migrations migrate -p tags + ./bin/cake migrations migrate -p ADmad/SocialAuth +} + +# waiting for DB to come up +for try in 1 2 3 4 5 6; do + echo >&2 "migration - attempt $try" + run_all_migrations && break || true + sleep 5 + [ "$try" = "6" ] && exit 1 +done + +exec /usr/local/bin/apache2-foreground "$@" diff --git a/docker/etc/DocumentRoot.htaccess b/docker/etc/DocumentRoot.htaccess new file mode 100644 index 0000000..ef9940b --- /dev/null +++ b/docker/etc/DocumentRoot.htaccess @@ -0,0 +1,3 @@ +RewriteEngine on +RewriteRule ^$ webroot/ [L] +RewriteRule (.*) webroot/$1 [L] diff --git a/docker/etc/app_local.php b/docker/etc/app_local.php new file mode 100644 index 0000000..ac1d212 --- /dev/null +++ b/docker/etc/app_local.php @@ -0,0 +1,44 @@ + env('CEREBRATE_DB_USERNAME', 'cerebrate'), + 'password' => env('CEREBRATE_DB_PASSWORD', ''), + 'host' => env('CEREBRATE_DB_HOST', 'localhost'), + 'database' => env('CEREBRATE_DB_NAME', 'cerebrate'), +]; + +// non-default port can be set on demand - otherwise the DB driver will choose the default +if (!empty(env('CEREBRATE_DB_PORT'))) { + $db['port'] = env('CEREBRATE_DB_PORT'); +} + +// If not using the default 'public' schema with the PostgreSQL driver set it here. +if (!empty(env('CEREBRATE_DB_SCHEMA'))) { + $db['schema'] = env('CEREBRATE_DB_SCHEMA'); +} + +return [ + 'debug' => filter_var(env('DEBUG', false), FILTER_VALIDATE_BOOLEAN), + + 'Security' => [ + 'salt' => env('CEREBRATE_SECURITY_SALT'), + ], + + 'Datasources' => [ + 'default' => $db, + ], + + 'EmailTransport' => [ + 'default' => [ + // host could be ssl://smtp.gmail.com then set port to 465 + 'host' => env('CEREBRATE_EMAIL_HOST', 'localhost'), + 'port' => env('CEREBRATE_EMAIL_PORT', 25), + 'username' => env('CEREBRATE_EMAIL_USERNAME', null), + 'password' => env('CEREBRATE_EMAIL_PASSWORD', null), + 'tls' => env('CEREBRATE_EMAIL_TLS', null) + ], + ], + 'Cerebrate' => [ + 'open' => [], + 'dark' => 0 + ] +]; diff --git a/docker/etc/webroot.htaccess b/docker/etc/webroot.htaccess new file mode 100644 index 0000000..879f805 --- /dev/null +++ b/docker/etc/webroot.htaccess @@ -0,0 +1,3 @@ +RewriteEngine On +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^ index.php [L]