diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix new file mode 100644 index 000000000000..01b6cfc62afb --- /dev/null +++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix @@ -0,0 +1,209 @@ +{ config, lib, pkgs, serverInfo, php, ... }: + +with lib; + +let + # https://wordpress.org/plugins/postgresql-for-wordpress/ + # Wordpress plugin 'postgresql-for-wordpress' installation example + postgresqlForWordpressPlugin = pkgs.stdenv.mkDerivation { + name = "postgresql-for-wordpress-plugin"; + # Download the theme from the wordpress site + src = pkgs.fetchurl { + url = https://downloads.wordpress.org/plugin/postgresql-for-wordpress.1.3.1.zip; + sha256 = "f11a5d76af884c7bec2bc653ed5bd29d3ede9a8657bd67ab7824e329e5d809e8"; + }; + # We need unzip to build this package + buildInputs = [ pkgs.unzip ]; + # Installing simply means copying all files to the output directory + installPhase = "mkdir -p $out; cp -R * $out/"; + }; + + # Our bare-bones wp-config.php file using the above settings + wordpressConfig = pkgs.writeText "wp-config.php" '' + + RewriteEngine On + RewriteBase / + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.php [L] + + ''; + + # The wordpress package itself + wordpressRoot = pkgs.stdenv.mkDerivation rec { + name = "wordpress"; + # Fetch directly from the wordpress site, want to upgrade? + # Just change the version URL and update the hash + src = pkgs.fetchurl { + url = http://wordpress.org/wordpress-4.1.1.tar.gz; + sha256 = "1s9y0i9ms3m6dswb9gqrr95plnx6imahc07fyhvrp5g35f6c12k1"; + }; + installPhase = '' + mkdir -p $out + # Copy all the wordpress files we downloaded + cp -R * $out/ + # We'll symlink the wordpress config + ln -s ${wordpressConfig} $out/wp-config.php + # As well as our custom .htaccess + ln -s ${htaccess} $out/.htaccess + # And the uploads directory + ln -s ${config.wordpressUploads} $out/wp-content/uploads + # And the theme(s) + ${concatMapStrings (theme: "ln -s ${theme} $out/wp-content/themes/${theme.name}\n") config.themes} + # And the plugin(s) + # remove bundled plugin(s) coming with wordpress + rm -Rf $out/wp-content/plugins/akismet + # install plugins + ${concatMapStrings (plugin: "ln -s ${plugin} $out/wp-content/plugins/${plugin.name}\n") (config.plugins ++ [ postgresqlForWordpressPlugin]) } + ''; + }; + +in + +{ + + # And some httpd extraConfig to make things work nicely + extraConfig = '' + + DirectoryIndex index.php + Allow from * + Options FollowSymLinks + AllowOverride All + + ''; + + enablePHP = true; + + options = { + dbHost = mkOption { + default = "localhost"; + description = "The location of the database server."; + example = "localhost"; + }; + dbName = mkOption { + default = "wordpress"; + description = "Name of the database that holds the Wordpress data."; + example = "localhost"; + }; + dbUser = mkOption { + default = "wordpress"; + description = "The dbUser, read the username, for the database."; + example = "wordpress"; + }; + dbPassword = mkOption { + default = "wordpress"; + description = "The password to the respective dbUser."; + example = "wordpress"; + }; + tablePrefix = mkOption { + default = "wp_"; + description = '' + The $table_prefix is the value placed in the front of your database tables. Change the value if you want to use something other than wp_ for your database prefix. Typically this is changed if you are installing multiple WordPress blogs in the same database. See . + ''; + }; + wordpressUploads = mkOption { + default = "/data/uploads"; + description = '' + This directory is used for uploads of pictures and must be accessible (read: owned) by the httpd running user. The directory passed here is automatically created and permissions are given to the httpd running user. + ''; + }; + plugins = mkOption { + default = []; + type = types.listOf types.path; + description = + '' + List of path(s) to respective plugin(s) which are symlinked from the 'plugins' directory. Note: These plugins need to be packaged before use. + ''; + example = '' + # Wordpress plugin 'akismet' installation example + akismetPlugin = pkgs.stdenv.mkDerivation { + name = "akismet-plugin"; + # Download the theme from the wordpress site + src = pkgs.fetchurl { + url = https://downloads.wordpress.org/plugin/akismet.3.1.zip; + sha256 = "1i4k7qyzna08822ncaz5l00wwxkwcdg4j9h3z2g0ay23q640pclg"; + }; + # We need unzip to build this package + buildInputs = [ pkgs.unzip ]; + # Installing simply means copying all files to the output directory + installPhase = "mkdir -p $out; cp -R * $out/"; + }; + + And then pass this theme to the themes list like this: + plugins = [ akismetPlugin ]; + ''; + }; + themes = mkOption { + default = []; + type = types.listOf types.path; + description = + '' + List of path(s) to respective theme(s) which are symlinked from the 'theme' directory. Note: These themes need to be packaged before use. + ''; + example = '' + # For shits and giggles, let's package the responsive theme + responsiveTheme = pkgs.stdenv.mkDerivation { + name = "responsive-theme"; + # Download the theme from the wordpress site + src = pkgs.fetchurl { + url = http://wordpress.org/themes/download/responsive.1.9.7.6.zip; + sha256 = "06i26xlc5kdnx903b1gfvnysx49fb4kh4pixn89qii3a30fgd8r8"; + }; + # We need unzip to build this package + buildInputs = [ pkgs.unzip ]; + # Installing simply means copying all files to the output directory + installPhase = "mkdir -p $out; cp -R * $out/"; + }; + + And then pass this theme to the themes list like this: + themes = [ responsiveTheme ]; + ''; + }; + extraConfig = mkOption { + default = ""; + example = + '' + define( 'AUTOSAVE_INTERVAL', 60 ); // Seconds + ''; + description = '' + Any additional text to be appended to Wordpress's wp-config.php + configuration file. This is a PHP script. For configuration + settings, see . + ''; + }; + }; + + documentRoot = wordpressRoot; + + startupScript = pkgs.writeScript "init-wordpress.sh" '' + #!/bin/sh + mkdir -p ${config.wordpressUploads} + chown ${serverInfo.serverConfig.user} ${config.wordpressUploads} + + # we should use systemd dependencies here + #waitForUnit("network-interfaces.target"); + if [ ! -d ${serverInfo.fullConfig.services.mysql.dataDir}/${config.dbName} ]; then + # Wait until MySQL is up + while [ ! -e /var/run/mysql/mysqld.pid ]; do + sleep 1 + done + ${pkgs.mysql}/bin/mysql -e 'CREATE DATABASE ${config.dbName};' + ${pkgs.mysql}/bin/mysql -e 'GRANT ALL ON ${config.dbName}.* TO ${config.dbUser}@localhost IDENTIFIED BY "${config.dbPassword}";' + fi + ''; +}