Skip to content

Commit

Permalink
Merge pull request #294 from codingdavinci/drupal-9
Browse files Browse the repository at this point in the history
Drupal 9 on nginx with Redis
  • Loading branch information
mbuechner authored Oct 29, 2021
2 parents cf39612 + 1b913a1 commit ca01ba7
Show file tree
Hide file tree
Showing 41 changed files with 4,449 additions and 2,905 deletions.
227 changes: 117 additions & 110 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,128 +1,135 @@
FROM composer:2 AS COMPOSER_CHAIN
MAINTAINER Michael Büchner <m.buechner@dnb.de>
COPY / /tmp/cdv
WORKDIR /tmp/cdv
RUN composer install --no-dev

# Add git tag version to PHP file
RUN { \
echo -e "<\x21-- $(git describe --tags) -->"; \
} >> /tmp/cdv/web/themes/custom/relaunch2018/templates/html.html.twig
RUN rm -rf .git/
echo -e "<\x21-- $(git describe --tags) -->"; \
} >> /tmp/cdv/web/themes/custom/relaunch2018/templates/html.html.twig; \
rm -rf .git/;

# from https://github.com/docker-library/drupal/blob/master/8.7/apache/Dockerfile
FROM php:7.4-apache
FROM php:8.0-fpm-alpine
MAINTAINER Michael Büchner <m.buechner@dnb.de>

# Install packages
RUN apk --no-cache add \
curl \
nginx \
nginx-mod-http-brotli \
redis \
supervisor; \
apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing \
supercronic;

RUN set -eux; \
if command -v a2enmod; then \
a2enmod rewrite; \
fi; \
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends \
libfreetype6-dev \
libjpeg-dev \
libpng-dev \
libpq-dev \
libzip-dev; \
docker-php-ext-configure gd \
--with-freetype \
--with-jpeg; \
docker-php-ext-install -j "$(nproc)" \
gd \
opcache \
pdo_mysql \
pdo_pgsql \
zip; \
pecl install uploadprogress apcu; \
docker-php-ext-enable uploadprogress apcu; \
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
| awk '/=>/ { print $3 }' \
| sort -u \
| xargs -r dpkg-query -S \
| cut -d: -f1 \
| sort -u \
| xargs -rt apt-mark manual; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false;
\
apk add --no-cache --virtual .build-deps \
coreutils \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
libzip-dev \
pcre-dev \
autoconf \
g++ \
make \
git \
# postgresql-dev is needed for https://bugs.alpinelinux.org/issues/3642
postgresql-dev; \
\
docker-php-ext-configure gd \
--with-freetype \
--with-jpeg=/usr/include; \
\
docker-php-ext-install -j "$(nproc)" \
gd \
opcache \
pdo_mysql \
pdo_pgsql \
zip; \
pecl channel-update pecl.php.net; \
pecl install oauth apcu redis; \
docker-php-ext-enable apcu oauth redis; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-network --virtual .drupal-phpexts-rundeps $runDeps; \
apk del --no-network .build-deps \
coreutils \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
libzip-dev \
pcre-dev \
autoconf \
g++ \
make \
git \
postgresql-dev;

ENV RUN_USER nobody
ENV RUN_GROUP 0

