Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store the log files in MW_VOLUME, which must be mounted on host #371

Merged
merged 18 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
MW_CORE_VERSION=1.39.6 \
WWW_ROOT=/var/www/mediawiki \
MW_HOME=/var/www/mediawiki/w \
MW_LOG=/var/log/mediawiki \
MW_ORIGIN_FILES=/mw_origin_files \
MW_VOLUME=/mediawiki \
WWW_USER=www-data \
WWW_GROUP=www-data \
APACHE_LOG_DIR=/var/log/apache2
WWW_GROUP=www-data \
PHP_LOG_DIR=/var/log/php-fpm \
APACHE_LOG_DIR=/var/log/apache2

# System setup
RUN set x; \

Check failure on line 19 in Dockerfile

View workflow job for this annotation

GitHub Actions / test

DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`

Check failure on line 19 in Dockerfile

View workflow job for this annotation

GitHub Actions / test

DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
apt-get clean \
&& apt-get update \
&& apt-get install -y aptitude \
Expand Down Expand Up @@ -72,21 +74,23 @@
&& rm /etc/apache2/sites-available/000-default.conf \
&& rm -rf /var/www/html \
# Enable rewrite module
&& a2enmod rewrite \
&& a2enmod rewrite \
# enabling mpm_event and php-fpm
&& a2dismod mpm_prefork \
&& a2enconf php7.4-fpm \
&& a2enmod mpm_event \
&& a2enmod proxy_fcgi \
# Create directories
&& mkdir -p $MW_HOME \
&& mkdir -p $MW_ORIGIN_FILES \
&& mkdir -p $MW_VOLUME
# Create directories
&& mkdir -p $MW_HOME \
&& mkdir -p $MW_LOG \
&& mkdir -p $PHP_LOG_DIR \
&& mkdir -p $MW_ORIGIN_FILES \
&& mkdir -p $MW_VOLUME

# Composer
RUN set -x; \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& composer self-update 2.1.3
&& composer self-update 2.1.3

FROM base as source

Expand All @@ -102,7 +106,7 @@
RUN set -x; \
cd $MW_HOME/skins \
# Chameleon (v. 4.2.1)
&& git clone https://github.com/ProfessionalWiki/chameleon $MW_HOME/skins/chameleon \
&& git clone https://github.com/ProfessionalWiki/chameleon $MW_HOME/skins/chameleon \
&& cd $MW_HOME/skins/chameleon \
&& git checkout -q f34a56528ada14ac07e1b03beda41f775ef27606 \
# CologneBlue
Expand Down Expand Up @@ -722,8 +726,13 @@
COPY --from=source $MW_ORIGIN_FILES $MW_ORIGIN_FILES

# Default values
ENV MW_ENABLE_JOB_RUNNER=true \
ENV MW_AUTOUPDATE=true \
MW_MAINTENANCE_UPDATE=0 \
MW_MAINTENANCE_CIRRUSSEARCH_UPDATECONFIG=2 \
MW_MAINTENANCE_CIRRUSSEARCH_FORCEINDEX=2 \
MW_ENABLE_JOB_RUNNER=true \
MW_JOB_RUNNER_PAUSE=2 \
MW_JOB_RUNNER_MEMORY_LIMIT=512M \
MW_ENABLE_TRANSCODER=true \
MW_JOB_TRANSCODER_PAUSE=60 \
MW_MAP_DOMAIN_TO_DOCKER_GATEWAY=true \
Expand All @@ -747,7 +756,7 @@
COPY _sources/configs/msmtprc /etc/
COPY _sources/configs/mediawiki.conf /etc/apache2/sites-enabled/
COPY _sources/configs/status.conf /etc/apache2/mods-available/
COPY _sources/configs/php_error_reporting.ini _sources/configs/php_upload_max_filesize.ini /etc/php/7.4/cli/conf.d/
COPY _sources/configs/php_cli_error_reporting.ini _sources/configs/php_upload_max_filesize.ini /etc/php/7.4/cli/conf.d/
COPY _sources/configs/php_error_reporting.ini _sources/configs/php_upload_max_filesize.ini /etc/php/7.4/fpm/conf.d/
COPY _sources/configs/php_max_input_vars.ini _sources/configs/php_max_input_vars.ini /etc/php/7.4/fpm/conf.d/
COPY _sources/configs/php_timeouts.ini /etc/php/7.4/fpm/conf.d/
Expand All @@ -758,13 +767,15 @@
COPY _sources/configs/robots.txt _sources/configs/robots.php $WWW_ROOT/
COPY _sources/configs/.htaccess $WWW_ROOT/
COPY _sources/images/favicon.ico $WWW_ROOT/
COPY _sources/canasta/LocalSettings.php _sources/canasta/CanastaDefaultSettings.php $MW_HOME/
COPY _sources/canasta/LocalSettings.php _sources/canasta/CanastaDefaultSettings.php _sources/canasta/FarmConfigLoader.php $MW_HOME/
COPY _sources/canasta/getMediawikiSettings.php /
COPY _sources/configs/mpm_event.conf /etc/apache2/mods-available/mpm_event.conf

RUN set -x; \
chmod -v +x /*.sh \
&& chmod -v +x /maintenance-scripts/*.sh \
# Sitemap directory
&& mkdir -p $MW_ORIGIN_FILES/sitemap \
&& ln -s $MW_VOLUME/sitemap $MW_HOME/sitemap \
# Comment out ErrorLog and CustomLog parameters, we use rotatelogs in mediawiki.conf for the log files
&& sed -i 's/^\(\s*ErrorLog .*\)/# \1/g' /etc/apache2/apache2.conf \
Expand All @@ -774,8 +785,12 @@
&& sed -i 's/MW_CONFIG_FILE/CANASTA_CONFIG_FILE/g' "$MW_HOME/includes/CanastaNoLocalSettings.php" \
# Modify config
&& sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf \
&& a2enmod expires \
&& a2enmod expires remoteip \
&& a2disconf other-vhosts-access-log \
# For Widgets extension
&& mkdir -p $MW_ORIGIN_FILES/canasta-extensions/Widgets \
&& mv $MW_HOME/canasta-extensions/Widgets/compiled_templates $MW_ORIGIN_FILES/canasta-extensions/Widgets/ \
&& ln -s $MW_VOLUME/canasta-extensions/Widgets/compiled_templates $MW_HOME/canasta-extensions/Widgets/compiled_templates \
# Enable environment variables for FPM workers
&& sed -i '/clear_env/s/^;//' /etc/php/7.4/fpm/pool.d/www.conf

Expand Down
59 changes: 53 additions & 6 deletions _sources/canasta/CanastaDefaultSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
}

$canastaLocalSettingsFilePath = getenv( 'MW_VOLUME' ) . '/config/LocalSettings.php';
$canastaCommonSettingsFilePath = getenv( 'MW_VOLUME' ) . '/config/CommonSettings.php';

if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
// Called from WebInstaller or similar entry point

if ( !file_exists( $canastaLocalSettingsFilePath ) ) {
if ( !file_exists( $canastaLocalSettingsFilePath ) && !file_exists( $canastaCommonSettingsFilePath ) ) {
// Remove all variables, WebInstaller should decide that "$IP/LocalSettings.php" does not exist.
$vars = array_keys( get_defined_vars() );
foreach ( $vars as $v => $k ) {
Expand All @@ -22,7 +24,7 @@
// WebStart entry point

// Check that user's LocalSettings.php exists
if ( !is_readable( $canastaLocalSettingsFilePath ) ) {
if ( !is_readable( $canastaLocalSettingsFilePath ) && !is_readable( $canastaCommonSettingsFilePath ) ) {
// Emulate that "$IP/LocalSettings.php" does not exist

// Set CANASTA_CONFIG_FILE for NoLocalSettings template work correctly in includes/CanastaNoLocalSettings.php
Expand Down Expand Up @@ -68,10 +70,55 @@
$wgCdnServersNoPurge[] = '172.16.0.0/12'; // 172.16.0.0 – 172.31.255.255
$wgCdnServersNoPurge[] = '192.168.0.0/16'; // 192.168.0.0 – 192.168.255.255

/**
* Returns boolean value from environment variable
* Must return the same result as isTrue function in run-apache.sh file
* @param $value
* @return bool
*/
function isEnvTrue( $name ): bool {
$value = getenv( $name );
switch ( $value ) {
case "True":
case "TRUE":
case "true":
case "1":
return true;
}
return false;
}

$DOCKER_MW_VOLUME = getenv( 'MW_VOLUME' );

## Set $wgCacheDirectory to a writable directory on the web server
## to make your wiki go slightly faster. The directory should not
## be publicly accessible from the web.
$wgCacheDirectory = isEnvTrue( 'MW_USE_CACHE_DIRECTORY' ) ? "$DOCKER_MW_VOLUME/l10n_cache" : false;

# SemanticMediaWiki
$smwgConfigFileDir = "$DOCKER_MW_VOLUME/extensions/SemanticMediaWiki/config";

# Include user defined CommonSettings.php file
if ( file_exists( $canastaCommonSettingsFilePath ) ) {
require_once "$canastaCommonSettingsFilePath";
}

# Include user defined LocalSettings.php file
require_once "$canastaLocalSettingsFilePath";
if ( file_exists( $canastaLocalSettingsFilePath ) ) {
require_once "$canastaLocalSettingsFilePath";
}

$filenames = glob( getenv( 'MW_VOLUME' ) . '/config/settings/*.php' );

if ( $filenames !== false && is_array( $filenames ) ) {
sort( $filenames );

foreach ( $filenames as $filename ) {
require_once "$filename";
}
}

# Include all php files in config/settings directory
foreach (glob(getenv( 'MW_VOLUME' ) . '/config/settings/*.php') as $filename) {
require_once $filename;
# Include the FarmConfig
if ( file_exists( getenv( 'MW_VOLUME' ) . '/config/wikis.yaml' ) ) {
require_once "$IP/FarmConfigLoader.php";
}
153 changes: 153 additions & 0 deletions _sources/canasta/FarmConfigLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php

# Protect against web entry
if ( !defined( 'MEDIAWIKI' ) ) {
exit;
}

// Get the original URL from the environment variables
$original_url = getenv( 'ORIGINAL_URL' );
$serverName = "";
$path = "";

// Check if the original URL is defined, else throw an exception
if ( $original_url === false && !defined( 'MW_WIKI_NAME' ) ) {
return;
}

// Parse the original URL
$urlComponents = parse_url( $original_url );

// Check if URL parsing was successful, else throw an exception
if ( $urlComponents === false ) {
throw new Exception( 'Error: Failed to parse the original URL' );
}

// Extract the server name (host) from the URL
if ( isset( $urlComponents['host'] ) ) {
$serverName = $urlComponents['host'];
}

// Extract the path from the URL, if any
if ( isset( $urlComponents['path'] ) ) {
// Split the path into parts
$pathParts = explode( '/', trim( $urlComponents['path'], '/' ) );

// Check if path splitting was successful, else throw an exception
if ( $pathParts === false ) {
throw new Exception( 'Error: Failed to split the path into parts' );
}

// If there is a path, store the first directory in the variable $path
if ( count( $pathParts ) > 0 ) {
$firstDirectory = $pathParts[0];
}

// If the first directory is not "wiki" or "w", store it in the variable $path
if ( $firstDirectory != "wiki" && $firstDirectory != "w" ) {
$path = $firstDirectory;
}
}

// Parse the YAML configuration file containing the wiki information
$wikiConfigurations = null;

try {
// Get the file path of the YAML configuration file
$file = getenv( 'MW_VOLUME' ) . '/config/wikis.yaml';

// Check if the configuration file exists, else throw an exception
if ( !file_exists( $file ) ) {
throw new Exception( 'The configuration file does not exist' );
}

// Parse the configuration file
$wikiConfigurations = yaml_parse_file( $file );

// Check if file parsing was successful, else throw an exception
if ( $wikiConfigurations === false ) {
throw new Exception( 'Error parsing the configuration file' );
}
} catch ( Exception $e ) {
die( 'Caught exception: ' . $e->getMessage() );
}

$wikiIdToConfigMap = [];
$urlToWikiIdMap = [];

// Populate the arrays with data from the configuration file
if ( isset( $wikiConfigurations ) && isset( $wikiConfigurations['wikis'] ) && is_array( $wikiConfigurations['wikis'] ) ) {
foreach ( $wikiConfigurations['wikis'] as $wiki ) {
// Check if 'url' and 'id' are set before using them
if ( isset( $wiki['url'] ) && isset( $wiki['id'] ) ) {
$urlToWikiIdMap[$wiki['url']] = $wiki['id'];
$wikiIdToConfigMap[$wiki['id']] = $wiki;
} else {
throw new Exception( 'Error: The wiki configuration is missing either the url or id attribute.' );
}
}
} else {
throw new Exception( 'Error: Invalid wiki configurations.' );
}

// Prepare the key using the server name and the path
if ( empty( $path ) ) {
$key = $serverName;
} else {
$key = $serverName . '/' . $path;
}

// Retrieve the wikiID if available
$wikiID = defined( 'MW_WIKI_NAME' ) ? MW_WIKI_NAME : null;

// Check if the key is null or if it exists in the urlToWikiIdMap, else throw an exception
if ( $key === null ) {
throw new Exception( "Error: Key is null." );
} elseif ( $wikiID === null && array_key_exists( $key, $urlToWikiIdMap ) ) {
$wikiID = $urlToWikiIdMap[$key];
} elseif ( $wikiID === null ) {
throw new Exception( "Error: $key does not exist in urlToWikiIdMap." );
}

// Get the configuration for the selected wiki
$selectedWikiConfig = $wikiIdToConfigMap[$wikiID] ?? null;

// Check if a matching configuration was found. If so, configure the wiki database, else terminate execution
if ( !empty( $selectedWikiConfig ) ) {
// Set database name to the wiki ID
$wgDBname = $wikiID;

// Set site name and meta namespace from the configuration, or use the wiki ID if 'name' is not set
$wgSitename = isset( $selectedWikiConfig['name'] ) ? $selectedWikiConfig['name'] : $wikiID;
$wgMetaNamespace = isset( $selectedWikiConfig['name'] ) ? $selectedWikiConfig['name'] : $wikiID;
} else {
die( 'Unknown wiki.' );
}

// Configure the wiki server and URL paths
$wgServer = "https://$serverName";
$wgScriptPath = !empty( $path )
? "/$path/w"
: "/w";

$wgArticlePath = !empty( $path )
? "/$path/wiki/$1"
: "/wiki/$1";
$wgCacheDirectory = "$IP/cache/$wikiID";
$wgUploadDirectory = "$IP/images/$wikiID";

// Load additional configuration files specific to the wiki ID
$files = glob( getenv( 'MW_VOLUME' ) . "/config/{$wikiID}/*.php" );

$wgEnableUploads = true;

// Check if the glob function was successful, else continue with the execution
if ( $files !== false && is_array( $files ) ) {
// Sort the files
sort( $files );

// Include each file
foreach ( $files as $filename ) {
require_once "$filename";
}
}
Loading
Loading