├── 6 ├── drupal │ ├── php8.1 │ │ ├── .my.cnf │ │ ├── Dockerfile │ │ ├── apache-sites-available-default.conf │ │ ├── apache.conf │ │ ├── civicrm-docker-dump │ │ ├── civicrm-docker-entrypoint │ │ ├── civicrm-docker-init │ │ ├── civicrm-docker-install │ │ ├── civicrm-docker-load │ │ ├── civicrm.settings.php │ │ ├── civicrm_dump.php │ │ ├── msmtp-wrapper │ │ └── settings.php │ ├── php8.2 │ │ ├── .my.cnf │ │ ├── Dockerfile │ │ ├── apache-sites-available-default.conf │ │ ├── apache.conf │ │ ├── civicrm-docker-dump │ │ ├── civicrm-docker-entrypoint │ │ ├── civicrm-docker-init │ │ ├── civicrm-docker-install │ │ ├── civicrm-docker-load │ │ ├── civicrm.settings.php │ │ ├── civicrm_dump.php │ │ ├── msmtp-wrapper │ │ └── settings.php │ └── php8.3 │ │ ├── .my.cnf │ │ ├── Dockerfile │ │ ├── apache-sites-available-default.conf │ │ ├── apache.conf │ │ ├── civicrm-docker-dump │ │ ├── civicrm-docker-entrypoint │ │ ├── civicrm-docker-init │ │ ├── civicrm-docker-install │ │ ├── civicrm-docker-load │ │ ├── civicrm.settings.php │ │ ├── civicrm_dump.php │ │ ├── msmtp-wrapper │ │ └── settings.php └── wordpress │ ├── php8.1 │ ├── .my.cnf │ ├── Dockerfile │ ├── apache-sites-available-default.conf │ ├── apache.conf │ ├── civicrm-docker-dump │ ├── civicrm-docker-entrypoint │ ├── civicrm-docker-init │ ├── civicrm-docker-install │ ├── civicrm-docker-load │ ├── civicrm.settings.php │ ├── civicrm_dump.php │ ├── msmtp-wrapper │ └── wp-config.php │ ├── php8.2 │ ├── .my.cnf │ ├── Dockerfile │ ├── apache-sites-available-default.conf │ ├── apache.conf │ ├── civicrm-docker-dump │ ├── civicrm-docker-entrypoint │ ├── civicrm-docker-init │ ├── civicrm-docker-install │ ├── civicrm-docker-load │ ├── civicrm.settings.php │ ├── civicrm_dump.php │ ├── msmtp-wrapper │ └── wp-config.php │ └── php8.3 │ ├── .my.cnf │ ├── Dockerfile │ ├── apache-sites-available-default.conf │ ├── apache.conf │ ├── civicrm-docker-dump │ ├── civicrm-docker-entrypoint │ ├── civicrm-docker-init │ ├── civicrm-docker-install │ ├── civicrm-docker-load │ ├── civicrm.settings.php │ ├── civicrm_dump.php │ ├── msmtp-wrapper │ └── wp-config.php ├── .gitignore ├── README.md ├── TODO.md ├── bin ├── civicrm-docker-dump-manual ├── civicrm-docker-lint ├── gen-secret-keys └── gen-wordpress-keys ├── buildAndPublish.php ├── combos.json ├── docker-compose ├── README.md ├── backdrop │ ├── .gitignore │ ├── dev.dist.env │ ├── docker-compose.dev.dist.yml │ └── docker-compose.prod.dist.yml ├── drupal │ ├── .gitignore │ ├── dev.dist.env │ ├── docker-compose.dev.dist.yml │ └── docker-compose.prod.dist.yml └── wordpress │ ├── .gitignore │ ├── dev.dist.env │ ├── docker-compose.dev.dist.yml │ └── docker-compose.prod.dist.yml ├── docs └── getting-started.md ├── generate.php ├── mysql ├── Dockerfile └── my.cnf ├── templates ├── .my.cnf ├── Dockerfile ├── apache-sites-available-default.conf ├── apache.conf ├── civicrm-docker-entrypoint ├── civicrm-docker-load ├── civicrm_dump.php ├── drupal.Dockerfile ├── drupal.civicrm-docker-dump ├── drupal.civicrm-docker-init ├── drupal.civicrm-docker-install ├── drupal.civicrm.settings.php ├── drupal.settings.php ├── msmtp-wrapper ├── wordpress.Dockerfile ├── wordpress.civicrm-docker-dump ├── wordpress.civicrm-docker-init ├── wordpress.civicrm-docker-install ├── wordpress.civicrm.settings.php └── wordpress.wp-config.php ├── update.php └── variables.php /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michaelmcandrew/civicrm-docker/4efca5b53198e48fa3cec073e70b8f0cc36a3cae/.gitignore -------------------------------------------------------------------------------- /6/drupal/php8.1/.my.cnf: -------------------------------------------------------------------------------- 1 | [mysqldump] 2 | max_allowed_packet=1024M 3 | -------------------------------------------------------------------------------- /6/drupal/php8.1/Dockerfile: -------------------------------------------------------------------------------- 1 | ### THIS FILE GENERATED BY https://github.com/michaelmcandrew/civicrm-docker/blob/master/generate.py ### 2 | 3 | FROM php:8.1-apache-bookworm 4 | 5 | # libc-client-dev and libkrb5-dev required for the imap php extension 6 | # libicu-dev required for the intl php extension 7 | # libmagickwand-dev required for the imagick php extension 8 | # libjpeg62-turbo-dev and libpng-dev required for the gd php extension 9 | # libxml2-dev required for the soap php extension 10 | # iproute2 is required to get the host ip at runtime for XDEBUG_REMOTE_HOST environment variable 11 | # msmtp-mta allows us to globally redirect email via SMTP 12 | # unzip is required for composer 13 | 14 | RUN apt-get update \ 15 | && apt-get install -y --no-install-recommends \ 16 | imagemagick \ 17 | iproute2 \ 18 | less \ 19 | libc-client-dev \ 20 | libicu-dev \ 21 | libjpeg62-turbo-dev \ 22 | libkrb5-dev \ 23 | libmagickwand-dev \ 24 | libpng-dev \ 25 | libxml2-dev \ 26 | libzip-dev \ 27 | msmtp-mta \ 28 | mariadb-client \ 29 | unzip \ 30 | wget \ 31 | && rm -r /var/lib/apt/lists/* 32 | 33 | # CiviCRM requires the following PHP extensions (some of which are already 34 | # enabled in the Docker image): 35 | # 36 | # * curl (already enabled) 37 | # * gd 38 | # * gettext 39 | # * imagick 40 | # * imap 41 | # * intl 42 | # * json (already enabled) 43 | # * mbstring (already enabled) 44 | # * mysqli 45 | # * openssl (already enabled) 46 | # * pdo_mysql 47 | # * phar (already enabled) 48 | # * posix (already enabled) 49 | # * soap 50 | # * zip 51 | 52 | # WordPress recommends the following PHP extensions in addition to 53 | # the ones listed above: 54 | # 55 | # * dom (already enabled) 56 | # * exif 57 | # * fileinfo (already enabled) 58 | # * hash (already enabled) 59 | # * igbinary 60 | # * imagick 61 | # * pcre (already enabled) 62 | # * xml (already enabled) 63 | 64 | # Configure and install php extensions (note configuration comes before installation) 65 | 66 | RUN docker-php-ext-install bcmath \ 67 | && docker-php-ext-install exif \ 68 | && docker-php-ext-configure gd --with-jpeg \ 69 | && docker-php-ext-install gd \ 70 | && docker-php-ext-install gettext \ 71 | && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ 72 | && docker-php-ext-install imap \ 73 | && docker-php-ext-install intl \ 74 | && docker-php-ext-install mysqli \ 75 | && docker-php-ext-install opcache \ 76 | && docker-php-ext-install pdo_mysql \ 77 | && docker-php-ext-install soap \ 78 | && docker-php-ext-install zip 79 | 80 | # Install and enable imagick PECL extensions 81 | 82 | # Copy pasta from https://github.com/docker-library/wordpress/blob/3f1a0cab9f2f938bbc57f5f92ec11eeea4511636/latest/php8.3/fpm-alpine/Dockerfile#L47-L51 83 | # Based on suggestion here: https://github.com/docker-library/php/issues/1532#issuecomment-2258777719 84 | RUN curl -fL -o imagick.tgz 'https://pecl.php.net/get/imagick-3.7.0.tgz'; \ 85 | echo '5a364354109029d224bcbb2e82e15b248be9b641227f45e63425c06531792d3e *imagick.tgz' | sha256sum -c -; \ 86 | tar --extract --directory /tmp --file imagick.tgz imagick-3.7.0; \ 87 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php; \ 88 | test "$(grep -c '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php)" = '1'; \ 89 | sed -i -e 's!^//#endif$!#endif!' /tmp/imagick-3.7.0/Imagick.stub.php; \ 90 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php && exit 1 || :; \ 91 | docker-php-ext-install /tmp/imagick-3.7.0; \ 92 | rm -rf imagick.tgz /tmp/imagick-3.7.0; 93 | 94 | # Install igbinary PECL extension 95 | RUN pecl install igbinary \ 96 | && docker-php-ext-enable igbinary 97 | 98 | # Install xdebug PECL extension 99 | RUN pecl install xdebug 100 | 101 | # Install composer using the method described at https://getcomposer.org/download/ (TODO consider whether this is really necessary - we could remove from this image) 102 | RUN EXPECTED_SIGNATURE="$(curl https://composer.github.io/installer.sig)" \ 103 | && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ 104 | && ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" \ 105 | && if [ "$EXPECTED_SIGNATURE" != "${ACTUAL_SIGNATURE}" ]; then >&2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | ENV CIVICRM_UF=Drupal 165 | 166 | USER civicrm 167 | 168 | ENV PATH="/home/civicrm/.composer/vendor/bin:${PATH}" 169 | 170 | RUN cgr drush/drush:~8 171 | 172 | RUN drush dl drupal-7 --destination=/var/www --drupal-project-rename=html -y 173 | 174 | RUN mkdir /var/www/html/sites/default/files 175 | 176 | RUN cd /var/www/html/sites/all/modules \ 177 | && curl -L https://download.civicrm.org/civicrm-6.3.1-drupal.tar.gz > civicrm-drupal.tar.gz \ 178 | && tar xzf civicrm-drupal.tar.gz \ 179 | && rm civicrm-drupal.tar.gz 180 | 181 | RUN cd /var/www/html/sites/all/modules \ 182 | && curl -L https://download.civicrm.org/civicrm-6.3.1-l10n.tar.gz > civicrm-l10n.tar.gz \ 183 | && tar xzf civicrm-l10n.tar.gz \ 184 | && rm civicrm-l10n.tar.gz 185 | 186 | USER root 187 | 188 | COPY ./civicrm-docker-entrypoint ./civicrm-docker-init ./civicrm-docker-dump ./civicrm-docker-install /usr/local/bin/ 189 | 190 | COPY --chown=civicrm:civicrm ./settings.php /usr/local/etc/civicrm 191 | 192 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 193 | 194 | 195 | # Configure mysqldump 196 | 197 | COPY ./.my.cnf /home/civicrm/.my.cnf 198 | -------------------------------------------------------------------------------- /6/drupal/php8.1/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /6/drupal/php8.1/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'drupal' 13 | ], 14 | 'directories' => [ 15 | 'files' => '/var/www/html/sites/default/files' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | 22 | 23 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | # Initialise CiviCRM and Drupal ready for loading an existing state dump or a fresh installation. Destroys any existing data and files. 5 | # Called automatically by civicrm-docker-install. 6 | 7 | pushd /var/www/html/sites/default 8 | 9 | chmod u+w . 10 | for FILE in settings.php civicrm.settings.php; do 11 | if test -f "$FILE"; then 12 | chmod u+w $FILE 13 | fi 14 | cp /usr/local/etc/civicrm/$FILE . 15 | chmod a-wx $FILE 16 | done 17 | chmod u-w . 18 | popd 19 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | # Fresh install of CiviCRM on Drupal 4 | 5 | chmod +w /var/www/html/sites/default 6 | 7 | drush -r /var/www/html/ site-install -y 8 | drush dis overlay -y 9 | chmod u+w /var/www/html/sites/default/civicrm.settings.php 10 | cv core:install --settings-path=/var/www/html/sites/default/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 11 | chmod u-w /var/www/html/sites/default/civicrm.settings.php 12 | 13 | if test -x "/home/civicrm/postInstall"; then 14 | /home/civicrm/postInstall 15 | fi 16 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /6/drupal/php8.1/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /6/drupal/php8.1/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /6/drupal/php8.1/settings.php: -------------------------------------------------------------------------------- 1 | 4 | array( 5 | 'default' => 6 | array( 7 | 'database' => getenv('DRUPAL_DB_NAME'), 8 | 'username' => getenv('DRUPAL_DB_USER'), 9 | 'password' => getenv('DRUPAL_DB_PASS'), 10 | 'host' => getenv('DRUPAL_DB_HOST'), 11 | 'port' => getenv('DRUPAL_DB_PORT'), 12 | 'driver' => 'mysql', 13 | 'prefix' => '', 14 | ), 15 | ), 16 | ); 17 | 18 | $update_free_access = FALSE; 19 | 20 | $drupal_hash_salt = getenv('DRUPAL_HASH_SALT'); 21 | 22 | $base_url = getenv('BASE_URL'); 23 | 24 | ini_set('session.gc_probability', 1); 25 | ini_set('session.gc_divisor', 100); 26 | ini_set('session.gc_maxlifetime', 200000); 27 | ini_set('session.cookie_lifetime', 2000000); 28 | 29 | $conf['404_fast_paths_exclude'] = '/\/(?:styles)|(?:system\/files)\//'; 30 | $conf['404_fast_paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; 31 | $conf['404_fast_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; 32 | 33 | $conf['reverse_proxy'] = TRUE; 34 | $conf['reverse_proxy_addresses'] = [$_SERVER['REMOTE_ADDR']]; 35 | 36 | if (file_exists(__DIR__ . '/extra.settings.php')) { 37 | require_once __DIR__ . '/extra.settings.php'; 38 | } 39 | -------------------------------------------------------------------------------- /6/drupal/php8.2/.my.cnf: -------------------------------------------------------------------------------- 1 | [mysqldump] 2 | max_allowed_packet=1024M 3 | -------------------------------------------------------------------------------- /6/drupal/php8.2/Dockerfile: -------------------------------------------------------------------------------- 1 | ### THIS FILE GENERATED BY https://github.com/michaelmcandrew/civicrm-docker/blob/master/generate.py ### 2 | 3 | FROM php:8.2-apache-bookworm 4 | 5 | # libc-client-dev and libkrb5-dev required for the imap php extension 6 | # libicu-dev required for the intl php extension 7 | # libmagickwand-dev required for the imagick php extension 8 | # libjpeg62-turbo-dev and libpng-dev required for the gd php extension 9 | # libxml2-dev required for the soap php extension 10 | # iproute2 is required to get the host ip at runtime for XDEBUG_REMOTE_HOST environment variable 11 | # msmtp-mta allows us to globally redirect email via SMTP 12 | # unzip is required for composer 13 | 14 | RUN apt-get update \ 15 | && apt-get install -y --no-install-recommends \ 16 | imagemagick \ 17 | iproute2 \ 18 | less \ 19 | libc-client-dev \ 20 | libicu-dev \ 21 | libjpeg62-turbo-dev \ 22 | libkrb5-dev \ 23 | libmagickwand-dev \ 24 | libpng-dev \ 25 | libxml2-dev \ 26 | libzip-dev \ 27 | msmtp-mta \ 28 | mariadb-client \ 29 | unzip \ 30 | wget \ 31 | && rm -r /var/lib/apt/lists/* 32 | 33 | # CiviCRM requires the following PHP extensions (some of which are already 34 | # enabled in the Docker image): 35 | # 36 | # * curl (already enabled) 37 | # * gd 38 | # * gettext 39 | # * imagick 40 | # * imap 41 | # * intl 42 | # * json (already enabled) 43 | # * mbstring (already enabled) 44 | # * mysqli 45 | # * openssl (already enabled) 46 | # * pdo_mysql 47 | # * phar (already enabled) 48 | # * posix (already enabled) 49 | # * soap 50 | # * zip 51 | 52 | # WordPress recommends the following PHP extensions in addition to 53 | # the ones listed above: 54 | # 55 | # * dom (already enabled) 56 | # * exif 57 | # * fileinfo (already enabled) 58 | # * hash (already enabled) 59 | # * igbinary 60 | # * imagick 61 | # * pcre (already enabled) 62 | # * xml (already enabled) 63 | 64 | # Configure and install php extensions (note configuration comes before installation) 65 | 66 | RUN docker-php-ext-install bcmath \ 67 | && docker-php-ext-install exif \ 68 | && docker-php-ext-configure gd --with-jpeg \ 69 | && docker-php-ext-install gd \ 70 | && docker-php-ext-install gettext \ 71 | && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ 72 | && docker-php-ext-install imap \ 73 | && docker-php-ext-install intl \ 74 | && docker-php-ext-install mysqli \ 75 | && docker-php-ext-install opcache \ 76 | && docker-php-ext-install pdo_mysql \ 77 | && docker-php-ext-install soap \ 78 | && docker-php-ext-install zip 79 | 80 | # Install and enable imagick PECL extensions 81 | 82 | # Copy pasta from https://github.com/docker-library/wordpress/blob/3f1a0cab9f2f938bbc57f5f92ec11eeea4511636/latest/php8.3/fpm-alpine/Dockerfile#L47-L51 83 | # Based on suggestion here: https://github.com/docker-library/php/issues/1532#issuecomment-2258777719 84 | RUN curl -fL -o imagick.tgz 'https://pecl.php.net/get/imagick-3.7.0.tgz'; \ 85 | echo '5a364354109029d224bcbb2e82e15b248be9b641227f45e63425c06531792d3e *imagick.tgz' | sha256sum -c -; \ 86 | tar --extract --directory /tmp --file imagick.tgz imagick-3.7.0; \ 87 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php; \ 88 | test "$(grep -c '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php)" = '1'; \ 89 | sed -i -e 's!^//#endif$!#endif!' /tmp/imagick-3.7.0/Imagick.stub.php; \ 90 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php && exit 1 || :; \ 91 | docker-php-ext-install /tmp/imagick-3.7.0; \ 92 | rm -rf imagick.tgz /tmp/imagick-3.7.0; 93 | 94 | # Install igbinary PECL extension 95 | RUN pecl install igbinary \ 96 | && docker-php-ext-enable igbinary 97 | 98 | # Install xdebug PECL extension 99 | RUN pecl install xdebug 100 | 101 | # Install composer using the method described at https://getcomposer.org/download/ (TODO consider whether this is really necessary - we could remove from this image) 102 | RUN EXPECTED_SIGNATURE="$(curl https://composer.github.io/installer.sig)" \ 103 | && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ 104 | && ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" \ 105 | && if [ "$EXPECTED_SIGNATURE" != "${ACTUAL_SIGNATURE}" ]; then >&2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | ENV CIVICRM_UF=Drupal 165 | 166 | USER civicrm 167 | 168 | ENV PATH="/home/civicrm/.composer/vendor/bin:${PATH}" 169 | 170 | RUN cgr drush/drush:~8 171 | 172 | RUN drush dl drupal-7 --destination=/var/www --drupal-project-rename=html -y 173 | 174 | RUN mkdir /var/www/html/sites/default/files 175 | 176 | RUN cd /var/www/html/sites/all/modules \ 177 | && curl -L https://download.civicrm.org/civicrm-6.3.1-drupal.tar.gz > civicrm-drupal.tar.gz \ 178 | && tar xzf civicrm-drupal.tar.gz \ 179 | && rm civicrm-drupal.tar.gz 180 | 181 | RUN cd /var/www/html/sites/all/modules \ 182 | && curl -L https://download.civicrm.org/civicrm-6.3.1-l10n.tar.gz > civicrm-l10n.tar.gz \ 183 | && tar xzf civicrm-l10n.tar.gz \ 184 | && rm civicrm-l10n.tar.gz 185 | 186 | USER root 187 | 188 | COPY ./civicrm-docker-entrypoint ./civicrm-docker-init ./civicrm-docker-dump ./civicrm-docker-install /usr/local/bin/ 189 | 190 | COPY --chown=civicrm:civicrm ./settings.php /usr/local/etc/civicrm 191 | 192 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 193 | 194 | 195 | # Configure mysqldump 196 | 197 | COPY ./.my.cnf /home/civicrm/.my.cnf 198 | -------------------------------------------------------------------------------- /6/drupal/php8.2/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /6/drupal/php8.2/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'drupal' 13 | ], 14 | 'directories' => [ 15 | 'files' => '/var/www/html/sites/default/files' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | 22 | 23 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | # Initialise CiviCRM and Drupal ready for loading an existing state dump or a fresh installation. Destroys any existing data and files. 5 | # Called automatically by civicrm-docker-install. 6 | 7 | pushd /var/www/html/sites/default 8 | 9 | chmod u+w . 10 | for FILE in settings.php civicrm.settings.php; do 11 | if test -f "$FILE"; then 12 | chmod u+w $FILE 13 | fi 14 | cp /usr/local/etc/civicrm/$FILE . 15 | chmod a-wx $FILE 16 | done 17 | chmod u-w . 18 | popd 19 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | # Fresh install of CiviCRM on Drupal 4 | 5 | chmod +w /var/www/html/sites/default 6 | 7 | drush -r /var/www/html/ site-install -y 8 | drush dis overlay -y 9 | chmod u+w /var/www/html/sites/default/civicrm.settings.php 10 | cv core:install --settings-path=/var/www/html/sites/default/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 11 | chmod u-w /var/www/html/sites/default/civicrm.settings.php 12 | 13 | if test -x "/home/civicrm/postInstall"; then 14 | /home/civicrm/postInstall 15 | fi 16 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /6/drupal/php8.2/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /6/drupal/php8.2/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /6/drupal/php8.2/settings.php: -------------------------------------------------------------------------------- 1 | 4 | array( 5 | 'default' => 6 | array( 7 | 'database' => getenv('DRUPAL_DB_NAME'), 8 | 'username' => getenv('DRUPAL_DB_USER'), 9 | 'password' => getenv('DRUPAL_DB_PASS'), 10 | 'host' => getenv('DRUPAL_DB_HOST'), 11 | 'port' => getenv('DRUPAL_DB_PORT'), 12 | 'driver' => 'mysql', 13 | 'prefix' => '', 14 | ), 15 | ), 16 | ); 17 | 18 | $update_free_access = FALSE; 19 | 20 | $drupal_hash_salt = getenv('DRUPAL_HASH_SALT'); 21 | 22 | $base_url = getenv('BASE_URL'); 23 | 24 | ini_set('session.gc_probability', 1); 25 | ini_set('session.gc_divisor', 100); 26 | ini_set('session.gc_maxlifetime', 200000); 27 | ini_set('session.cookie_lifetime', 2000000); 28 | 29 | $conf['404_fast_paths_exclude'] = '/\/(?:styles)|(?:system\/files)\//'; 30 | $conf['404_fast_paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; 31 | $conf['404_fast_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; 32 | 33 | $conf['reverse_proxy'] = TRUE; 34 | $conf['reverse_proxy_addresses'] = [$_SERVER['REMOTE_ADDR']]; 35 | 36 | if (file_exists(__DIR__ . '/extra.settings.php')) { 37 | require_once __DIR__ . '/extra.settings.php'; 38 | } 39 | -------------------------------------------------------------------------------- /6/drupal/php8.3/.my.cnf: -------------------------------------------------------------------------------- 1 | [mysqldump] 2 | max_allowed_packet=1024M 3 | -------------------------------------------------------------------------------- /6/drupal/php8.3/Dockerfile: -------------------------------------------------------------------------------- 1 | ### THIS FILE GENERATED BY https://github.com/michaelmcandrew/civicrm-docker/blob/master/generate.py ### 2 | 3 | FROM php:8.3-apache-bookworm 4 | 5 | # libc-client-dev and libkrb5-dev required for the imap php extension 6 | # libicu-dev required for the intl php extension 7 | # libmagickwand-dev required for the imagick php extension 8 | # libjpeg62-turbo-dev and libpng-dev required for the gd php extension 9 | # libxml2-dev required for the soap php extension 10 | # iproute2 is required to get the host ip at runtime for XDEBUG_REMOTE_HOST environment variable 11 | # msmtp-mta allows us to globally redirect email via SMTP 12 | # unzip is required for composer 13 | 14 | RUN apt-get update \ 15 | && apt-get install -y --no-install-recommends \ 16 | imagemagick \ 17 | iproute2 \ 18 | less \ 19 | libc-client-dev \ 20 | libicu-dev \ 21 | libjpeg62-turbo-dev \ 22 | libkrb5-dev \ 23 | libmagickwand-dev \ 24 | libpng-dev \ 25 | libxml2-dev \ 26 | libzip-dev \ 27 | msmtp-mta \ 28 | mariadb-client \ 29 | unzip \ 30 | wget \ 31 | && rm -r /var/lib/apt/lists/* 32 | 33 | # CiviCRM requires the following PHP extensions (some of which are already 34 | # enabled in the Docker image): 35 | # 36 | # * curl (already enabled) 37 | # * gd 38 | # * gettext 39 | # * imagick 40 | # * imap 41 | # * intl 42 | # * json (already enabled) 43 | # * mbstring (already enabled) 44 | # * mysqli 45 | # * openssl (already enabled) 46 | # * pdo_mysql 47 | # * phar (already enabled) 48 | # * posix (already enabled) 49 | # * soap 50 | # * zip 51 | 52 | # WordPress recommends the following PHP extensions in addition to 53 | # the ones listed above: 54 | # 55 | # * dom (already enabled) 56 | # * exif 57 | # * fileinfo (already enabled) 58 | # * hash (already enabled) 59 | # * igbinary 60 | # * imagick 61 | # * pcre (already enabled) 62 | # * xml (already enabled) 63 | 64 | # Configure and install php extensions (note configuration comes before installation) 65 | 66 | RUN docker-php-ext-install bcmath \ 67 | && docker-php-ext-install exif \ 68 | && docker-php-ext-configure gd --with-jpeg \ 69 | && docker-php-ext-install gd \ 70 | && docker-php-ext-install gettext \ 71 | && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ 72 | && docker-php-ext-install imap \ 73 | && docker-php-ext-install intl \ 74 | && docker-php-ext-install mysqli \ 75 | && docker-php-ext-install opcache \ 76 | && docker-php-ext-install pdo_mysql \ 77 | && docker-php-ext-install soap \ 78 | && docker-php-ext-install zip 79 | 80 | # Install and enable imagick PECL extensions 81 | 82 | # Copy pasta from https://github.com/docker-library/wordpress/blob/3f1a0cab9f2f938bbc57f5f92ec11eeea4511636/latest/php8.3/fpm-alpine/Dockerfile#L47-L51 83 | # Based on suggestion here: https://github.com/docker-library/php/issues/1532#issuecomment-2258777719 84 | RUN curl -fL -o imagick.tgz 'https://pecl.php.net/get/imagick-3.7.0.tgz'; \ 85 | echo '5a364354109029d224bcbb2e82e15b248be9b641227f45e63425c06531792d3e *imagick.tgz' | sha256sum -c -; \ 86 | tar --extract --directory /tmp --file imagick.tgz imagick-3.7.0; \ 87 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php; \ 88 | test "$(grep -c '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php)" = '1'; \ 89 | sed -i -e 's!^//#endif$!#endif!' /tmp/imagick-3.7.0/Imagick.stub.php; \ 90 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php && exit 1 || :; \ 91 | docker-php-ext-install /tmp/imagick-3.7.0; \ 92 | rm -rf imagick.tgz /tmp/imagick-3.7.0; 93 | 94 | # Install igbinary PECL extension 95 | RUN pecl install igbinary \ 96 | && docker-php-ext-enable igbinary 97 | 98 | # Install xdebug PECL extension 99 | RUN pecl install xdebug 100 | 101 | # Install composer using the method described at https://getcomposer.org/download/ (TODO consider whether this is really necessary - we could remove from this image) 102 | RUN EXPECTED_SIGNATURE="$(curl https://composer.github.io/installer.sig)" \ 103 | && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ 104 | && ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" \ 105 | && if [ "$EXPECTED_SIGNATURE" != "${ACTUAL_SIGNATURE}" ]; then >&2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | ENV CIVICRM_UF=Drupal 165 | 166 | USER civicrm 167 | 168 | ENV PATH="/home/civicrm/.composer/vendor/bin:${PATH}" 169 | 170 | RUN cgr drush/drush:~8 171 | 172 | RUN drush dl drupal-7 --destination=/var/www --drupal-project-rename=html -y 173 | 174 | RUN mkdir /var/www/html/sites/default/files 175 | 176 | RUN cd /var/www/html/sites/all/modules \ 177 | && curl -L https://download.civicrm.org/civicrm-6.3.1-drupal.tar.gz > civicrm-drupal.tar.gz \ 178 | && tar xzf civicrm-drupal.tar.gz \ 179 | && rm civicrm-drupal.tar.gz 180 | 181 | RUN cd /var/www/html/sites/all/modules \ 182 | && curl -L https://download.civicrm.org/civicrm-6.3.1-l10n.tar.gz > civicrm-l10n.tar.gz \ 183 | && tar xzf civicrm-l10n.tar.gz \ 184 | && rm civicrm-l10n.tar.gz 185 | 186 | USER root 187 | 188 | COPY ./civicrm-docker-entrypoint ./civicrm-docker-init ./civicrm-docker-dump ./civicrm-docker-install /usr/local/bin/ 189 | 190 | COPY --chown=civicrm:civicrm ./settings.php /usr/local/etc/civicrm 191 | 192 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 193 | 194 | 195 | # Configure mysqldump 196 | 197 | COPY ./.my.cnf /home/civicrm/.my.cnf 198 | -------------------------------------------------------------------------------- /6/drupal/php8.3/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /6/drupal/php8.3/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'drupal' 13 | ], 14 | 'directories' => [ 15 | 'files' => '/var/www/html/sites/default/files' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | 22 | 23 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | # Initialise CiviCRM and Drupal ready for loading an existing state dump or a fresh installation. Destroys any existing data and files. 5 | # Called automatically by civicrm-docker-install. 6 | 7 | pushd /var/www/html/sites/default 8 | 9 | chmod u+w . 10 | for FILE in settings.php civicrm.settings.php; do 11 | if test -f "$FILE"; then 12 | chmod u+w $FILE 13 | fi 14 | cp /usr/local/etc/civicrm/$FILE . 15 | chmod a-wx $FILE 16 | done 17 | chmod u-w . 18 | popd 19 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | # Fresh install of CiviCRM on Drupal 4 | 5 | chmod +w /var/www/html/sites/default 6 | 7 | drush -r /var/www/html/ site-install -y 8 | drush dis overlay -y 9 | chmod u+w /var/www/html/sites/default/civicrm.settings.php 10 | cv core:install --settings-path=/var/www/html/sites/default/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 11 | chmod u-w /var/www/html/sites/default/civicrm.settings.php 12 | 13 | if test -x "/home/civicrm/postInstall"; then 14 | /home/civicrm/postInstall 15 | fi 16 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /6/drupal/php8.3/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /6/drupal/php8.3/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /6/drupal/php8.3/settings.php: -------------------------------------------------------------------------------- 1 | 4 | array( 5 | 'default' => 6 | array( 7 | 'database' => getenv('DRUPAL_DB_NAME'), 8 | 'username' => getenv('DRUPAL_DB_USER'), 9 | 'password' => getenv('DRUPAL_DB_PASS'), 10 | 'host' => getenv('DRUPAL_DB_HOST'), 11 | 'port' => getenv('DRUPAL_DB_PORT'), 12 | 'driver' => 'mysql', 13 | 'prefix' => '', 14 | ), 15 | ), 16 | ); 17 | 18 | $update_free_access = FALSE; 19 | 20 | $drupal_hash_salt = getenv('DRUPAL_HASH_SALT'); 21 | 22 | $base_url = getenv('BASE_URL'); 23 | 24 | ini_set('session.gc_probability', 1); 25 | ini_set('session.gc_divisor', 100); 26 | ini_set('session.gc_maxlifetime', 200000); 27 | ini_set('session.cookie_lifetime', 2000000); 28 | 29 | $conf['404_fast_paths_exclude'] = '/\/(?:styles)|(?:system\/files)\//'; 30 | $conf['404_fast_paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; 31 | $conf['404_fast_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; 32 | 33 | $conf['reverse_proxy'] = TRUE; 34 | $conf['reverse_proxy_addresses'] = [$_SERVER['REMOTE_ADDR']]; 35 | 36 | if (file_exists(__DIR__ . '/extra.settings.php')) { 37 | require_once __DIR__ . '/extra.settings.php'; 38 | } 39 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/.my.cnf: -------------------------------------------------------------------------------- 1 | [mysqldump] 2 | max_allowed_packet=1024M 3 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/Dockerfile: -------------------------------------------------------------------------------- 1 | ### THIS FILE GENERATED BY https://github.com/michaelmcandrew/civicrm-docker/blob/master/generate.py ### 2 | 3 | FROM php:8.1-apache-bookworm 4 | 5 | # libc-client-dev and libkrb5-dev required for the imap php extension 6 | # libicu-dev required for the intl php extension 7 | # libmagickwand-dev required for the imagick php extension 8 | # libjpeg62-turbo-dev and libpng-dev required for the gd php extension 9 | # libxml2-dev required for the soap php extension 10 | # iproute2 is required to get the host ip at runtime for XDEBUG_REMOTE_HOST environment variable 11 | # msmtp-mta allows us to globally redirect email via SMTP 12 | # unzip is required for composer 13 | 14 | RUN apt-get update \ 15 | && apt-get install -y --no-install-recommends \ 16 | imagemagick \ 17 | iproute2 \ 18 | less \ 19 | libc-client-dev \ 20 | libicu-dev \ 21 | libjpeg62-turbo-dev \ 22 | libkrb5-dev \ 23 | libmagickwand-dev \ 24 | libpng-dev \ 25 | libxml2-dev \ 26 | libzip-dev \ 27 | msmtp-mta \ 28 | mariadb-client \ 29 | unzip \ 30 | wget \ 31 | && rm -r /var/lib/apt/lists/* 32 | 33 | # CiviCRM requires the following PHP extensions (some of which are already 34 | # enabled in the Docker image): 35 | # 36 | # * curl (already enabled) 37 | # * gd 38 | # * gettext 39 | # * imagick 40 | # * imap 41 | # * intl 42 | # * json (already enabled) 43 | # * mbstring (already enabled) 44 | # * mysqli 45 | # * openssl (already enabled) 46 | # * pdo_mysql 47 | # * phar (already enabled) 48 | # * posix (already enabled) 49 | # * soap 50 | # * zip 51 | 52 | # WordPress recommends the following PHP extensions in addition to 53 | # the ones listed above: 54 | # 55 | # * dom (already enabled) 56 | # * exif 57 | # * fileinfo (already enabled) 58 | # * hash (already enabled) 59 | # * igbinary 60 | # * imagick 61 | # * pcre (already enabled) 62 | # * xml (already enabled) 63 | 64 | # Configure and install php extensions (note configuration comes before installation) 65 | 66 | RUN docker-php-ext-install bcmath \ 67 | && docker-php-ext-install exif \ 68 | && docker-php-ext-configure gd --with-jpeg \ 69 | && docker-php-ext-install gd \ 70 | && docker-php-ext-install gettext \ 71 | && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ 72 | && docker-php-ext-install imap \ 73 | && docker-php-ext-install intl \ 74 | && docker-php-ext-install mysqli \ 75 | && docker-php-ext-install opcache \ 76 | && docker-php-ext-install pdo_mysql \ 77 | && docker-php-ext-install soap \ 78 | && docker-php-ext-install zip 79 | 80 | # Install and enable imagick PECL extensions 81 | 82 | # Copy pasta from https://github.com/docker-library/wordpress/blob/3f1a0cab9f2f938bbc57f5f92ec11eeea4511636/latest/php8.3/fpm-alpine/Dockerfile#L47-L51 83 | # Based on suggestion here: https://github.com/docker-library/php/issues/1532#issuecomment-2258777719 84 | RUN curl -fL -o imagick.tgz 'https://pecl.php.net/get/imagick-3.7.0.tgz'; \ 85 | echo '5a364354109029d224bcbb2e82e15b248be9b641227f45e63425c06531792d3e *imagick.tgz' | sha256sum -c -; \ 86 | tar --extract --directory /tmp --file imagick.tgz imagick-3.7.0; \ 87 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php; \ 88 | test "$(grep -c '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php)" = '1'; \ 89 | sed -i -e 's!^//#endif$!#endif!' /tmp/imagick-3.7.0/Imagick.stub.php; \ 90 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php && exit 1 || :; \ 91 | docker-php-ext-install /tmp/imagick-3.7.0; \ 92 | rm -rf imagick.tgz /tmp/imagick-3.7.0; 93 | 94 | # Install igbinary PECL extension 95 | RUN pecl install igbinary \ 96 | && docker-php-ext-enable igbinary 97 | 98 | # Install xdebug PECL extension 99 | RUN pecl install xdebug 100 | 101 | # Install composer using the method described at https://getcomposer.org/download/ (TODO consider whether this is really necessary - we could remove from this image) 102 | RUN EXPECTED_SIGNATURE="$(curl https://composer.github.io/installer.sig)" \ 103 | && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ 104 | && ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" \ 105 | && if [ "$EXPECTED_SIGNATURE" != "${ACTUAL_SIGNATURE}" ]; then >&2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | ENV CIVICRM_UF=WordPress 165 | 166 | ARG CIVICRM_VERSION 167 | 168 | RUN curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp \ 169 | && chmod +x /usr/local/bin/wp 170 | 171 | USER civicrm 172 | 173 | RUN php -d memory_limit=1G /usr/local/bin/wp core download 174 | 175 | RUN mkdir /var/www/html/wp-content/uploads 176 | 177 | RUN cd /var/www/html/wp-content/plugins \ 178 | && curl -L https://download.civicrm.org/civicrm-6.3.1-wordpress.zip > civicrm-wordpress.zip \ 179 | && unzip civicrm-wordpress.zip \ 180 | && rm civicrm-wordpress.zip 181 | 182 | RUN cd /var/www/html/wp-content/plugins \ 183 | && curl -L https://download.civicrm.org/civicrm-6.3.1-l10n.tar.gz > civicrm-l10n.tar.gz \ 184 | && tar xzf civicrm-l10n.tar.gz \ 185 | && rm civicrm-l10n.tar.gz 186 | 187 | USER root 188 | 189 | COPY --chown=civicrm:civicrm \ 190 | ./civicrm-docker-entrypoint \ 191 | ./civicrm-docker-init \ 192 | ./civicrm-docker-dump \ 193 | ./civicrm-docker-install \ 194 | /usr/local/bin/ 195 | 196 | COPY --chown=civicrm:civicrm ./wp-config.php /usr/local/etc/civicrm 197 | 198 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 199 | 200 | # Configure mysqldump 201 | 202 | COPY ./.my.cnf /home/civicrm/.my.cnf 203 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'wordpress' 13 | ], 14 | 'directories' => [ 15 | 'uploads' => '/var/www/html/wp-content/uploads' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd /var/www/html 4 | 5 | chmod u+w . 6 | 7 | # WordPress settings 8 | [[ -f wp-config.php ]] && chmod u+w wp-config.php 9 | cp /usr/local/etc/civicrm/wp-config.php . 10 | chmod a-wx wp-config.php 11 | 12 | [[ -d /var/www/html/wp-content/uploads/civicrm ]] || mkdir -p /var/www/html/wp-content/uploads/civicrm 13 | 14 | pushd /var/www/html/wp-content/uploads/civicrm 15 | 16 | # CiviCRM settings 17 | chmod u+w . 18 | 19 | [[ -f civicrm.settings.php ]] && chmod u+w civicrm.settings.php 20 | cp /usr/local/etc/civicrm/civicrm.settings.php . 21 | chmod a-wx civicrm.settings.php 22 | 23 | popd 24 | 25 | popd 26 | 27 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | civicrm-docker-init 4 | 5 | pushd /var/www/html 6 | 7 | wp core install --url=$BASE_URL --title=$PROJECT_NAME --admin_user=admin --admin_email=admin@example.org 8 | 9 | # Prepare for CiviCRM install 10 | if test -f civicrm.settings.php; then 11 | chmod u+w civicrm.settings.php 12 | fi 13 | 14 | cv core:install --settings-path=/var/www/html/wp-content/uploads/civicrm/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 15 | wp plugin activate civicrm 16 | 17 | popd 18 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /6/wordpress/php8.1/wp-config.php: -------------------------------------------------------------------------------- 1 | &2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | ENV CIVICRM_UF=WordPress 165 | 166 | ARG CIVICRM_VERSION 167 | 168 | RUN curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp \ 169 | && chmod +x /usr/local/bin/wp 170 | 171 | USER civicrm 172 | 173 | RUN php -d memory_limit=1G /usr/local/bin/wp core download 174 | 175 | RUN mkdir /var/www/html/wp-content/uploads 176 | 177 | RUN cd /var/www/html/wp-content/plugins \ 178 | && curl -L https://download.civicrm.org/civicrm-6.3.1-wordpress.zip > civicrm-wordpress.zip \ 179 | && unzip civicrm-wordpress.zip \ 180 | && rm civicrm-wordpress.zip 181 | 182 | RUN cd /var/www/html/wp-content/plugins \ 183 | && curl -L https://download.civicrm.org/civicrm-6.3.1-l10n.tar.gz > civicrm-l10n.tar.gz \ 184 | && tar xzf civicrm-l10n.tar.gz \ 185 | && rm civicrm-l10n.tar.gz 186 | 187 | USER root 188 | 189 | COPY --chown=civicrm:civicrm \ 190 | ./civicrm-docker-entrypoint \ 191 | ./civicrm-docker-init \ 192 | ./civicrm-docker-dump \ 193 | ./civicrm-docker-install \ 194 | /usr/local/bin/ 195 | 196 | COPY --chown=civicrm:civicrm ./wp-config.php /usr/local/etc/civicrm 197 | 198 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 199 | 200 | # Configure mysqldump 201 | 202 | COPY ./.my.cnf /home/civicrm/.my.cnf 203 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'wordpress' 13 | ], 14 | 'directories' => [ 15 | 'uploads' => '/var/www/html/wp-content/uploads' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd /var/www/html 4 | 5 | chmod u+w . 6 | 7 | # WordPress settings 8 | [[ -f wp-config.php ]] && chmod u+w wp-config.php 9 | cp /usr/local/etc/civicrm/wp-config.php . 10 | chmod a-wx wp-config.php 11 | 12 | [[ -d /var/www/html/wp-content/uploads/civicrm ]] || mkdir -p /var/www/html/wp-content/uploads/civicrm 13 | 14 | pushd /var/www/html/wp-content/uploads/civicrm 15 | 16 | # CiviCRM settings 17 | chmod u+w . 18 | 19 | [[ -f civicrm.settings.php ]] && chmod u+w civicrm.settings.php 20 | cp /usr/local/etc/civicrm/civicrm.settings.php . 21 | chmod a-wx civicrm.settings.php 22 | 23 | popd 24 | 25 | popd 26 | 27 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | civicrm-docker-init 4 | 5 | pushd /var/www/html 6 | 7 | wp core install --url=$BASE_URL --title=$PROJECT_NAME --admin_user=admin --admin_email=admin@example.org 8 | 9 | # Prepare for CiviCRM install 10 | if test -f civicrm.settings.php; then 11 | chmod u+w civicrm.settings.php 12 | fi 13 | 14 | cv core:install --settings-path=/var/www/html/wp-content/uploads/civicrm/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 15 | wp plugin activate civicrm 16 | 17 | popd 18 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /6/wordpress/php8.2/wp-config.php: -------------------------------------------------------------------------------- 1 | &2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | ENV CIVICRM_UF=WordPress 165 | 166 | ARG CIVICRM_VERSION 167 | 168 | RUN curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp \ 169 | && chmod +x /usr/local/bin/wp 170 | 171 | USER civicrm 172 | 173 | RUN php -d memory_limit=1G /usr/local/bin/wp core download 174 | 175 | RUN mkdir /var/www/html/wp-content/uploads 176 | 177 | RUN cd /var/www/html/wp-content/plugins \ 178 | && curl -L https://download.civicrm.org/civicrm-6.3.1-wordpress.zip > civicrm-wordpress.zip \ 179 | && unzip civicrm-wordpress.zip \ 180 | && rm civicrm-wordpress.zip 181 | 182 | RUN cd /var/www/html/wp-content/plugins \ 183 | && curl -L https://download.civicrm.org/civicrm-6.3.1-l10n.tar.gz > civicrm-l10n.tar.gz \ 184 | && tar xzf civicrm-l10n.tar.gz \ 185 | && rm civicrm-l10n.tar.gz 186 | 187 | USER root 188 | 189 | COPY --chown=civicrm:civicrm \ 190 | ./civicrm-docker-entrypoint \ 191 | ./civicrm-docker-init \ 192 | ./civicrm-docker-dump \ 193 | ./civicrm-docker-install \ 194 | /usr/local/bin/ 195 | 196 | COPY --chown=civicrm:civicrm ./wp-config.php /usr/local/etc/civicrm 197 | 198 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 199 | 200 | # Configure mysqldump 201 | 202 | COPY ./.my.cnf /home/civicrm/.my.cnf 203 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'wordpress' 13 | ], 14 | 'directories' => [ 15 | 'uploads' => '/var/www/html/wp-content/uploads' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd /var/www/html 4 | 5 | chmod u+w . 6 | 7 | # WordPress settings 8 | [[ -f wp-config.php ]] && chmod u+w wp-config.php 9 | cp /usr/local/etc/civicrm/wp-config.php . 10 | chmod a-wx wp-config.php 11 | 12 | [[ -d /var/www/html/wp-content/uploads/civicrm ]] || mkdir -p /var/www/html/wp-content/uploads/civicrm 13 | 14 | pushd /var/www/html/wp-content/uploads/civicrm 15 | 16 | # CiviCRM settings 17 | chmod u+w . 18 | 19 | [[ -f civicrm.settings.php ]] && chmod u+w civicrm.settings.php 20 | cp /usr/local/etc/civicrm/civicrm.settings.php . 21 | chmod a-wx civicrm.settings.php 22 | 23 | popd 24 | 25 | popd 26 | 27 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | civicrm-docker-init 4 | 5 | pushd /var/www/html 6 | 7 | wp core install --url=$BASE_URL --title=$PROJECT_NAME --admin_user=admin --admin_email=admin@example.org 8 | 9 | # Prepare for CiviCRM install 10 | if test -f civicrm.settings.php; then 11 | chmod u+w civicrm.settings.php 12 | fi 13 | 14 | cv core:install --settings-path=/var/www/html/wp-content/uploads/civicrm/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 15 | wp plugin activate civicrm 16 | 17 | popd 18 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /6/wordpress/php8.3/wp-config.php: -------------------------------------------------------------------------------- 1 | 16 | - 6, 6-php8.3, 6-wordpress, 6-wordpress-php8.3, 6.3, 6.3-php8.3, 6.3-wordpress, 6.3-wordpress-php8.3, 6.3.1, 6.3.1-php8.3, 6.3.1-wordpress, 6.3.1-wordpress-php8.3, latest, php8.3, wordpress, wordpress-php8.3 [6/wordpress/php8.3](6/wordpress/php8.3) 17 | - 6-php8.2, 6-wordpress-php8.2, 6.3-php8.2, 6.3-wordpress-php8.2, 6.3.1-php8.2, 6.3.1-wordpress-php8.2, php8.2, wordpress-php8.2 [6/wordpress/php8.2](6/wordpress/php8.2) 18 | - 6-php8.1, 6-wordpress-php8.1, 6.3-php8.1, 6.3-wordpress-php8.1, 6.3.1-php8.1, 6.3.1-wordpress-php8.1, php8.1, wordpress-php8.1 [6/wordpress/php8.1](6/wordpress/php8.1) 19 | - 6-drupal, 6-drupal-php8.3, 6.3-drupal, 6.3-drupal-php8.3, 6.3.1-drupal, 6.3.1-drupal-php8.3, drupal, drupal-php8.3 [6/drupal/php8.3](6/drupal/php8.3) 20 | - 6-drupal-php8.2, 6.3-drupal-php8.2, 6.3.1-drupal-php8.2, drupal-php8.2 [6/drupal/php8.2](6/drupal/php8.2) 21 | - 6-drupal-php8.1, 6.3-drupal-php8.1, 6.3.1-drupal-php8.1, drupal-php8.1 [6/drupal/php8.1](6/drupal/php8.1) 22 | 23 | 24 | ## 'Quick' start 25 | 26 | There are a couple of options for getting started. Here are a couple of common workflows that I use. 27 | 28 | If I plan on doing a fair amount of custom development as part of a project, I like to start with a 'mono repo' on the host machine containing everything from the CMS root downwards (excluding files with credentials in and folders that include uploads via the web server). This makes working with IDEs, debugging, etc. easier. 29 | 30 | If you aren't planning on doing much custom development (e.g. maybe you are just installing already existing modules and extensions) it might make more sense to take advantage of the CMS and CiviCRM already installed on the image (at `/var/www/html`). 31 | 32 | To get a local project up and running, choose your CMS flavour from the [docker-compose](docker-compose) and copy the entire directory to somewhere like `~/projects/backdrop-example-project` 33 | 34 | 1. Copy the `dev.dist.env` file to `.env`. and edit as appropriate (choose sensible passwords, set the base url and other required environment variables, e.g. the domain you want the site to be available at. 35 | 2. Copy `docker-compose.dev.dist.yml` to `docker-compose.yml` and assign port numbers as appropriate (see _Reverse proxies_ for more details). 36 | 3. _If you are mounting a mono repo from the host to the container_ (see above), place it in the `src` folder, and uncomment the `./src:/var/www/html` volume. 37 | 4. _If you want development site to be available at a memorable address and/or you want to serve it via https_, configure it now. 38 | 5. Run `docker-compose up -d` 39 | 6. Install a new site with something like `docker-compose exec civicrm civicrm-docker-install` . 40 | 41 | Note that if you already have a dump containing the database and file dump (in the format expected by civicrm-docker) you do not need to install the CMS and CiviCRM. You can just initialise it with `docker-compose exec civicrm civicrm-docker-install` and then follow the load instructions below. 42 | 43 | ## Dumping state 44 | 45 | Running `docker-compose exec civicrm civicrm-docker-dump` will place a database and file dump in the `/state` folder of the container (which is mapped to the `./state` sub-folder in your docker-compose root on the host). 46 | 47 | ## Loading state 48 | 49 | Running `docker-compose exec civicrm civicrm-docker-load` will load an existing database dump from the `/state` folder of the container (which is mapped to the `./state` sub-folder in your docker-compose root on the host. 50 | 51 | # MySQL 52 | 53 | The images are MySQL flavour agnostic. 54 | 55 | ## Administration 56 | 57 | To update the images on Docker Hub that are defined in this repository, run the `update.php` script. 58 | 59 | This calls the following processes in order: 60 | 61 | - `generate.php` automates the generation of Dockerfiles (updates combos.json). 62 | - `buildAndPublish.php` builds images based on the dockerfiles (based on combos.json) and publishes them. 63 | 64 | Note: The `buildAndPublish.php` script publishes multi-architecture images to docker hub using commands that look like this: 65 | 66 | `docker build --builder amd_and_arm --platform linux/amd64,linux/arm64 --tag image:1 --tag image:1.0 --push` 67 | 68 | Hence, you'll need to run this on a host that can build `linux/arm64` and `linux/amd64` images. You'll also need to set up a builder called `amd_and_arm`. 69 | 70 | Note:`update.php` also pulls from and pushes to the various repositories for this code (3SD's Gitlab, CiviCRM's Gitlab, and Github). 71 | 72 | ### Configuring multiple native nodes 73 | 74 | 1. Choose a primary Docker instance that will run the build (and not the platform architecture) 75 | 2. Create other Docker instances that can build natively on the other architectures that you want. For example if you want to build for `amd` and `arm`, and your primary Docker instance is on `arm`, then create a docker instance on an `amd` machine. 76 | 3. Create a *Context* on the primary machine that allows you to access the other Docker service with `docker context create --docker "host=ssh://"`. You can test that this worked by listing docker images using the other services' context, e.g. `docker --context= image ls` should show images on the other service. It should also have created a builder on the primary machine which you can see with `docker builder ls`. 77 | 4. Create a builder that can build for both architectures with the following commands (assuming you are on `arm` and the other context is on `amd`) 78 | 5. `docker buildx create --platform arm64 --name amd_and_arm` creates a new context 79 | 6. `docker buildx create --platform amd64 --append --name amd_and_arm ` appends the amd builder. 80 | 7. Test all is as it should be with `docker builder ls`. It should output something like the following: 81 | Buildkit 82 | 83 | ``` 84 | NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS 85 | amd_and_arm docker-container 86 | \_ amd_and_arm0 \_ unix:///var/run/docker.sock running v0.15.2 linux/arm64*, linux/arm/v7, linux/arm/v6 87 | \_ amd_and_arm1 \_ almond running v0.15.2 linux/amd64*, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386 88 | ``` 89 | 90 | ### Building for multiple architectures 91 | 92 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | * Work out if we really need to set the CIVICRM_UF environment variable in the CMS specific parts of the Dockerfile, and remove if not. 4 | * Order combinations and tags sensibly 5 | * Auto generate tags file 6 | * Auto generate docker-compose files 7 | * Incorporate docs/getting-started.md into README.md 8 | * Get really accurate about the responsibilities of init, and install so they can work OK in different db environments 9 | * Document the new ideas around MySQL 10 | -------------------------------------------------------------------------------- /bin/civicrm-docker-dump-manual: -------------------------------------------------------------------------------- 1 | #!/bin/env php 2 | $database) { 28 | // TODO: consider compressing these while in transit 29 | if (isset($database['defaults_extra_file'])) { 30 | $lines[] = "ssh {$projectName} mysqldump --defaults-extra-file={$database['defaults_extra_file']} --single-transaction --skip-triggers {$database['name']} > {$tempDir}/{$dbKey}.sql"; 31 | } else { 32 | $lines[] = "ssh {$projectName} mysqldump --single-transaction --skip-triggers {$database['name']} > {$tempDir}/{$dbKey}.sql"; 33 | } 34 | } 35 | 36 | // Tar files 37 | foreach ($definition['directories'] as $dirKey => $directory) { 38 | $lines[] = "ssh {$projectName} tar -cz -C {$directory['src']} . > {$tempDir}/{$dirKey}.tar.gz"; 39 | } 40 | 41 | // Generate state.json 42 | $lines[] = "cat << EOF > {$tempDir}/state.json"; 43 | $state = [ 44 | 'project' => $projectName, 45 | 'databases' => array_keys($definition['databases']), 46 | 'directories' => array_map(function ($dir) { 47 | return $dir['dest']; 48 | }, $definition['directories']), 49 | ]; 50 | $lines[] = json_encode($state, JSON_PRETTY_PRINT); 51 | $lines[] = "EOF"; 52 | $lines[] = "OUTFILE={$projectName}.$(date +%Y%m%dT%H%M%S).tar.gz"; 53 | $lines[] = "tar -cz -C {$tempDir} . -f {$pwd}/state/\${OUTFILE}"; 54 | $lines[] = "echo \$OUTFILE"; 55 | $lines[] = "rm -rf {$tempDir}"; 56 | 57 | // Abort if we have encountered any errors (e.g. due to missing variables in 58 | // the json definition, etc.) 59 | if (error_get_last()) { 60 | echo "Some errors occured - aborting manual dump.\n"; 61 | exit; 62 | } 63 | $commands = implode("\n", $lines); 64 | 65 | $options = getopt('d'); 66 | if(!isset($options['d'])){ 67 | file_put_contents($dumpScript, $commands . "\n"); 68 | passthru("bash $dumpScript"); 69 | unlink($dumpScript); 70 | }else{ 71 | echo $commands; 72 | } 73 | -------------------------------------------------------------------------------- /bin/civicrm-docker-lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # check that we have a src/wordpress directory 4 | # check that 3sd is in the mu plugins list and is at least v ? 5 | 6 | 7 | # if we are in WordPress, check that we are git ignoring the src/wordpress/wp-content/uploads directory v czc 8 | import yaml 9 | 10 | with open("docker-compose.dev.yml", "r") as stream: 11 | try: 12 | print(yaml.safe_load(stream)["version"]) 13 | except yaml.YAMLError as exc: 14 | print(exc) 15 | -------------------------------------------------------------------------------- /bin/gen-secret-keys: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 'CIVICRM_SITE_KEY', 11 | 'command' => 'pwgen -snc 32 1', 12 | 'prefix' => 'CIVICRM_SITE_KEY=' 13 | ], [ 14 | 'name' => 'CIVICRM_CRED_KEYS', 15 | 'command' => 'head -c32 /dev/urandom | base64', 16 | 'prefix' => 'CIVICRM_CRED_KEYS=aes-cbc::' 17 | ], [ 18 | 'name' => 'CIVICRM_SIGN_KEYS', 19 | 'command' => 'head -c32 /dev/urandom | base64', 20 | 'prefix' => 'CIVICRM_SIGN_KEYS=jwt-hs256::' 21 | ] 22 | ]; 23 | 24 | foreach ($vars as $k => $var) { 25 | unset($result); 26 | exec($var['command'], $result, $result_code); 27 | if ($result_code) { 28 | echo "Error generating CIVICRM_SITE_KEY using command: {$var['command']}\n"; 29 | exit(1); 30 | }else{ 31 | $vars[$k]['result']=$result[0]; 32 | } 33 | } 34 | 35 | foreach ($vars as $var) { 36 | echo "{$var['prefix']}{$var['result']}\n"; 37 | } 38 | -------------------------------------------------------------------------------- /bin/gen-wordpress-keys: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | ~`+=,.;:/?|'; 14 | } 15 | 16 | $password = ''; 17 | for ( $i = 0; $i < $length; $i++ ) { 18 | $password .= substr( $chars, random_int( 0, strlen( $chars ) - 1 ), 1 ); 19 | } 20 | 21 | return $password; 22 | } 23 | 24 | $prefix = 'WORDPRESS'; 25 | $name = ['AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET']; 26 | $type = ['KEY', 'SALT']; 27 | foreach ( $name as $first ) { 28 | foreach ( $type as $second ) { 29 | $key = wp_generate_password( 64, true, true ); 30 | echo "{$prefix}_{$first}_{$second}='{$key}'\n"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /buildAndPublish.php: -------------------------------------------------------------------------------- 1 | "--tag $imageName:$t", $image->tags)); 12 | $dir = __DIR__ . '/' . $image->dir; 13 | // TODO: save the planet - do more caching. 14 | $commands[] = "docker build --pull --builder $builder --platform $platforms $dir $tags --push"; 15 | } 16 | foreach ($commands as $command) { 17 | `$command`; 18 | } 19 | -------------------------------------------------------------------------------- /combos.json: -------------------------------------------------------------------------------- 1 | { 2 | "6.3.1/wordpress/8.3": { 3 | "dir": "6/wordpress/php8.3", 4 | "tags": [ 5 | "6", 6 | "6-php8.3", 7 | "6-wordpress", 8 | "6-wordpress-php8.3", 9 | "6.3", 10 | "6.3-php8.3", 11 | "6.3-wordpress", 12 | "6.3-wordpress-php8.3", 13 | "6.3.1", 14 | "6.3.1-php8.3", 15 | "6.3.1-wordpress", 16 | "6.3.1-wordpress-php8.3", 17 | "latest", 18 | "php8.3", 19 | "wordpress", 20 | "wordpress-php8.3" 21 | ], 22 | "variables": { 23 | "civi": "6.3.1", 24 | "cms": "wordpress", 25 | "php": "8.3" 26 | } 27 | }, 28 | "6.3.1/wordpress/8.2": { 29 | "dir": "6/wordpress/php8.2", 30 | "tags": [ 31 | "6-php8.2", 32 | "6-wordpress-php8.2", 33 | "6.3-php8.2", 34 | "6.3-wordpress-php8.2", 35 | "6.3.1-php8.2", 36 | "6.3.1-wordpress-php8.2", 37 | "php8.2", 38 | "wordpress-php8.2" 39 | ], 40 | "variables": { 41 | "civi": "6.3.1", 42 | "cms": "wordpress", 43 | "php": "8.2" 44 | } 45 | }, 46 | "6.3.1/wordpress/8.1": { 47 | "dir": "6/wordpress/php8.1", 48 | "tags": [ 49 | "6-php8.1", 50 | "6-wordpress-php8.1", 51 | "6.3-php8.1", 52 | "6.3-wordpress-php8.1", 53 | "6.3.1-php8.1", 54 | "6.3.1-wordpress-php8.1", 55 | "php8.1", 56 | "wordpress-php8.1" 57 | ], 58 | "variables": { 59 | "civi": "6.3.1", 60 | "cms": "wordpress", 61 | "php": "8.1" 62 | } 63 | }, 64 | "6.3.1/drupal/8.3": { 65 | "dir": "6/drupal/php8.3", 66 | "tags": [ 67 | "6-drupal", 68 | "6-drupal-php8.3", 69 | "6.3-drupal", 70 | "6.3-drupal-php8.3", 71 | "6.3.1-drupal", 72 | "6.3.1-drupal-php8.3", 73 | "drupal", 74 | "drupal-php8.3" 75 | ], 76 | "variables": { 77 | "civi": "6.3.1", 78 | "cms": "drupal", 79 | "php": "8.3" 80 | } 81 | }, 82 | "6.3.1/drupal/8.2": { 83 | "dir": "6/drupal/php8.2", 84 | "tags": [ 85 | "6-drupal-php8.2", 86 | "6.3-drupal-php8.2", 87 | "6.3.1-drupal-php8.2", 88 | "drupal-php8.2" 89 | ], 90 | "variables": { 91 | "civi": "6.3.1", 92 | "cms": "drupal", 93 | "php": "8.2" 94 | } 95 | }, 96 | "6.3.1/drupal/8.1": { 97 | "dir": "6/drupal/php8.1", 98 | "tags": [ 99 | "6-drupal-php8.1", 100 | "6.3-drupal-php8.1", 101 | "6.3.1-drupal-php8.1", 102 | "drupal-php8.1" 103 | ], 104 | "variables": { 105 | "civi": "6.3.1", 106 | "cms": "drupal", 107 | "php": "8.1" 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /docker-compose/README.md: -------------------------------------------------------------------------------- 1 | # Docker compose example files 2 | 3 | Use these as a starting point for your running sites with docker-compose. -------------------------------------------------------------------------------- /docker-compose/backdrop/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | state 3 | .bash_history 4 | docker-compose.yml 5 | -------------------------------------------------------------------------------- /docker-compose/backdrop/dev.dist.env: -------------------------------------------------------------------------------- 1 | PROJECT_NAME=example 2 | BASE_URL=http://localhost:NNNN 3 | 4 | CIVICRM_DB_NAME=civicrm 5 | CIVICRM_DB_USER=civicrm 6 | CIVICRM_DB_PASS=xxx 7 | CIVICRM_DB_HOST=mysql 8 | CIVICRM_DB_PORT=3306 9 | 10 | BACKDROP_DB_NAME=backdrop 11 | BACKDROP_DB_USER=backdrop 12 | BACKDROP_DB_PASS=xxx 13 | BACKDROP_DB_HOST=mysql 14 | BACKDROP_DB_PORT=3306 15 | 16 | CIVICRM_SITE_KEY 17 | 18 | SMTP_HOST=maildev 19 | SMTP_MAILDOMAIN=example.org 20 | 21 | PHP_DATE_TIMEZONE="UTC" 22 | -------------------------------------------------------------------------------- /docker-compose/backdrop/docker-compose.dev.dist.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | services: 3 | civicrm: 4 | image: michaelmcandrew/civicrm:backdrop 5 | hostname: $PROJECT_NAME 6 | environment: 7 | - APACHE_RUN_USER=civicrm 8 | - PROJECT_NAME 9 | - BASE_URL 10 | - CIVICRM_DB_NAME 11 | - CIVICRM_DB_USER 12 | - CIVICRM_DB_PASS 13 | - CIVICRM_DB_HOST 14 | - CIVICRM_DB_PORT 15 | - BACKDROP_DB_NAME 16 | - BACKDROP_DB_USER 17 | - BACKDROP_DB_PASS 18 | - BACKDROP_DB_HOST 19 | - BACKDROP_DB_PORT 20 | - DEBUG=ON 21 | - SMTP_HOST 22 | - SMTP_MAILDOMAIN 23 | ports: 24 | - NNNN:80 25 | volumes: 26 | # - ./src:/var/www/html # uncomment for a mono-repo mounted from the host 27 | - files:/var/www/html/files 28 | - ./state:/state 29 | - ./.bash_history:/home/civicrm/.bash_history 30 | restart: always 31 | maildev: 32 | image: djfarrelly/maildev 33 | restart: always 34 | ports: 35 | - NNNN:80 36 | volumes: 37 | files: 38 | -------------------------------------------------------------------------------- /docker-compose/backdrop/docker-compose.prod.dist.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | services: 3 | civicrm: 4 | image: michaelmcandrew/civicrm:backdrop 5 | hostname: $PROJECT_NAME 6 | environment: 7 | - APACHE_RUN_USER=civicrm 8 | - PROJECT_NAME 9 | - BASE_URL 10 | - CIVICRM_DB_NAME 11 | - CIVICRM_DB_USER 12 | - CIVICRM_DB_PASS 13 | - CIVICRM_DB_HOST 14 | - CIVICRM_DB_PORT 15 | - BACKDROP_DB_NAME 16 | - BACKDROP_DB_USER 17 | - BACKDROP_DB_PASS 18 | - BACKDROP_DB_HOST 19 | - BACKDROP_DB_PORT 20 | ports: 21 | - NNNN:80 22 | volumes: 23 | - files:/var/www/html/files 24 | - ./state:/state 25 | restart: always 26 | volumes: 27 | files: 28 | -------------------------------------------------------------------------------- /docker-compose/drupal/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | state 3 | .bash_history 4 | docker-compose.yml 5 | -------------------------------------------------------------------------------- /docker-compose/drupal/dev.dist.env: -------------------------------------------------------------------------------- 1 | CIVICRM_DB_PASS=xxx 2 | DRUPAL_DB_PASS=xxx 3 | SMTP_HOST=maildev 4 | SMTP_MAILDOMAIN=example.org 5 | -------------------------------------------------------------------------------- /docker-compose/drupal/docker-compose.dev.dist.yml: -------------------------------------------------------------------------------- 1 | version: "3.6" 2 | services: 3 | civicrm: 4 | image: michaelmcandrew/civicrm:drupal 5 | hostname: example 6 | environment: 7 | - PROJECT_NAME=example 8 | - BASE_URL=http://example.localhost 9 | - CIVICRM_DB_NAME=example_civicrm 10 | - CIVICRM_DB_USER=example 11 | - CIVICRM_DB_PASS 12 | - CIVICRM_DB_HOST=mysql.localhost 13 | - CIVICRM_DB_PORT=3306 14 | - DRUPAL_DB_NAME=example_drupal 15 | - DRUPAL_DB_USER=example 16 | - DRUPAL_DB_PASS 17 | - DRUPAL_DB_HOST=mysql.localhost 18 | - DRUPAL_DB_PORT=3306 19 | - PHP_DATE_TIMEZONE="UTC" 20 | 21 | - DEBUG=ON 22 | - SMTP_HOST 23 | - SMTP_MAILDOMAIN 24 | volumes: 25 | - files:/var/www/html/sites/default/files 26 | - ./state:/state 27 | - ./.bash_history:/home/civicrm/.bash_history 28 | restart: always 29 | maildev: 30 | image: djfarrelly/maildev 31 | restart: always 32 | volumes: 33 | files: 34 | -------------------------------------------------------------------------------- /docker-compose/drupal/docker-compose.prod.dist.yml: -------------------------------------------------------------------------------- 1 | version: "3.6" 2 | services: 3 | civicrm: 4 | image: michaelmcandrew/civicrm:drupal 5 | hostname: example 6 | environment: 7 | - PROJECT_NAME=example 8 | - BASE_URL=https://example.org 9 | - CIVICRM_DB_NAME=example_civicrm 10 | - CIVICRM_DB_USER=example 11 | - CIVICRM_DB_PASS 12 | - CIVICRM_DB_HOST=mysql.example.org 13 | - CIVICRM_DB_PORT=3306 14 | - DRUPAL_DB_NAME=example_drupal 15 | - DRUPAL_DB_USER=example 16 | - DRUPAL_DB_PASS 17 | - DRUPAL_DB_HOST=mysql.example.org 18 | - DRUPAL_DB_PORT=3306 19 | - PHP_DATE_TIMEZONE="UTC" 20 | volumes: 21 | - files:/var/www/html/sites/default/files 22 | - ./state:/state 23 | - ./.bash_history:/home/civicrm/.bash_history 24 | restart: always 25 | volumes: 26 | files: 27 | -------------------------------------------------------------------------------- /docker-compose/wordpress/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | state 3 | .bash_history 4 | docker-compose.yml 5 | -------------------------------------------------------------------------------- /docker-compose/wordpress/dev.dist.env: -------------------------------------------------------------------------------- 1 | PROJECT_NAME=example 2 | 3 | CIVICRM_DB_NAME=civicrm 4 | CIVICRM_DB_USER=civicrm 5 | CIVICRM_DB_PASS=xxx 6 | CIVICRM_DB_HOST=mysql 7 | CIVICRM_DB_PORT=3306 8 | 9 | WORDPRESS_DB_NAME=wordpress 10 | WORDPRESS_DB_USER=wordpress 11 | WORDPRESS_DB_PASS=xxx 12 | WORDPRESS_DB_HOST=mysql 13 | WORDPRESS_DB_PORT=3306 14 | # WORDPRESS_TABLE_PREFIX 15 | 16 | CIVICRM_SITE_KEY=xxxxxx 17 | 18 | SMTP_HOST=maildev 19 | SMTP_MAILDOMAIN=example.org 20 | 21 | PHP_DATE_TIMEZONE="UTC" 22 | -------------------------------------------------------------------------------- /docker-compose/wordpress/docker-compose.dev.dist.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | services: 3 | civicrm: 4 | image: michaelmcandrew/civicrm-wordpress 5 | hostname: civicrm 6 | environment: 7 | - PROJECT_NAME 8 | - BASE_URL 9 | - CIVICRM_DB_NAME 10 | - CIVICRM_DB_USER 11 | - CIVICRM_DB_PASS 12 | - CIVICRM_DB_HOST 13 | - CIVICRM_DB_PORT 14 | - WORDPRESS_DB_NAME 15 | - WORDPRESS_DB_USER 16 | - WORDPRESS_DB_PASS 17 | - WORDPRESS_DB_HOST 18 | - WORDPRESS_DB_PORT 19 | - SMTP_HOST 20 | - SMTP_MAILDOMAIN 21 | - DEBUG=ON 22 | ports: 23 | - NNNN:80 24 | restart: always 25 | volumes: 26 | - ./.bash_history:/home/civicrm/.bash_history 27 | - ./state:/state 28 | - ./src:/var/www/html 29 | maildev: 30 | image: djfarrelly/maildev 31 | restart: always 32 | ports: 33 | - NNNN:80 34 | volumes: 35 | uploads: 36 | -------------------------------------------------------------------------------- /docker-compose/wordpress/docker-compose.prod.dist.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | services: 3 | civicrm: 4 | image: michaelmcandrew/civicrm-wordpress 5 | hostname: civicrm 6 | environment: 7 | - PROJECT_NAME 8 | - BASE_URL 9 | - CIVICRM_DB_NAME 10 | - CIVICRM_DB_USER 11 | - CIVICRM_DB_PASS 12 | - CIVICRM_DB_HOST 13 | - CIVICRM_DB_PORT 14 | - WORDPRESS_DB_NAME 15 | - WORDPRESS_DB_USER 16 | - WORDPRESS_DB_PASS 17 | - WORDPRESS_DB_HOST 18 | - WORDPRESS_DB_PORT 19 | - SMTP_HOST 20 | - SMTP_MAILDOMAIN 21 | ports: 22 | - NNNN:80 23 | restart: always 24 | volumes: 25 | - uploads:/var/www/html/wp-content/uploads 26 | - ./.bash_history:/home/civicrm/.bash_history 27 | - ./state:/state 28 | volumes: 29 | uploads: 30 | -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | In short, you'll need to: 4 | 5 | 1. Choose a base image (e.g. `civicrm-wordpress` or `civicrm-drupal`). 6 | 2. Create a `Dockerfile` and `docker-compose.yml` file for your project and configure as appropriate. 7 | 3. Create an `.env` file with your environmental configuration (see the examples `.env` files for inspiration). 8 | 4. Spin up your containers and initialise the project. 9 | 10 | Each of the above steps is explained in more detail below. You may also wish to consult the pages on `deploying features` and `mantaining your site`. 11 | 12 | ## Images 13 | 14 | We currently build images for running CiviCRM with WordPress and Drupal. These are more or less 'out-of-the-box' downloads of the CMS and CiviCRM with some configuration tweaks that make them more suitable for Docker hosting. 15 | 16 | If you're interested in the details, the Dockerfiles should be pretty self explanatory. 17 | 18 | The settings files have been tweaked to receive all environmental config from environment variables. 19 | 20 | ### The `civicrm-wordpress` image 21 | 22 | WordPress is installed at `/var/www/html`. 23 | 24 | CiviCRM (including the l10n files) is installed at `/var/www/html/wp-content/plugins/civcrm`. 25 | 26 | `wp-cli` is installed at `/usr/local/bin`. 27 | 28 | TODO: disable downloading from the web via FTP or similar in wp-config. 29 | 30 | ### The `civicrm-drupal` image 31 | 32 | Drupal is installed at `/var/www/html`. 33 | 34 | CiviCRM (including the l10n files) is installed at `/var/www/html/sites/all/modules/civcrm`. 35 | 36 | `drush` is installed at `/usr/local/bin`. 37 | 38 | ### The `civicrm-base` image 39 | 40 | The CMS specific images are built from a `civicrm-base` image, which satisfies CiviCRM's dependecies and is built from the offical docker `php:strech` image. 41 | 42 | `cv` is installed at `/usr/local/bin`. 43 | 44 | Note that this image is not designed to be used directly to run a CiviCRM site. You should use the CMS specific image for the CMS that you want to use. 45 | 46 | ## Dockerfiles 47 | 48 | While it is possible to use the CMS images above to host a CiviCRM site with no further modifications, most users will want to further extend their sites with extensions, plugins, modules, etc. 49 | 50 | There are various approaches to doing this. One is add the relevant code via a Dockerfile. 51 | 52 | Here is an example Dockerfile for Drupal that downloads the `views`, `webform`, and `webform_civicrm` Drupal modules. 53 | 54 | ```docker 55 | FROM civicrm:drupal 56 | 57 | RUN drush dl views webform webform_civicrm 58 | ``` 59 | -------------------------------------------------------------------------------- /generate.php: -------------------------------------------------------------------------------- 1 | 'settings.php', 'wordpress' => 'wp-config.php']; 11 | 12 | 13 | $combos = []; 14 | foreach ($cmses as $cms) { 15 | foreach ($phpVers as $phpVer) { 16 | $combos["$latestCiviVer/$cms/$phpVer"] = [ 17 | 'dir' => "$civiMajorVer/$cms/php$phpVer", 18 | 'tags' => [['civi' => $latestCiviVer, 'cms' => $cms, 'php' => 'php' . $phpVer]], 19 | 'variables' => ['civi' => $latestCiviVer, 'cms' => $cms, 'php' => $phpVer], 20 | ]; 21 | } 22 | } 23 | 24 | $tags = []; 25 | 26 | foreach ($combos as $k => $combo) { 27 | // default cms 28 | foreach ($combos[$k]['tags'] as $tag) { 29 | if ($tag['cms'] == $defaults['cms']) { 30 | $combos[$k]['tags'][] = ['cms' => ''] + $tag; 31 | } 32 | } 33 | 34 | // default php version 35 | foreach ($combos[$k]['tags'] as $tag) { 36 | if ($tag['php'] == 'php' . $defaults['php']) { 37 | $combos[$k]['tags'][] = ['php' => ''] + $tag; 38 | } 39 | } 40 | 41 | // default civicrm version 42 | foreach ($combos[$k]['tags'] as $tag) { 43 | if ($tag['civi'] == $defaults['civi']) { 44 | $combos[$k]['tags'][] = ['civi' => ''] + $tag; 45 | } 46 | } 47 | 48 | // minor alias 49 | foreach ($combos[$k]['tags'] as $tag) { 50 | if ($tag['civi'] == $defaults['civi']) { 51 | $combos[$k]['tags'][] = ['civi' => "$civiMajorVer.$civiMinorVer"] + $tag; 52 | } 53 | } 54 | 55 | // major alias 56 | foreach ($combos[$k]['tags'] as $tag) { 57 | if ($tag['civi'] == $defaults['civi']) { 58 | $combos[$k]['tags'][] = ['civi' => $civiMajorVer] + $tag; 59 | } 60 | } 61 | $implodedTags = []; 62 | foreach ($combos[$k]['tags'] as &$tag) { 63 | $newTag = implode('-', array_filter($tag)); 64 | $implodedTags[] = $newTag ? $newTag : 'latest'; 65 | } 66 | $combos[$k]['tags'] = $implodedTags; 67 | sort($combos[$k]['tags']); 68 | } 69 | file_put_contents(__DIR__ . '/' . 'combos.json', json_encode($combos, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); 70 | 71 | $projectDir = __DIR__; 72 | // TODO: this number should not be hardcoded 73 | `rm -r $projectDir/6`; 74 | 75 | 76 | foreach ($combos as $combo) { 77 | $cms = $combo['variables']['cms']; 78 | $comboDir = __DIR__ . '/' . $combo['dir']; 79 | `mkdir -p $comboDir`; 80 | $dockerFile = inc("$projectDir/templates/Dockerfile", $combo['variables']); 81 | file_put_contents("$comboDir/Dockerfile", $dockerFile); 82 | `cp $projectDir/templates/$cms.civicrm.settings.php $comboDir/civicrm.settings.php`; 83 | $cmsSettingsFile = $cmsSettingsFiles[$cms]; 84 | `cp $projectDir/templates/$cms.$cmsSettingsFile $comboDir/$cmsSettingsFile`; 85 | `cp $projectDir/templates/$cms.civicrm-docker-init $comboDir/civicrm-docker-init`; 86 | `cp $projectDir/templates/$cms.civicrm-docker-dump $comboDir/civicrm-docker-dump`; 87 | `cp $projectDir/templates/civicrm-docker-load $comboDir/civicrm-docker-load`; 88 | `cp $projectDir/templates/$cms.civicrm-docker-install $comboDir/civicrm-docker-install`; 89 | `cp $projectDir/templates/.my.cnf $comboDir`; 90 | `cp $projectDir/templates/apache.conf $comboDir`; 91 | `cp $projectDir/templates/apache-sites-available-default.conf $comboDir`; 92 | `cp $projectDir/templates/civicrm_dump.php $comboDir`; 93 | `cp $projectDir/templates/civicrm-docker-entrypoint $comboDir`; 94 | `cp $projectDir/templates/msmtp-wrapper $comboDir`; 95 | } 96 | 97 | $readme = file_get_contents($projectDir . '/README.md'); 98 | $startTagsToken = ''; 99 | $endTagsToken = ''; 100 | $startPos = strpos($readme, $startTagsToken) + strlen($startTagsToken); 101 | $endPos = strpos($readme, $endTagsToken); 102 | 103 | 104 | $readmeStart = substr($readme, 0, $startPos); 105 | $readmeEnd = substr($readme, $endPos); 106 | 107 | $tagsText = "\n"; 108 | foreach ($combos as $combo) { 109 | $tagsText .= '- ' . implode(', ', $combo['tags']) . " [" . $combo['dir'] . "](" . $combo['dir'] . ")\n"; 110 | } 111 | file_put_contents($projectDir . '/README.md', $readmeStart . $tagsText . $readmeEnd); 112 | 113 | function inc($file, $vars) { 114 | ob_start(); 115 | include $file; 116 | return ob_get_clean(); 117 | } 118 | -------------------------------------------------------------------------------- /mysql/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mysql:8.0 2 | 3 | COPY ./my.cnf /etc/mysql/conf.d/civicrm.cnf 4 | -------------------------------------------------------------------------------- /mysql/my.cnf: -------------------------------------------------------------------------------- 1 | # Keep this in sync with https://docs.civicrm.org/sysadmin/en/latest/requirements/#mysql 2 | 3 | [mysqld] 4 | # By default MySQL 8.0 includes ONLY_FULL_GROUP_BY in sql-mode. It should be turned off as it might result in error for CiviCRM queries. 5 | sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" 6 | max_allowed_packet=1024M 7 | 8 | # Turn off binary logging as it's default turned in MySQL 8.0. It's mainly used for replication 9 | skip-log-bin 10 | 11 | # Set - this is recommended by CiviCRM 12 | character_set_server=utf8mb4 13 | collation_server=utf8mb4_unicode_ci 14 | 15 | # Preallocate and limit the amount of space that can be used by temporary tables (https://chat.civicrm.org/civicrm/pl/eh138wwpciddbctuwuubqxjcaw) 16 | innodb_temp_data_file_path=ibtmp1:100M:autoextend:max:10G 17 | 18 | # Set a limit on long running SELECT statements (https://chat.civicrm.org/civicrm/pl/eh138wwpciddbctuwuubqxjcaw) 19 | max_execution_time=600000 20 | -------------------------------------------------------------------------------- /templates/.my.cnf: -------------------------------------------------------------------------------- 1 | [mysqldump] 2 | max_allowed_packet=1024M 3 | -------------------------------------------------------------------------------- /templates/Dockerfile: -------------------------------------------------------------------------------- 1 | ### THIS FILE GENERATED BY https://github.com/michaelmcandrew/civicrm-docker/blob/master/generate.py ### 2 | 3 | FROM php:-apache-bookworm 4 | 5 | # libc-client-dev and libkrb5-dev required for the imap php extension 6 | # libicu-dev required for the intl php extension 7 | # libmagickwand-dev required for the imagick php extension 8 | # libjpeg62-turbo-dev and libpng-dev required for the gd php extension 9 | # libxml2-dev required for the soap php extension 10 | # iproute2 is required to get the host ip at runtime for XDEBUG_REMOTE_HOST environment variable 11 | # msmtp-mta allows us to globally redirect email via SMTP 12 | # unzip is required for composer 13 | 14 | RUN apt-get update \ 15 | && apt-get install -y --no-install-recommends \ 16 | imagemagick \ 17 | iproute2 \ 18 | less \ 19 | libc-client-dev \ 20 | libicu-dev \ 21 | libjpeg62-turbo-dev \ 22 | libkrb5-dev \ 23 | libmagickwand-dev \ 24 | libpng-dev \ 25 | libxml2-dev \ 26 | libzip-dev \ 27 | msmtp-mta \ 28 | mariadb-client \ 29 | unzip \ 30 | wget \ 31 | && rm -r /var/lib/apt/lists/* 32 | 33 | # CiviCRM requires the following PHP extensions (some of which are already 34 | # enabled in the Docker image): 35 | # 36 | # * curl (already enabled) 37 | # * gd 38 | # * gettext 39 | # * imagick 40 | # * imap 41 | # * intl 42 | # * json (already enabled) 43 | # * mbstring (already enabled) 44 | # * mysqli 45 | # * openssl (already enabled) 46 | # * pdo_mysql 47 | # * phar (already enabled) 48 | # * posix (already enabled) 49 | # * soap 50 | # * zip 51 | 52 | # WordPress recommends the following PHP extensions in addition to 53 | # the ones listed above: 54 | # 55 | # * dom (already enabled) 56 | # * exif 57 | # * fileinfo (already enabled) 58 | # * hash (already enabled) 59 | # * igbinary 60 | # * imagick 61 | # * pcre (already enabled) 62 | # * xml (already enabled) 63 | 64 | # Configure and install php extensions (note configuration comes before installation) 65 | 66 | RUN docker-php-ext-install bcmath \ 67 | && docker-php-ext-install exif \ 68 | && docker-php-ext-configure gd --with-jpeg \ 69 | && docker-php-ext-install gd \ 70 | && docker-php-ext-install gettext \ 71 | && docker-php-ext-configure imap --with-kerberos --with-imap-ssl \ 72 | && docker-php-ext-install imap \ 73 | && docker-php-ext-install intl \ 74 | && docker-php-ext-install mysqli \ 75 | && docker-php-ext-install opcache \ 76 | && docker-php-ext-install pdo_mysql \ 77 | && docker-php-ext-install soap \ 78 | && docker-php-ext-install zip 79 | 80 | # Install and enable imagick PECL extensions 81 | 82 | # Copy pasta from https://github.com/docker-library/wordpress/blob/3f1a0cab9f2f938bbc57f5f92ec11eeea4511636/latest/php8.3/fpm-alpine/Dockerfile#L47-L51 83 | # Based on suggestion here: https://github.com/docker-library/php/issues/1532#issuecomment-2258777719 84 | RUN curl -fL -o imagick.tgz 'https://pecl.php.net/get/imagick-3.7.0.tgz'; \ 85 | echo '5a364354109029d224bcbb2e82e15b248be9b641227f45e63425c06531792d3e *imagick.tgz' | sha256sum -c -; \ 86 | tar --extract --directory /tmp --file imagick.tgz imagick-3.7.0; \ 87 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php; \ 88 | test "$(grep -c '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php)" = '1'; \ 89 | sed -i -e 's!^//#endif$!#endif!' /tmp/imagick-3.7.0/Imagick.stub.php; \ 90 | grep '^//#endif$' /tmp/imagick-3.7.0/Imagick.stub.php && exit 1 || :; \ 91 | docker-php-ext-install /tmp/imagick-3.7.0; \ 92 | rm -rf imagick.tgz /tmp/imagick-3.7.0; 93 | 94 | # Install igbinary PECL extension 95 | RUN pecl install igbinary \ 96 | && docker-php-ext-enable igbinary 97 | 98 | # Install xdebug PECL extension 99 | RUN pecl install xdebug 100 | 101 | # Install composer using the method described at https://getcomposer.org/download/ (TODO consider whether this is really necessary - we could remove from this image) 102 | RUN EXPECTED_SIGNATURE="$(curl https://composer.github.io/installer.sig)" \ 103 | && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ 104 | && ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" \ 105 | && if [ "$EXPECTED_SIGNATURE" != "${ACTUAL_SIGNATURE}" ]; then >&2 echo 'ERROR: Invalid installer signature'; rm composer-setup.php; exit 1; fi \ 106 | && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ 107 | && rm composer-setup.php 108 | 109 | # Create civicrm user 110 | 111 | RUN useradd civicrm --home-dir /home/civicrm --create-home 112 | 113 | RUN chown -R civicrm:civicrm /var/www 114 | 115 | ENV APACHE_RUN_USER=civicrm 116 | 117 | ENV APACHE_RUN_GROUP=civicrm 118 | 119 | USER civicrm 120 | 121 | # TODO: I think we only use cgr for drush. If we can find another way to install drush, then we can remove this dependency. 122 | RUN composer global require --ignore-platform-req php consolidation/cgr 123 | 124 | USER root 125 | 126 | # Download cv 127 | 128 | RUN curl -LsS https://download.civicrm.org/cv/cv.phar -o /usr/local/bin/cv \ 129 | && chmod +x /usr/local/bin/cv 130 | 131 | # Download civix 132 | 133 | RUN curl -LsS https://download.civicrm.org/civix/civix.phar -o /usr/local/bin/civix \ 134 | && chmod +x /usr/local/bin/civix 135 | 136 | # Configure apache 137 | 138 | RUN a2enmod expires headers remoteip rewrite 139 | 140 | COPY ./apache.conf /etc/apache2/conf-available/civicrm.conf 141 | 142 | RUN a2enconf civicrm 143 | 144 | COPY ./apache-sites-available-default.conf /etc/apache2/sites-available/000-default.conf 145 | 146 | # Configure php 147 | 148 | RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini 149 | 150 | COPY ./civicrm-docker-load /usr/local/bin 151 | 152 | COPY ./civicrm_dump.php /usr/local/src/civicrm_dump.php 153 | 154 | RUN mkdir /usr/local/etc/civicrm 155 | 156 | # Install msmtp wrapper 157 | 158 | COPY ./msmtp-wrapper /usr/local/bin/msmtp-wrapper 159 | 160 | ENTRYPOINT [ "civicrm-docker-entrypoint" ] 161 | 162 | CMD ["apache2-foreground"] 163 | 164 | 165 | 166 | # Configure mysqldump 167 | 168 | COPY ./.my.cnf /home/civicrm/.my.cnf 169 | -------------------------------------------------------------------------------- /templates/apache-sites-available-default.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/html 5 | 6 | # We are behind a proxy and using remoteip 7 | # See https://httpd.apache.org/docs/2.4/mod/mod_remoteip.html 8 | RemoteIPHeader X-Forwarded-For 9 | RemoteIPInternalProxy traefik 10 | 11 | # Combined log format with %h replaced by %a as we are behind a proxy 12 | # See https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats 13 | # for more details of custom log formats. 14 | LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" remoteip_combined 15 | CustomLog ${APACHE_LOG_DIR}/access.log remoteip_combined 16 | 17 | ErrorLog ${APACHE_LOG_DIR}/error.log 18 | 19 | 20 | -------------------------------------------------------------------------------- /templates/apache.conf: -------------------------------------------------------------------------------- 1 | ServerName ${BASE_URL} 2 | -------------------------------------------------------------------------------- /templates/civicrm-docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # sendmail via smtp 5 | cat </etc/msmtprc 6 | host $SMTP_HOST 7 | EOF 8 | 9 | if [ ! -z "$SMTP_PORT" ]; then 10 | cat <>/etc/msmtprc 11 | port $SMTP_PORT 12 | EOF 13 | fi 14 | 15 | # Note: we assume TlS when we have a username and password 16 | if [ ! -z "$SMTP_USER" ] && [ ! -z "$SMTP_PASSWORD" ]; then 17 | cat <>/etc/msmtprc 18 | auth on 19 | tls on 20 | tls_starttls on 21 | user $SMTP_USER 22 | password $SMTP_PASSWORD 23 | EOF 24 | fi 25 | 26 | # civicrm php.ini settings 27 | cat </usr/local/etc/php/conf.d/civicrm.ini 28 | memory_limit = 1024M 29 | upload_max_filesize = 64M 30 | post_max_size = 64M 31 | max_execution_time=300 32 | max_input_time = -1 33 | max_input_vars = 10000 34 | sendmail_path=/usr/local/bin/msmtp-wrapper 35 | date.timezone=$PHP_DATE_TIMEZONE 36 | log_errors = On 37 | error_log = /dev/stderr 38 | EOF 39 | 40 | : "${DEBUG_MODE:=develop,debug}" 41 | 42 | 43 | if [ "$DEBUG" = "ON" ]; then 44 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini 45 | CONTAINER_IP=$(/sbin/ip route | awk '/default/ { print $3 }') 46 | XDEBUG_REMOTE_HOST=$CONTAINER_IP 47 | cat </usr/local/etc/php/conf.d/debug.ini 48 | 49 | max_execution_time=600 50 | 51 | xdebug.cli_color=1 52 | xdebug.client_host=${CONTAINER_IP} 53 | xdebug.log_level=0 54 | xdebug.mode=${DEBUG_MODE} 55 | xdebug.output_dir = /state 56 | xdebug.start_with_request=yes 57 | xdebug.var_display_max_children=128 58 | xdebug.var_display_max_data=128 59 | xdebug.var_display_max_depth=2 60 | 61 | zend_extension=xdebug.so 62 | EOF 63 | fi 64 | 65 | su civicrm -c /usr/local/bin/civicrm-docker-init 66 | 67 | # first arg is `-f` or `--some-option` 68 | if [ "${1#-}" != "$1" ]; then 69 | set -- apache2-foreground "$@" 70 | fi 71 | exec "$@" 72 | -------------------------------------------------------------------------------- /templates/civicrm-docker-load: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | /dev/null`); 11 | if (!$states) { 12 | die("Error: could not find any state dumps in /state.\n"); 13 | } 14 | $states = explode("\n", $states); 15 | echo "Choose the number for the state you want to load (or 'Enter' for the most recent):\n"; 16 | foreach ($states as $n => $state) { 17 | echo "[$n] " . basename($state) . "\n"; 18 | } 19 | $key = readline(); 20 | if ($key == '') { 21 | $key = 0; 22 | } 23 | if (array_key_exists($key, $states)) { 24 | $dump = $states[$key]; 25 | } else { 26 | die("Error: '$key' was not an option.\n"); 27 | } 28 | } 29 | 30 | $loadDir = tempnam('/tmp', 'civicrm_load_'); 31 | `rm $loadDir; mkdir $loadDir`; 32 | echo "Opening $dump\n"; 33 | `tar -xf $dump -C $loadDir `; 34 | $state = json_decode(file_get_contents("$loadDir/state.json"), 1); 35 | foreach ($state['databases'] as $name) { 36 | foreach (['USER', 'PASS', 'HOST', 'PORT', 'NAME'] as $var) { 37 | $$var = getenv(strtoupper($name) . '_DB_' . $var); 38 | } 39 | echo "Importing $name dump into $NAME database\n"; 40 | `mysql -p$PASS -u $USER -h $HOST -e "DROP DATABASE IF EXISTS \\\`$NAME\\\`; CREATE DATABASE \\\`$NAME\\\`"`; 41 | `sed -E "/^\/\*\![[:digit:]]+ DEFINER/d" $loadDir/$name.sql | mysql -p$PASS -u $USER -h $HOST $NAME`; 42 | } 43 | 44 | foreach ($state['directories'] as $name => $path) { 45 | echo "Unpacking $name tar into $path\n"; 46 | `tar -xf {$loadDir}/{$name}.tar.gz -C $path`; 47 | } 48 | 49 | `rm -r $loadDir`; 50 | `cv flush -T`; 51 | 52 | if (is_executable('/home/civicrm/postLoad')) { 53 | `/home/civicrm/postLoad`; 54 | } 55 | -------------------------------------------------------------------------------- /templates/civicrm_dump.php: -------------------------------------------------------------------------------- 1 | {$dumpDir}/{$name}.sql`; 22 | } 23 | foreach ($state['directories'] as $name => $path) { 24 | `tar -czf {$dumpDir}/{$name}.tar.gz -C $path .`; 25 | } 26 | 27 | $state['end'] = date(DATE_ISO8601); 28 | file_put_contents("$dumpDir/state.json", json_encode($state, JSON_PRETTY_PRINT)); 29 | 30 | `tar -czf /state/$tarName -C $dumpDir .`; 31 | 32 | `rm -r $dumpDir`; 33 | 34 | echo "$tarName\n"; 35 | } 36 | -------------------------------------------------------------------------------- /templates/drupal.Dockerfile: -------------------------------------------------------------------------------- 1 | ENV CIVICRM_UF=Drupal 2 | 3 | USER civicrm 4 | 5 | ENV PATH="/home/civicrm/.composer/vendor/bin:${PATH}" 6 | 7 | RUN cgr drush/drush:~8 8 | 9 | RUN drush dl drupal-7 --destination=/var/www --drupal-project-rename=html -y 10 | 11 | RUN mkdir /var/www/html/sites/default/files 12 | 13 | RUN cd /var/www/html/sites/all/modules \ 14 | && curl -L https://download.civicrm.org/civicrm--drupal.tar.gz > civicrm-drupal.tar.gz \ 15 | && tar xzf civicrm-drupal.tar.gz \ 16 | && rm civicrm-drupal.tar.gz 17 | 18 | RUN cd /var/www/html/sites/all/modules \ 19 | && curl -L https://download.civicrm.org/civicrm--l10n.tar.gz > civicrm-l10n.tar.gz \ 20 | && tar xzf civicrm-l10n.tar.gz \ 21 | && rm civicrm-l10n.tar.gz 22 | 23 | USER root 24 | 25 | COPY ./civicrm-docker-entrypoint ./civicrm-docker-init ./civicrm-docker-dump ./civicrm-docker-install /usr/local/bin/ 26 | 27 | COPY --chown=civicrm:civicrm ./settings.php /usr/local/etc/civicrm 28 | 29 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 30 | 31 | -------------------------------------------------------------------------------- /templates/drupal.civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'drupal' 13 | ], 14 | 'directories' => [ 15 | 'files' => '/var/www/html/sites/default/files' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | 22 | 23 | -------------------------------------------------------------------------------- /templates/drupal.civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | 4 | # Initialise CiviCRM and Drupal ready for loading an existing state dump or a fresh installation. Destroys any existing data and files. 5 | # Called automatically by civicrm-docker-install. 6 | 7 | pushd /var/www/html/sites/default 8 | 9 | chmod u+w . 10 | for FILE in settings.php civicrm.settings.php; do 11 | if test -f "$FILE"; then 12 | chmod u+w $FILE 13 | fi 14 | cp /usr/local/etc/civicrm/$FILE . 15 | chmod a-wx $FILE 16 | done 17 | chmod u-w . 18 | popd 19 | -------------------------------------------------------------------------------- /templates/drupal.civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | # Fresh install of CiviCRM on Drupal 4 | 5 | chmod +w /var/www/html/sites/default 6 | 7 | drush -r /var/www/html/ site-install -y 8 | drush dis overlay -y 9 | chmod u+w /var/www/html/sites/default/civicrm.settings.php 10 | cv core:install --settings-path=/var/www/html/sites/default/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 11 | chmod u-w /var/www/html/sites/default/civicrm.settings.php 12 | 13 | if test -x "/home/civicrm/postInstall"; then 14 | /home/civicrm/postInstall 15 | fi 16 | -------------------------------------------------------------------------------- /templates/drupal.civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /templates/drupal.settings.php: -------------------------------------------------------------------------------- 1 | 4 | array( 5 | 'default' => 6 | array( 7 | 'database' => getenv('DRUPAL_DB_NAME'), 8 | 'username' => getenv('DRUPAL_DB_USER'), 9 | 'password' => getenv('DRUPAL_DB_PASS'), 10 | 'host' => getenv('DRUPAL_DB_HOST'), 11 | 'port' => getenv('DRUPAL_DB_PORT'), 12 | 'driver' => 'mysql', 13 | 'prefix' => '', 14 | ), 15 | ), 16 | ); 17 | 18 | $update_free_access = FALSE; 19 | 20 | $drupal_hash_salt = getenv('DRUPAL_HASH_SALT'); 21 | 22 | $base_url = getenv('BASE_URL'); 23 | 24 | ini_set('session.gc_probability', 1); 25 | ini_set('session.gc_divisor', 100); 26 | ini_set('session.gc_maxlifetime', 200000); 27 | ini_set('session.cookie_lifetime', 2000000); 28 | 29 | $conf['404_fast_paths_exclude'] = '/\/(?:styles)|(?:system\/files)\//'; 30 | $conf['404_fast_paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; 31 | $conf['404_fast_html'] = '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'; 32 | 33 | $conf['reverse_proxy'] = TRUE; 34 | $conf['reverse_proxy_addresses'] = [$_SERVER['REMOTE_ADDR']]; 35 | 36 | if (file_exists(__DIR__ . '/extra.settings.php')) { 37 | require_once __DIR__ . '/extra.settings.php'; 38 | } 39 | -------------------------------------------------------------------------------- /templates/msmtp-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Wraps `msmtp` so that it can cope with receiving both -f and --read-envelope-from 5 | 6 | This script calls `msmt`. It will add --read-envelope-from to the arguments ONLY IF 7 | an argument starting with '-f' cannot be found. 8 | """ 9 | import sys 10 | import subprocess 11 | 12 | command = sys.argv.copy() 13 | command[0] = "msmtp" 14 | command.append("--read-recipients") 15 | 16 | if not [i for i in command if i.startswith("-f")]: 17 | command.append("--read-envelope-from") 18 | 19 | subprocess.run(command, stdin=sys.stdin) 20 | -------------------------------------------------------------------------------- /templates/wordpress.Dockerfile: -------------------------------------------------------------------------------- 1 | ENV CIVICRM_UF=WordPress 2 | 3 | ARG CIVICRM_VERSION 4 | 5 | RUN curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp \ 6 | && chmod +x /usr/local/bin/wp 7 | 8 | USER civicrm 9 | 10 | RUN php -d memory_limit=1G /usr/local/bin/wp core download 11 | 12 | RUN mkdir /var/www/html/wp-content/uploads 13 | 14 | RUN cd /var/www/html/wp-content/plugins \ 15 | && curl -L https://download.civicrm.org/civicrm--wordpress.zip > civicrm-wordpress.zip \ 16 | && unzip civicrm-wordpress.zip \ 17 | && rm civicrm-wordpress.zip 18 | 19 | RUN cd /var/www/html/wp-content/plugins \ 20 | && curl -L https://download.civicrm.org/civicrm--l10n.tar.gz > civicrm-l10n.tar.gz \ 21 | && tar xzf civicrm-l10n.tar.gz \ 22 | && rm civicrm-l10n.tar.gz 23 | 24 | USER root 25 | 26 | COPY --chown=civicrm:civicrm \ 27 | ./civicrm-docker-entrypoint \ 28 | ./civicrm-docker-init \ 29 | ./civicrm-docker-dump \ 30 | ./civicrm-docker-install \ 31 | /usr/local/bin/ 32 | 33 | COPY --chown=civicrm:civicrm ./wp-config.php /usr/local/etc/civicrm 34 | 35 | COPY --chown=civicrm:civicrm ./civicrm.settings.php /usr/local/etc/civicrm 36 | -------------------------------------------------------------------------------- /templates/wordpress.civicrm-docker-dump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getenv('PROJECT_NAME'), 10 | 'databases' => [ 11 | 'civicrm', 12 | 'wordpress' 13 | ], 14 | 'directories' => [ 15 | 'uploads' => '/var/www/html/wp-content/uploads' 16 | ] 17 | ]; 18 | } 19 | 20 | civicrm_dump($state); 21 | -------------------------------------------------------------------------------- /templates/wordpress.civicrm-docker-init: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd /var/www/html 4 | 5 | chmod u+w . 6 | 7 | # WordPress settings 8 | [[ -f wp-config.php ]] && chmod u+w wp-config.php 9 | cp /usr/local/etc/civicrm/wp-config.php . 10 | chmod a-wx wp-config.php 11 | 12 | [[ -d /var/www/html/wp-content/uploads/civicrm ]] || mkdir -p /var/www/html/wp-content/uploads/civicrm 13 | 14 | pushd /var/www/html/wp-content/uploads/civicrm 15 | 16 | # CiviCRM settings 17 | chmod u+w . 18 | 19 | [[ -f civicrm.settings.php ]] && chmod u+w civicrm.settings.php 20 | cp /usr/local/etc/civicrm/civicrm.settings.php . 21 | chmod a-wx civicrm.settings.php 22 | 23 | popd 24 | 25 | popd 26 | 27 | -------------------------------------------------------------------------------- /templates/wordpress.civicrm-docker-install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | civicrm-docker-init 4 | 5 | pushd /var/www/html 6 | 7 | wp core install --url=$BASE_URL --title=$PROJECT_NAME --admin_user=admin --admin_email=admin@example.org 8 | 9 | # Prepare for CiviCRM install 10 | if test -f civicrm.settings.php; then 11 | chmod u+w civicrm.settings.php 12 | fi 13 | 14 | cv core:install --settings-path=/var/www/html/wp-content/uploads/civicrm/civicrm.settings.php --keep --db=mysql://$CIVICRM_DB_USER:$CIVICRM_DB_PASS@$CIVICRM_DB_HOST:$CIVICRM_DB_PORT/$CIVICRM_DB_NAME 15 | wp plugin activate civicrm 16 | 17 | popd 18 | -------------------------------------------------------------------------------- /templates/wordpress.civicrm.settings.php: -------------------------------------------------------------------------------- 1 | "; 45 | exit(); 46 | } 47 | 48 | // Clean URLs 49 | if (!defined('CIVICRM_CLEANURL')) { 50 | if (function_exists('variable_get') && variable_get('clean_url', '0') != '0') { 51 | define('CIVICRM_CLEANURL', 1); 52 | } 53 | elseif (function_exists('config_get') && config_get('system.core', 'clean_url') != 0) { 54 | define('CIVICRM_CLEANURL', 1); 55 | } 56 | elseif (function_exists('get_option') && get_option('permalink_structure') != '') { 57 | define('CIVICRM_CLEANURL', 1); 58 | } 59 | else { 60 | define('CIVICRM_CLEANURL', 0); 61 | } 62 | } 63 | 64 | // More stuff that probably shouldn't be in a settings file 65 | $memLimitString = trim(ini_get('memory_limit')); 66 | $memLimitUnit = strtolower(substr($memLimitString, -1)); 67 | $memLimit = (int) $memLimitString; 68 | switch ($memLimitUnit) { 69 | case 'g': 70 | $memLimit *= 1024; 71 | case 'm': 72 | $memLimit *= 1024; 73 | case 'k': 74 | $memLimit *= 1024; 75 | } 76 | if ($memLimit >= 0 and $memLimit < 134217728) { 77 | ini_set('memory_limit', '128M'); 78 | } 79 | require_once 'CRM/Core/ClassLoader.php'; 80 | CRM_Core_ClassLoader::singleton()->register(); 81 | -------------------------------------------------------------------------------- /templates/wordpress.wp-config.php: -------------------------------------------------------------------------------- 1 | $latestCiviVer, 18 | "cms" => "wordpress", 19 | "php" => "8.3", 20 | ]; 21 | --------------------------------------------------------------------------------