RUN echo "LISTEN 8080" > /etc/apache2/ports.conf; \
{ \
echo "opcache.file_update_protection=0"; \
echo "opcache.validate_timestamps=0"; \
echo "opcache.interned_strings_buffer=16"; \
echo "opcache.memory_consumption=128"; \
echo "opcache.max_accelerated_files=4000"; \
echo "opcache.max_wasted_percentage=10"; \
echo "opcache.revalidate_freq=60"; \
} > /usr/local/etc/php/conf.d/2-opcache-recommended.ini; \
{ \
echo "apc.enabled=1"; \
echo "apc.file_update_protection=2"; \
echo "apc.optimization=0"; \
echo "apc.shm_size=256M"; \
echo "apc.include_once_override=0"; \
echo "apc.shm_segments=1"; \
echo "apc.ttl=7200"; \
echo "apc.user_ttl=7200"; \
echo "apc.gc_ttl=3600"; \
echo "apc.num_files_hint=1024"; \
echo "apc.enable_cli=0"; \
echo "apc.max_file_size=5M"; \
echo "apc.cache_by_default=1"; \
echo "apc.use_request_time=1"; \
echo "apc.slam_defense=0"; \
echo "apc.mmap_file_mask=/tmp/apc.XXXXXX"; \
echo "apc.stat_ctime=0"; \
echo "apc.canonicalize=1"; \
echo "apc.write_lock=1"; \
echo "apc.report_autofilter=0"; \
echo "apc.rfc1867=0"; \
echo "apc.rfc1867_prefix =upload_"; \
echo "apc.rfc1867_name=APC_UPLOAD_PROGRESS"; \
echo "apc.rfc1867_freq=0"; \
echo "apc.rfc1867_ttl=3600"; \
echo "apc.lazy_classes=0"; \
echo "apc.lazy_functions=0"; \
} > /usr/local/etc/php/conf.d/1-apcu-caching.ini; \
{ \
echo "error_log = /dev/stderr"; \
echo "error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT"; \
echo "display_errors = Off"; \
echo "display_startup_errors = Off"; \
echo "html_errors = On"; \
echo "log_errors = On"; \
echo "upload_max_filesize = 128M"; \
echo "post_max_size = 128M"; \
echo "memory_limit = 512M"; \
echo "max_execution_time = 600"; \
echo "max_input_vars = 5000"; \
} > /usr/local/etc/php/conf.d/0-upload_large_dumps.ini; \
{ \
echo "<VirtualHost *:8080>"; \
echo " ServerAdmin m.buechner@dnb.de"; \
echo " DocumentRoot /var/www/html/web"; \
echo " ErrorLog /dev/stderr"; \
echo " CustomLog /dev/stdout combined"; \
echo "</VirtualHost>"; \
} > /etc/apache2/sites-enabled/000-default.conf;
# add PHP config
COPY --chown=${RUN_USER}:${RUN_GROUP} ./config/php/ /usr/local/etc/php/conf.d/

