diff --git a/.github/workflows/oci.yml b/.github/workflows/oci.yml index 94ca2a8..7521a0d 100644 --- a/.github/workflows/oci.yml +++ b/.github/workflows/oci.yml @@ -34,25 +34,25 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push PHP 8.1 image - run: | - nix build .#wordpress-php81 - docker load < result - docker tag wordpress-php81:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php81 - docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php81 - - name: Build and push PHP 8.2 image run: | nix build .#wordpress-php82 docker load < result docker tag wordpress-php82:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php82 docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php82 - docker tag wordpress-php82:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - name: Build and push PHP 8.3 image run: | nix build .#wordpress-php83 docker load < result docker tag wordpress-php83:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php83 - docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php83 \ No newline at end of file + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php83 + docker tag wordpress-php83:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + + - name: Build and push PHP 8.4 image + run: | + nix build .#wordpress-php84 + docker load < result + docker tag wordpress-php84:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php84 + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:php84 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 877149b..f9d5089 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: '3.8' services: wordpress: # image: ghcr.io/avunu/wordpress:latest-php83 - image: wordpress-php82:latest + image: wordpress-php83:latest ports: - "8080:80" volumes: @@ -13,14 +13,14 @@ services: - WORDPRESS_DB_USER=wordpress - WORDPRESS_DB_PASSWORD=wordpresspassword - WORDPRESS_DB_NAME=wordpress - - WORDPRESS_AUTH_KEY=$AUTH_KEY - - WORDPRESS_SECURE_AUTH_KEY=$SECURE_AUTH_KEY - - WORDPRESS_LOGGED_IN_KEY=$LOGGED_IN_KEY - - WORDPRESS_NONCE_KEY=$NONCE_KEY - - WORDPRESS_AUTH_SALT=$AUTH_SALT - - WORDPRESS_SECURE_AUTH_SALT=$SECURE_AUTH_SALT - - WORDPRESS_LOGGED_IN_SALT=$LOGGED_IN_SALT - - WORDPRESS_NONCE_SALT=$NONCE_SALT + - WORDPRESS_AUTH_KEY=${WORDPRESS_AUTH_KEY} + - WORDPRESS_SECURE_AUTH_KEY=${WORDPRESS_SECURE_AUTH_KEY} + - WORDPRESS_LOGGED_IN_KEY=${WORDPRESS_LOGGED_IN_KEY} + - WORDPRESS_NONCE_KEY=${WORDPRESS_NONCE_KEY} + - WORDPRESS_AUTH_SALT=${WORDPRESS_AUTH_SALT} + - WORDPRESS_SECURE_AUTH_SALT=${WORDPRESS_SECURE_AUTH_SALT} + - WORDPRESS_LOGGED_IN_SALT=${WORDPRESS_LOGGED_IN_SALT} + - WORDPRESS_NONCE_SALT=${WORDPRESS_NONCE_SALT} depends_on: - db diff --git a/flake.nix b/flake.nix index d874e39..84b4a10 100644 --- a/flake.nix +++ b/flake.nix @@ -1,133 +1,28 @@ { - description = "FrankenPHP with latest PHP versions using nix2container and skopeo"; + description = "WordPress FrankenPHP NixOS containers with multiple PHP versions"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; }; - outputs = { self, nixpkgs, flake-utils, nix2container, ... }: + outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let - pkgs = import nixpkgs { - inherit system; - overlays = [ - (final: prev: { - phpCommonConfig = { - embedSupport = true; - ztsSupport = true; - apxs2Support = false; - systemdSupport = false; - phpdbgSupport = false; - cgiSupport = false; - fpmSupport = false; - }; - - optimizePhp = phpPackage: (phpPackage.override final.phpCommonConfig).withExtensions - ({ all, ... }: with all; [ - curl dom exif fileinfo gd iconv imagick intl - mbstring mysqli opcache openssl sodium xml zip - ]); - - php81Optimized = final.optimizePhp prev.php81; - php82Optimized = final.optimizePhp prev.php82; - php83Optimized = final.optimizePhp prev.php83; - - buildWordpressPhp = { php, name }: - let - busyboxWithApps = pkgs.busybox.override { - enableStatic = true; - enableAppletSymlinks = true; - }; - image = nix2container.packages.${system}.nix2container.buildImage { - inherit name; - tag = "latest"; - copyToRoot = pkgs.buildEnv { - name = "root"; - paths = [ - busyboxWithApps - pkgs.coreutils - pkgs.curl - pkgs.frankenphp - php - pkgs.cacert - pkgs.ghostscript - pkgs.libxml2 - pkgs.mariadb.client - pkgs.unzip - (pkgs.writeTextFile { - name = "wp-config.php"; - text = builtins.readFile ./wp-config.php; - destination = "/opt/wp-config.php"; - }) - (pkgs.writeScriptBin "docker-entrypoint.sh" (builtins.readFile ./docker-entrypoint.sh)) - (pkgs.runCommand "shell-setup" {} '' - mkdir -p $out/bin - ln -s ${busyboxWithApps}/bin/sh $out/bin/sh - '') - ]; - pathsToLink = [ "/bin" "/etc" "/lib" "/opt" "/usr" ]; - }; - config = { - Entrypoint = [ "/bin/docker-entrypoint.sh" ]; - Cmd = [ "frankenphp" "php-server" "--root" "/var/www/html" "--listen" "0.0.0.0:80" ]; - ExposedPorts = { - "80/tcp" = {}; - }; - Env = [ - "WORDPRESS_SOURCE_URL=https://wordpress.org/latest.zip" - "WORDPRESS_DB_HOST=localhost" - "WORDPRESS_DB_USER=wordpress" - "WORDPRESS_DB_PASSWORD=wordpress" - "WORDPRESS_DB_NAME=wordpress" - "WORDPRESS_AUTH_KEY=key" - "WORDPRESS_SECURE_AUTH_KEY=key" - "WORDPRESS_LOGGED_IN_KEY=key" - "WORDPRESS_NONCE_KEY=key" - "WORDPRESS_AUTH_SALT=key" - "WORDPRESS_SECURE_AUTH_SALT=key" - "WORDPRESS_LOGGED_IN_SALT=key" - "WORDPRESS_NONCE_SALT=key" - ]; - }; - }; - in pkgs.buildPackages.runCommand "docker-image-${name}" - { - nativeBuildInputs = [ pkgs.buildPackages.skopeo pkgs.buildPackages.bubblewrap ]; - } - '' - mkdir -p $out - # Create a fake /var/tmp directory for skopeo - mkdir -p $TMPDIR/fake-var/tmp - args=(--unshare-user --bind "$TMPDIR/fake-var" /var) - for dir in /*; do - args+=(--dev-bind "/$dir" "/$dir") - done - bwrap ''${args[@]} -- ${pkgs.lib.getExe image.copyTo} docker-archive:$out/${name}.tar - gzip $out/${name}.tar - echo "${name}" > $out/image-name - ''; - }) - ]; - }; + pkgs = nixpkgs.legacyPackages.${system}; + + mkWordPressImage = phpVersion: + import ./wordpress.nix { + inherit pkgs; + php = pkgs.${phpVersion}; + imageName = "wordpress-${phpVersion}"; + }; in { packages = { - wordpress-php81 = pkgs.buildWordpressPhp { - php = pkgs.php81Optimized; - name = "wordpress-php81"; - }; - wordpress-php82 = pkgs.buildWordpressPhp { - php = pkgs.php82Optimized; - name = "wordpress-php82"; - }; - wordpress-php83 = pkgs.buildWordpressPhp { - php = pkgs.php83Optimized; - name = "wordpress-php83"; - }; + wordpress-php82 = mkWordPressImage "php82"; + wordpress-php83 = mkWordPressImage "php83"; + wordpress-php84 = mkWordPressImage "php84"; + default = self.packages.${system}.wordpress-php83; }; } ); diff --git a/flake.nix.bak b/flake.nix.bak deleted file mode 100644 index 83e0063..0000000 --- a/flake.nix.bak +++ /dev/null @@ -1,101 +0,0 @@ -{ - description = "FrankenPHP with latest PHP versions"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - # frankenwp = { - # url = "github:StephenMiracle/frankenwp"; - # flake = false; - # }; - }; - - outputs = { self, nixpkgs, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ - (final: prev: { - phpCommonConfig = { - embedSupport = true; - ztsSupport = true; - apxs2Support = false; - systemdSupport = false; - phpdbgSupport = false; - cgiSupport = false; - fpmSupport = false; - }; - - optimizePhp = phpPackage: (phpPackage.override final.phpCommonConfig).withExtensions - ({ all, ... }: with all; [ - curl dom exif fileinfo gd iconv imagick intl - mbstring mysqli opcache openssl sodium xml zip - ]); - - php81Optimized = final.optimizePhp prev.php81; - php82Optimized = final.optimizePhp prev.php82; - php83Optimized = final.optimizePhp prev.php83; - - buildwordpress-php = { php, name }: - final.dockerTools.buildLayeredImage { - inherit name; - tag = "latest"; - contents = [ - final.frankenphp - php - final.busybox - final.cacert - final.curl - final.ghostscript - final.libxml2 - final.mariadb.client - final.unzip - ]; - extraCommands = '' - mkdir -p var/www/html usr/bin - cp ${./wp-config.php} wp-config.php - cp ${./docker-entrypoint.sh} docker-entrypoint.sh - chmod +x docker-entrypoint.sh - ln -s ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt etc/ssl/certs/ca-certificates.crt - ln -s ${pkgs.busybox}/bin/sh usr/bin/bash - ''; - config = { - Entrypoint = [ "/docker-entrypoint.sh" ]; - Cmd = [ "frankenphp" "php-server" "--root" "/var/www/html" "--listen" "0.0.0.0:80" ]; - ExposedPorts = { - "80/tcp" = {}; - }; - Env = [ - "PHP_INI_DIR=/usr/local/etc/php" - "WORDPRESS_VERSION=latest" - "WORDPRESS_SHA1=" - "WORDPRESS_DB_HOST=localhost" - "WORDPRESS_DB_USER=wordpress" - "WORDPRESS_DB_PASSWORD=wordpress" - "WORDPRESS_DB_NAME=wordpress" - "WORDPRESS_TABLE_PREFIX=wp_" - ]; - }; - }; - }) - ]; - }; - in { - packages = { - wordpress-php81 = pkgs.buildwordpress-php { - php = pkgs.php81Optimized; - name = "wordpress-php81"; - }; - wordpress-php82 = pkgs.buildwordpress-php { - php = pkgs.php82Optimized; - name = "wordpress-php82"; - }; - wordpress-php83 = pkgs.buildwordpress-php { - php = pkgs.php83Optimized; - name = "wordpress-php83"; - }; - }; - } - ); -} \ No newline at end of file diff --git a/wordpress.nix b/wordpress.nix index 247b284..d0bcf2e 100644 --- a/wordpress.nix +++ b/wordpress.nix @@ -1,61 +1,113 @@ { pkgs, php, imageName }: let - phpBuild = php.buildEnv { - extensions = { all, enabled }: with all; enabled ++ [ - # Required extensions - mysqli + customPhp = (php.override { + # Sapi flags + cgiSupport = false; + cliSupport = true; # CLI is needed for FrankenPHP + fpmSupport = false; + pearSupport = false; + pharSupport = true; # Needed for Composer and some WordPress plugins + phpdbgSupport = false; - # Highly recommended extensions - curl - dom - exif - fileinfo - imagick - intl - mbstring - openssl - xml - zip + # Misc flags + apxs2Support = false; + argon2Support = true; # Useful for password hashing + cgotoSupport = false; + embedSupport = true; # Needed for FrankenPHP + staticSupport = false; + ipv6Support = true; + zendSignalsSupport = false; + zendMaxExecutionTimersSupport = true; + systemdSupport = false; + valgrindSupport = false; + ztsSupport = true; # Needed for FrankenPHP + }).overrideAttrs (oldAttrs: { + # Explicitly enable XML support + configureFlags = (oldAttrs.configureFlags or [ ]) ++ [ + "--enable-xml" + "--with-libxml" + ]; - # Recommended for caching (choose one or more as needed) - opcache - # redis + buildInputs = (oldAttrs.buildInputs or [ ]) ++ [ + pkgs.libxml2.dev + ]; + }); - # Optional extensions for improved functionality - gd - iconv - sodium + phpWithExtensions = customPhp.withExtensions ({ all, ... }: with all; [ + # Required extensions + mysqli - # Development extensions (can be removed in production) - # xdebug - ]; + # Highly recommended extensions + curl + dom + exif + fileinfo + imagick + intl + mbstring + openssl + xml + zip + + # Recommended for caching + opcache + + # Optional extensions for improved functionality + gd + iconv + sodium + + # Development extensions (uncomment if needed in production) + # xdebug + ]); + + phpBuild = phpWithExtensions.buildEnv { extraConfig = '' memory_limit = 256M upload_max_filesize = 100M post_max_size = 100M max_execution_time = 300 + zend.max_allowed_stack_size = -1 + opcache.enable = 1 + ffi.enable = 1 ''; }; + + frankenphp = (pkgs.frankenphp.override { + php = phpBuild; + }).overrideAttrs (oldAttrs: { + # Here we override the let...in section + phpEmbedWithZts = phpBuild; + phpUnwrapped = phpBuild.unwrapped; + phpConfig = "${phpBuild.unwrapped.dev}/bin/php-config"; + # no musl support + pieBuild = false; + }); + + wp-cli = (pkgs.wp-cli.override { + php = phpBuild; + }); + in pkgs.dockerTools.buildLayeredImage { name = imageName; tag = "latest"; contents = [ + frankenphp phpBuild pkgs.busybox pkgs.cacert - pkgs.frankenphp pkgs.ghostscript pkgs.imagemagick pkgs.mysql.client pkgs.vips - pkgs.wp-cli + wp-cli ]; config = { Entrypoint = [ "${pkgs.busybox}/bin/sh" "/docker-entrypoint.sh" ]; - Cmd = [ "${pkgs.lib.getExe pkgs.frankenphp}" "php-server" "--root" "/var/www/html" "--listen" "0.0.0.0:80" ]; + Cmd = [ "${pkgs.lib.getExe frankenphp}" "php-server" "--root" "/var/www/html" "--listen" "0.0.0.0:80" ]; ExposedPorts = { "80/tcp" = { }; }; diff --git a/wp-config.php b/wp-config.php index 61d8c36..b64da3c 100644 --- a/wp-config.php +++ b/wp-config.php @@ -40,6 +40,11 @@ define( 'WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] ); } +define('FS_METHOD', 'direct'); +define('WP_AUTO_UPDATE_CORE', 'minor'); +define('CONCATENATE_SCRIPTS', false); +define('DISALLOW_FILE_EDIT', true); + // That's all, stop editing! Happy publishing. if ( ! defined( 'ABSPATH' ) ) { define( 'ABSPATH', dirname( __FILE__ ) . '/' );