PHP-FPM's imagick module cannot access Ghostscript

My php code fails with the following error message PHP Fatal error: Uncaught ImagickException: FailedToExecuteCommand ‘gs’ -sstdout=%stderr -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 ‘-sDEVICE=pngalpha’ -dTextAlphaBits=4 -dGraphicsAlphaBits=4 ‘-r72x72’ -dPrinted=false ‘-sOutputFile=/tmp/magick-o-_h4WGFpV8Dw-PZ2mGU8L_V_PjNZhHk%d’ ‘-f/tmp/magick-3JXH9KP2lHlWlrZKIcI-WazZArgOZTlh’ ‘-f/tmp/magick-s9Th3fJJEfjbIxsl6N–vG8BM5CE7mlW’’ (32512) @ error/ghostscript-private.h/ExecuteGhostscriptCommand/75 in …`

Here is a part of my configuration.nix:

environment.systemPackages = with pkgs; [
                ...
                imagemagickBig
                ghostscript
               ( php83.buildEnv {
                        extensions = ({enabled, all}: enabled ++ (with all; [
                                apcu
                                bcmath
                                gmp
                                imagick
                                opcache
                                pdo
                                pdo_mysql
                          ]));
                          extraConfig = ''
                                apc.enable_cli = 1
                          '';
                        })
                php.packages.composer
                mariadb
        ];

This is my Nginx configuration:

{ config, ... }:

{
        networking.firewall.allowedTCPPorts = [ 80 443 ];  # Open HTTP & HTTPS. Add 3306 to open MySQL if needed externally.

        security.acme = {
                acceptTerms = true;

                defaults = {
                        email = "name@email";
                };
        };

        services.nginx = {
                enable = true;

                virtualHosts = {
                        "thedomain" = {
                                enableACME = true;
                                forceSSL = true;
                                root = "/var/www/dev";

                                locations."/" = {
                                        index = "index.php";  # Correct way to set the index file
                                        tryFiles = "$uri $uri/ /index.php?$query_string";
                                };
                                locations."/wp-json/" = {
                                        tryFiles = "$uri $uri/ /index.php$is_args$args";
                                };
                                # PHP-FPM Configuration
                                locations."~* \.php$" = {
                                        extraConfig = ''
                                                fastcgi_pass unix:${ config.services.phpfpm.pools.defaultpool.socket };
                                                fastcgi_index index.php;
                                                include ${ config.services.nginx.package }/conf/fastcgi.conf;
                                                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                                        '';
                                };

                                listen = [
                                        { addr = "*"; port = 80; }  # Explicitly listen on HTTP
                                        { addr = "*"; port = 443; ssl = true; }  # Listen on HTTPS
                                ];
                        };
                };
        };

        systemd.services.nginx.environment = {
                LD_LIBRARY_PATH = "/nix/store/xmwfnpci7bjw95dhsbip40yav4zw803f-ghostscript-with-X-10.04.0/lib:/nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib";
        };
}

And this is my PHP-FPM configuration:

{ config, lib, pkgs, ... }:

{
        services.phpfpm = {
                phpPackage = pkgs.php83.withExtensions ( { enabled, all }: enabled ++ ( with all; [
                        imagick
                ] ) );
                pools = {
                        defaultpool = {
                                user = "nginx";
                                group = "nginx";
                                settings = {
                                        "listen.owner" = "nginx";
                                        "listen.group" = "nginx";
                                        "listen.mode" = "0660";
                                        "pm" = "dynamic";
                                        "pm.max_children" = 10;
                                        "pm.start_servers" = 2;
                                        "pm.min_spare_servers" = 2;
                                        "pm.max_spare_servers" = 5;
                                        "pm.max_requests" = 500;
                                        "env[TMPDIR]" = "/tmp";
                                };
                        };
                };
        };

        # Ensure PHP-FPM can find Ghostscript
        systemd.services.phpfpm.serviceConfig.Environment = [
                "PATH=${lib.makeBinPath [ pkgs.ghostscript pkgs.coreutils ]}"
        ];
}

Can anyone help my me to make it work, please?

try this instead, maybe it will work:

services.phpfpm.pools.defaultPool.settings."env[PATH]" = "${lib.makeBinPath [ pkgs.ghostscript pkgs.coreutils ]}"
2 Likes

Great! After at least four hours of internet research and AI assistance and countless changes in the configuration code that all lead to nothing this single line made my day! Thanks a lot!

1 Like

glad to hear it worked

btw i don’t think this was a NixOS specific issue… look for clear_env in upstream docs

Yes, for sure you’re right. I think I never realized it on other servers that don’t use NixOS because of configuration presets.