# add NGINX config
COPY --chown=${RUN_USER}:${RUN_GROUP} config/nginx/*.conf /etc/nginx/
COPY --chown=${RUN_USER}:${RUN_GROUP} config/nginx/mime.types /etc/nginx/mime.types
COPY --chown=${RUN_USER}:${RUN_GROUP} config/nginx/conf.d/ /etc/nginx/conf.d/
COPY --chown=${RUN_USER}:${RUN_GROUP} config/nginx/.authpasswd /etc/nginx/.authpasswd

# add cron jobs
COPY --chown=${RUN_USER}:${RUN_GROUP} config/cron/* /etc/crontabs/

# add supervisord config
COPY --chown=${RUN_USER}:${RUN_GROUP} config/supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Add application
WORKDIR /var/www/html
COPY --from=COMPOSER_CHAIN /tmp/cdv/ .
COPY docker-php-entrypoint-drupal.sh /usr/local/bin/docker-php-entrypoint-drupal
RUN chmod 775 /usr/local/bin/docker-php-entrypoint-drupal; \
chown -R www-data:www-data web/sites web/modules web/themes web/tmp; \
chmod +x /var/www/html/vendor/drush/drush/drush; \
find web \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \);
COPY --chown=${RUN_USER}:${RUN_GROUP} --from=COMPOSER_CHAIN /tmp/cdv/ .
ENV PATH=${PATH}:/var/www/html/vendor/bin

RUN \
# Create symlink for php8
ln -s /usr/bin/php8 /usr/bin/php; \
# Use the default PHP production configuration
mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"; \
# Move entrypoint script in place
mv scripts/docker-php-entrypoint-drupal.sh /usr/local/bin/docker-php-entrypoint-drupal; \
mv scripts/drupal-maintenance.sh /usr/local/bin/drupal-maintenance; \
# Generate SSL certificates fpr HTTP2
# Generating signing SSL private key
openssl genrsa -des3 -passout pass:foobar -out /etc/ssl/mykey.pem 2048; \
# Removing passphrase from private key
cp /etc/ssl/mykey.pem /etc/ssl/mykey.pem.orig; \
openssl rsa -passin pass:foobar -in /etc/ssl/mykey.pem.orig -out /etc/ssl/mykey.pem; \
# Generating certificate signing request
openssl req -new -key /etc/ssl/mykey.pem -out /etc/ssl/mycert.csr -subj "/C=DE/ST=DE/L=Frankfurt am Main/O=Deutsche Nationalbibliothek/OU=IT.DDB/CN=Coding da Vinci"; \
# Generating self-signed certificate
openssl x509 -req -days 3650 -in /etc/ssl/mycert.csr -signkey /etc/ssl/mykey.pem -out /etc/ssl/mycert.pem; \
# Make sure files/folders needed by the processes are accessable when they run under the nobody user
mkdir /var/cache/nginx; \
chgrp -R ${RUN_GROUP} /run /var/cache/nginx/ /var/lib/nginx/ /var/log/nginx/ /var/www/html/ /etc/ssl/mycert.pem /etc/ssl/mykey.pem /etc/nginx/.authpasswd; \
chmod -R g=u /run/ /etc/nginx/conf.d/ /etc/nginx/*.conf /var/cache/nginx/ /var/lib/nginx/ /var/log/nginx/ /var/www/html/ /etc/ssl/mycert.pem /etc/ssl/mykey.pem /etc/nginx/.authpasswd; \
chmod 751 /usr/local/bin/docker-php-entrypoint-drupal /usr/local/bin/drupal-maintenance /var/www/html/vendor/drush/drush/drush /var/www/html/web/sites/default; \
chmod 440 /var/www/html/web/sites/default/settings.php; \
# add permissions for suervisor & nginx user
touch /run/supervisord.pid && chgrp -R ${RUN_GROUP} /run/supervisord.pid && chmod -R g=u /run/supervisord.pid; \
touch /run/nginx/nginx.pid && chgrp -R ${RUN_GROUP} /run/nginx/nginx.pid && chmod -R g=u /run/nginx/nginx.pid;

# Clean system
RUN apt-get clean; \
rm -rf /var/lib/apt/lists/*
# Switch to use a non-root user
USER ${RUN_USER}:${RUN_GROUP}

ENTRYPOINT ["docker-php-entrypoint-drupal"]

HEALTHCHECK --interval=1m --timeout=3s CMD curl --fail http://localhost:8080/ || exit 1
# Expose the ports for nginx
EXPOSE 8080 4430

EXPOSE 8080
CMD ["apache2-foreground"]
# supervisord starts nginx & php-fpm
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
39 changes: 22 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ The website [codingdavinci.de](https://codingdavinci.de/) was launched in early

Task management: Tasks are broken down as [issues](https://github.com/codingdavinci/relaunch2018/issues) and prioritised/tracked in the ["Relaunch 2018" project kanban](https://github.com/codingdavinci/relaunch2018/projects/1).

Contact: lucy.patterson@wikimedia.de (@lucyWMDE)

## Installation

The project was set up using the [Composer template for Drupal projects](https://github.com/drupal-composer/drupal-project). Installation requires [Composer](https://getcomposer.org/) for managing PHP packages.
Expand Down Expand Up @@ -63,7 +61,7 @@ Yarn scripts are set up to lint ES6 JavaScript files and SCSS files:

## Docker

This Dupal project is available as Docker container from Docker Hub: https://hub.docker.com/r/codingdavinci/relaunch2018
This Dupal project is available as Docker container from GitHub: https://github.com/codingdavinci/relaunch2018/pkgs/container/relaunch2018%2Fcdv

To execute the pre-compiled Docker container run the following command with the variables set for your environment. An example for Docker Composer can be found in [docker-compose.yml](docker-compose.yml).
```shell
Expand All @@ -77,24 +75,30 @@ docker run -d -p 8080:80 -P \
--env "UPDATE_FREE_ACCESS=FALSE" \
--env "FILE_PUBLIC_PATH=sites/default/files" \
--env "TRUSTED_HOST_PATTERNS=\"^localhost\$, ^127.0.0.1\$\"" \
codingsdavinci/relaunch2018:lastest
ghcr.io/codingdavinci/relaunch2018/cdv:latest
```

### Environment variables

Please see [web/sites/default/settings.php](web/sites/default/settings.php) for additional information.

| Environment variable | Description | Example |
|-----------------------|-------------------------------------------------------------------------|---------------------------------|
| MYSQL_HOSTNAME | Database connection. Server host name. | `cdv.example.com` |
| MYSQL_DATABASE | Database connection. Name of the database. | `mycdvdatabase` |
| MYSQL_USER | Database connection. Login name for database. | `mycdvuser` |
| MYSQL_PASSWORD | Database connection. Password for database. | `mycdvpassword` |
| MYSQL_PORT | Database connection. Server Connection Port. | `3306` |
| HASH_SALT | Salt for Drupal's one-time login links, cancel links, form tokens, etc. | `myverysecretcdvhashsalt` |
| UPDATE_FREE_ACCESS | Access control for update.php script. | `FALSE` |
| FILE_PUBLIC_PATH | Public file path. | `sites/default/files` |
| TRUSTED_HOST_PATTERNS | Trusted host configuration. | `"^localhost\$, ^127.0.0.1\$\"` |
Please also see [web/sites/default/settings.php](web/sites/default/settings.php) for additional information.

| Environment variable | Description | Example |
|-------------------------|------------------------------------------------------------------------------------------------|---------------------------------|
| MYSQL_HOSTNAME | Database connection. Server host name. | `cdv.example.com` |
| MYSQL_DATABASE | Database connection. Name of the database. | `mycdvdatabase` |
| MYSQL_USER | Database connection. Login name for database. | `mycdvuser` |
| MYSQL_PASSWORD | Database connection. Password for database. | `mycdvpassword` |
| MYSQL_PORT | Database connection. Server Connection Port. | `3306` |
| HASH_SALT | Salt for Drupal's one-time login links, cancel links, form tokens, etc. | `myverysecretcdvhashsalt` |
| UPDATE_FREE_ACCESS | Access control for update.php script. | `FALSE` |
| FILE_PUBLIC_PATH | Public file path. | `sites/default/files` |
| TRUSTED_HOST_PATTERNS | Trusted host configuration. | `"^localhost\$, ^127.0.0.1\$\"` |
| HTPASSWD_USER | If `HTPASSWD_USER` and `HTPASSWD_PWD` are set, ... | `user` |
| HTPASSWD_PWD | the user will get a Basic HTTP Auth request when accessing the website . | `mypassword` |
| HTPASSWD_GREETING | Customized HTTP Auth greeting | `Hello, welcome!` |
| UPDATEDB_ON_STARTUP | If set to `yes`, `drush updatedb` will be executed once on container start. Default: `no` | `yes`or `no` |
| CACHEREBUILD_ON_STARTUP | If set to `yes`, `drush cache-rebuild` will be executed once on container start. Default: `no` | `yes`or `no` |
| USE_REDIS | Use Redis as memory cache. Default: `no` | `yes`or `no` |

### Build and start Docker container locally

Expand All @@ -117,3 +121,4 @@ docker run -d -p 8080:80 -P \
--env "TRUSTED_HOST_PATTERNS=\"^localhost\$, ^127.0.0.1\$\"" \
cdv
```

Loading

0 comments on commit ca01ba7

Please sign in to comment.