Printing: Difference between revisions

From NixOS Wiki
imported>Fadenb
m Syntax highlighting
Writer (talk | contribs)
mNo edit summary
 
(73 intermediate revisions by 36 users not shown)
Line 1: Line 1:
= Basic configuration =
Printing in NixOS is done via the <code>services.printing</code> module, to configure the local printing services which is provided by the software [https://openprinting.github.io/projects/00-cups CUPS]. Setting up physical printer devices is done using <code>hardware.printers</code> option.


Add to <code>configuration.nix</code>:
== Installation ==
 
To enable the local print service on your machine, simply add following lines to your configuration


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
services.printing.enable = true;
services.printing.enable = true;
</syntaxhighlight>
== Configuration ==
=== Enable autodiscovery of network printers ===
Most printers manufactured after 2013 support the [https://www.pwg.org/ipp/everywhere.html IPP Everywhere] protocol, i.e. printing without installing drivers. This is notably the case of all WiFi printers marketed as Apple-compatible ([https://support.apple.com/en-ca/HT201311 list]).
To detect these printers, add the following to your system configuration:
<syntaxhighlight lang="nix">
services.avahi = {
  enable = true;
  nssmdns4 = true;
  openFirewall = true;
};
</syntaxhighlight>
Discovery is done via the opened UDP port <code>5353</code>. Printers should get automatically detected and visible in your printer configuration client.
=== Adding printers ===
Beside manually adding printers with client tools, it is possible to permanently add printers to your system configuration (but be aware of [https://github.com/NixOS/nixpkgs/issues/78535 this bug] that sometimes expect the printer to be plugged in your system). The following example configures a network printer called <code>Dell_1250c</code> to your local system, reachable via IPP at <code>http://192.168.178.2:631/printers/Dell_1250c</code>
<syntaxhighlight lang="nix">
hardware.printers = {
  ensurePrinters = [
    {
      name = "Dell_1250c";
      location = "Home";
      deviceUri = "http://192.168.178.2:631/printers/Dell_1250c";
      model = "drv:///sample.drv/generic.ppd";
      ppdOptions = {
        PageSize = "A4";
      };
    }
  ];
  ensureDefaultPrinter = "Dell_1250c";
};
</syntaxhighlight>
To add a local printer, connected via USB, change the <code>deviceUri</code> to a USB address and optionally define which driver to use by adding the <code>model</code> option.
<syntaxhighlight lang="nix">
hardware.printers = {
  ensurePrinters = [
    {
      name = "Dell_1250c";
      location = "Home";
      deviceUri = "usb://Dell/1250c%20Color%20Printer?serial=YNP023240";
      model = "Dell-1250c.ppd.gz";
      ppdOptions = {
        PageSize = "A4";
      };
    }
  ];
};
</syntaxhighlight>
Some local or network printers might need additional drivers. You can add them using the <code>drivers</code> option
<syntaxhighlight lang="nix">
services.printing.drivers = [ YOUR_DRIVER ];
services.printing.drivers = [ YOUR_DRIVER ];
</syntaxhighlight>
</syntaxhighlight>
Replace <code>YOUR_DRIVER</code> with the driver of your printer. The driver is a regular derivation but should be added to <syntaxhighlight lang="nix" inline>services.printing.drivers</syntaxhighlight>, ''not'' <syntaxhighlight lang="nix" inline>environment.systemPackages</syntaxhighlight>. [https://nixos.org/nixos/packages.html Search] for eg. "print driver".


* Some printers might be supported by the built-in CUPS drivers
where <code>YOUR_DRIVER</code> is the driver package appropriate for your printer. Commonly used driver packages include:
* HP: <code>hplip</code> or <code>hplipWithPlugin</code> depending on your [http://hplipopensource.com/hplip-web/supported_devices/index.html exact model]: Find your model and &quot;continue&quot;. Then search for &quot;Driver plug-in&quot; in the page.
 
* <tt>pkgs.gutenprint</tt> &mdash; Drivers for many different printers from many different vendors.
* <tt>pkgs.gutenprintBin</tt> &mdash; Additional, binary-only drivers for some printers.
* <tt>pkgs.hplip</tt> &mdash; Drivers for HP printers.
* <tt>pkgs.hplipWithPlugin</tt> &mdash; Drivers for HP printers, with the proprietary plugin. Use <code>NIXPKGS_ALLOW_UNFREE=1 nix-shell -p hplipWithPlugin --run 'sudo -E hp-setup'</code> to add the printer, regular CUPS UI doesn't seem to work.
* <tt>pkgs.postscript-lexmark</tt> &mdash; Postscript drivers for Lexmark
* <tt>pkgs.samsung-unified-linux-driver</tt> &mdash; Proprietary Samsung Drivers
* <tt>pkgs.splix</tt> &mdash; Drivers for printers supporting SPL (Samsung Printer Language).
* <tt>pkgs.brlaser</tt> &mdash; Drivers for some Brother printers
* <tt>pkgs.brgenml1lpr</tt> and <tt>pkgs.brgenml1cupswrapper</tt> &mdash; Generic drivers for more Brother printers [https://support.brother.com/g/s/id/linux/en/instruction_prn1a.html]
* <tt>pkgs.cnijfilter2</tt> &mdash; Drivers for some Canon Pixma devices (Proprietary driver)
 
Search for other printer drivers in the NixOS package directory: the official list of packages is [https://search.nixos.org/packages here]. Add the driver to {{nixos:option|services.printing.drivers}}, '''not''' {{nixos:option|environment.systemPackages}}.
 
 
To get the specific string for <code>model</code>, run <code>lpinfo -m</code> which will produce output similar to
 
<pre>
...
samsung/SCX-3200.ppd Samsung SCX-3200 Series
samsung/SCX-3400.ppd Samsung SCX-3400 Series
samsung/SCX-4100.ppd Samsung SCX-4100 Series
samsung/SCX-4200.ppd Samsung SCX-4200 Series
samsung/SCX-4300.ppd Samsung SCX-4300 Series
samsung/SCX-4500.ppd Samsung SCX-4500 Series
samsung/SCX-4500W.ppd Samsung SCX-4500W Series
samsung/SCX-4600.ppd Samsung SCX-4600 Series
samsung/SCX-4623.ppd Samsung SCX-4623 Series
...
</pre>
 
The <code>model</code> string is the first column. For example, for the Samsung SCX-4300 series, set <code>model = "samsung/SCX-4300.ppd";</code>
 
=== Printer sharing ===
 
Enable network sharing of the default local printer, also known as "AirPrinting". Note that <code>listenAddresses = [ "*:631" ];</code>, <code>allowFrom = [ "all" ];</code> and <code>openFirewall = true;</code> will enable anonymous access to your printer on all interfaces, you might want to restrict this.
 
<syntaxhighlight lang="nix">
services.avahi = {
  enable = true;
  nssmdns = true;
  openFirewall = true;
  publish = {
    enable = true;
    userServices = true;
  };
};
services.printing = {
  listenAddresses = [ "*:631" ];
  allowFrom = [ "all" ];
  browsing = true;
  defaultShared = true;
  openFirewall = true;
};
</syntaxhighlight>
 
Once printer sharing is enabled, it could be additionally advertised in the home network via the Samba protocol, [[Samba#Printer_sharing|see]].
 
== Usage ==
 
After enabling the printing service you'll be able to configure and add network printers via http://localhost:631. You may need to authenticate with your local user when you add the printer.
 
Depending on your desktop environment, there are several graphical tools available which will connect to this backend service and allow you a more convenient printer management, for example <code>system-config-printer</code>.
 
=== Command line ===
 
List printers
 
<syntaxhighlight lang="bash">
# lpstat -p
</syntaxhighlight>
 
Print test page for printer called <code>HP-LaserJet-1020</code>
 
<syntaxhighlight lang="bash">
# lp -o job-sheets=standard,none -d HP-LaserJet-1020 /dev/null
</syntaxhighlight>
 
List jobs


Then <code>nixos-rebuild switch</code>. This install and starts CUPS.
<syntaxhighlight lang="bash">
# lpstat
</syntaxhighlight>


Go to http://localhost:631 to add the printer. Note that you need to authenticate as root (or yourself if you have sudo access) when you add the printer. Search the web for eg. &quot;cups add printer&quot; for further help.
Cancel job


= Setup a shared printer =
<syntaxhighlight lang="bash">
# cancel 1
</syntaxhighlight>


== Server ==
== Tips and tricks ==


Follow the steps in [[#basic-configuration|basic configuration]] but make sure to check &quot;Share This Printer&quot; when adding the printer.
==== Manually supplying printer driver  ====


It's probably a good idea to check that printing work locally at the server at this point.
===== Provide the PPD imperatively =====
If no driver is found for your printer, even when <code>services.printing.drivers</code> is correctly populated (see above),
you can try to give cups a PPD file.
* Download the required PPD file, for example from [https://openprinting.org/printers openprinting.org]
* Open the PPD as a text file, and check that it does not mention FHS paths like <code>/usr/bin</code>. If it does, this method is unlikely to work, as the PPD file depends on executables not present on your system. You can certainly install the binaries yourself and point to the new binary, but it is certainly easier to patch the executables in a derivation (see below) to avoid garbage collection of your binaries.
* add the printer with <code>system-config-printer</code> (for example) and at the 'choose driver' screen choose 'provide PPD file'


Add to <code>configuration.nix</code>
===== Provide the PPD declaratively =====
 
You can also declaratively add the PPD as a new driver by creating a simple derivation. You just need to create a derivation that puts the PPD file in <code>$out/share/cups/model/yourfile.ppd</code> (you can also put it in a subfolder like <code>$out/share/cups/model/HP/yourfile.ppd</code> to limit conflicts between ppd having the same name). Note that the name of the file does not change the way cups will list it as the model/manufacturer is written inside the (text) ppd.
 
As in the imperative method, first check that your file does not contain any reference to binaries outside the store like <code>/bin/</code> or <code>/usr/</code>. If it does not contain any reference then you should be able to simply do this:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
# Enable automatic discovery of the printer (from other linux systems with avahi running)
{
services.avahi.enable = true;
  ...
services.avahi.publish.enable = true;
  services.printing.enable = true;
services.avahi.publish.userServices = true;
  services.printing.drivers = [
    (writeTextDir "share/cups/model/yourppd.ppd" (builtins.readFile ./yourppd.ppd))
  ];
  ...
}
</syntaxhighlight>


services.printing.browsing = true;
If your ppd contains links to external binaries, you can instead patch the file using for instance <code>substituteInPlace</code>. For that, create a file, say, <code>myPrinter.nix</code> containing something like:
services.printing.listenAddresses = [ "*:631" ]; # Not 100% sure this is needed and you might want to restrict to the local network
<syntaxhighlight lang="nix">
services.printing.defaultShared = true; # If you want
{ stdenv }:
stdenv.mkDerivation rec {
  name = "myprinter-${version}";
  version = "1.0";
 
  src = ./.;


networking.firewall.allowedUDPPorts = [ 631 ];
  installPhase = ''
networking.firewall.allowedTCPPorts = [ 631 ];
    mkdir -p $out/share/cups/model/
    cp myprinter.ppd $out/share/cups/model/
    # If you need to patch the path to files outside the nix store, you can do it this way
    # (if the ppd also comes with executables you may need to also patch the executables)
    substituteInPlace $out/share/cups/model/myprinter.ppd \
      --replace "/usr/yourProgram/" "${yourProgram}/bin/yourProgram"
  '';
}
</syntaxhighlight>
Of course update the name of the files and adapt the substituteInPlace command to your needs. Then add your driver as:
<syntaxhighlight lang="nix">
{
  ...
  services.printing.enable = true;
  services.printing.drivers = [
    (pkgs.callPackage ./myPrinter.nix {})
  ];
  ...
}
</syntaxhighlight>
</syntaxhighlight>
and <code>nixos-rebuild switch</code>.
Your PPD file should now appear next to the other PPD files installed on your system when you add a new printer.


Note: I ''think'' I had to check "Share printers connected to this system" and "Allow printing from the internet" at http://192.168.11.9:631/admin but I'm not sure.
For debugging purpose, it may be interesting to note that the data folder used by cups (containing the drivers and more) can be obtained by looking in the environment <code>$CUPS_DATADIR</code> (the contents of <code>$out/share/cups/</code> contained in your drivers are linked in this folder).


== Client (linux) ==
== Troubleshooting ==


If you enabled avahi user services in the server config it should be enough to turn on avahi on the client: <syntaxhighlight lang="nix" inline>services.avahi.enable = true</syntaxhighlight>. The printer should be found automatically (at least in the gnome print dialog).
=== Upgrade required ===
Described in: [https://github.com/NixOS/nixpkgs/issues/23993 Github issue 23993]<br />
'''Problem'''<br />
Using the cups web interface, the page tells you "Upgrade Required" and then redirects you to a page that fails to load.<br />


Otherwise CUPS (<code>services.printing</code>) should be enabled on the client too and a new network printer should be added to the local CUPS instance (http://localhost:631). Despite what the CUPS interface tell you the url scheme is <code>http://HOSTNAME:631/printers/QUEUE_NAME</code>, where QUEUE_NAME is the name you gave the printer at the server.
'''Cause'''<br />
When you are using http and cups wants authentication it will redirect you to a https version by default.<br />
In order to use https it needs ssl keys. However it is possible that cups fails to generate these keys, and then the page will fail to load.<br />


NB: https might not work due to missing certificates.
'''Solution'''<br />
Either we can help cups to get ssl keys, or we can tell it to not use https at all.<br />
''Generating ssl keys:''<br />
First make sure the directory /etc/cups/ssl exists:<br />
<code>sudo mkdir -p /etc/cups/ssl</code><br />
Try restarting cups and using the web interface again. This might be enough to get it working.<br />
If this didn't help, then check if cups has generated ssl keys in /etc/cups/ssl<br />
''Disabling ssl:''<br />
Edit your <code>/etc/nixos/configuration.nix</code> and add the following lines:<br />
<code><pre>services.printing.extraConf = ''
    DefaultEncryption Never
  '';</pre></code>


Refer to eg. https://wiki.archlinux.org/index.php/CUPS/Printer_sharing for further info.
===Unable to launch Ghostscript: gs: No such file or directory===
Described in: [https://github.com/NixOS/nixpkgs/issues/20806 Github issue 20806]
and [https://github.com/NixOS/nixpkgs/issues/22062 issues 22062]<br />
'''Problem'''<br />
When printing, cups will report an error: Unable to launch Ghostscript: gs: No such file or directory<br />


== Client (windows) ==
'''Cause'''<br />
Some drivers use the ghostscript binary.<br />
Cups will look for the binary path in it's config file: cupsd.conf<br />
This file is normally a link. But it can be overwritten, and consequentially become outdated.<br />
 
'''Solution'''<br />
You could try to manually fix the path variable in /var/lib/cups/cupsd.conf<br />
Alternatively you could try to delete the file and run <code>sudo nixos-rebuild switch</code>
 
===File is missing (Gnome 3)===
 
When you add an printer in Gnome (using <code>gnome-control-center printers</code>) you create a profile for your printer.
 
'''Problem'''<br />
But, later you may experience an error like '''"/nix/store/.../lib/cups/filter/pstospl not available: No such file or directory"'''.
 
'''Cause'''<br />
When you create a printer profile you get a freeze version of cups filter and when cups is updated, because you have upgraded your system, and garbage collected this version is gone.
 
'''Solution'''<br />
Go into the  <code>gnome-control-center printers</code> settings, remove the printer and recreate it.
 
=== Debugging a broken printer driver ===
 
Add to <code>/etc/nixos/configuration.nix</code>
 
<syntaxhighlight lang="nix">
services.printing.logLevel = "debug";
</syntaxhighlight>
 
Rebuild
 
<pre>
sudo nixos-rebuild switch
</pre>
 
Watch the cups logs
 
<syntaxhighlight lang=console>
$ journalctl --follow --unit=cups
</syntaxhighlight>
or
<syntaxhighlight lang=console>
$ journalctl --follow --unit=cups | grep -C10 --color=always -i -e 'No such file or directory' -e 'error:'
</syntaxhighlight>


See https://wiki.archlinux.org/index.php/CUPS/Printer_sharing#Sharing_via_IPP for now.
Start a print job


=== Sources ===
Now watch the cups logs for errors like <code>No such file or directory</code>


* [https://github.com/NixOS/nixpkgs/issues/13901 How to properly setup a shared (home) printer? #13901]
[[Category:Hardware]]
* [https://wiki.archlinux.org/index.php/CUPS/Printer_sharing Arch wiki - Printer sharing]
* [https://github.com/NixOS/nixpkgs/issues/23993 Little Printing/CUPS Documentation for Configuration as a Print Server #23993]
* [https://web.archive.org/web/20160829175522/https://nixos.org/wiki/Printers Old wiki page]

Latest revision as of 14:33, 12 November 2024

Printing in NixOS is done via the services.printing module, to configure the local printing services which is provided by the software CUPS. Setting up physical printer devices is done using hardware.printers option.

Installation

To enable the local print service on your machine, simply add following lines to your configuration

services.printing.enable = true;

Configuration

Enable autodiscovery of network printers

Most printers manufactured after 2013 support the IPP Everywhere protocol, i.e. printing without installing drivers. This is notably the case of all WiFi printers marketed as Apple-compatible (list).

To detect these printers, add the following to your system configuration:

services.avahi = {
  enable = true;
  nssmdns4 = true;
  openFirewall = true;
};

Discovery is done via the opened UDP port 5353. Printers should get automatically detected and visible in your printer configuration client.

Adding printers

Beside manually adding printers with client tools, it is possible to permanently add printers to your system configuration (but be aware of this bug that sometimes expect the printer to be plugged in your system). The following example configures a network printer called Dell_1250c to your local system, reachable via IPP at http://192.168.178.2:631/printers/Dell_1250c

hardware.printers = {
  ensurePrinters = [
    {
      name = "Dell_1250c";
      location = "Home";
      deviceUri = "http://192.168.178.2:631/printers/Dell_1250c";
      model = "drv:///sample.drv/generic.ppd";
      ppdOptions = {
        PageSize = "A4";
      };
    }
  ];
  ensureDefaultPrinter = "Dell_1250c";
};

To add a local printer, connected via USB, change the deviceUri to a USB address and optionally define which driver to use by adding the model option.

hardware.printers = {
  ensurePrinters = [
    {
      name = "Dell_1250c";
      location = "Home";
      deviceUri = "usb://Dell/1250c%20Color%20Printer?serial=YNP023240";
      model = "Dell-1250c.ppd.gz";
      ppdOptions = {
        PageSize = "A4";
      };
    }
  ];
};

Some local or network printers might need additional drivers. You can add them using the drivers option

services.printing.drivers = [ YOUR_DRIVER ];

where YOUR_DRIVER is the driver package appropriate for your printer. Commonly used driver packages include:

  • pkgs.gutenprint — Drivers for many different printers from many different vendors.
  • pkgs.gutenprintBin — Additional, binary-only drivers for some printers.
  • pkgs.hplip — Drivers for HP printers.
  • pkgs.hplipWithPlugin — Drivers for HP printers, with the proprietary plugin. Use NIXPKGS_ALLOW_UNFREE=1 nix-shell -p hplipWithPlugin --run 'sudo -E hp-setup' to add the printer, regular CUPS UI doesn't seem to work.
  • pkgs.postscript-lexmark — Postscript drivers for Lexmark
  • pkgs.samsung-unified-linux-driver — Proprietary Samsung Drivers
  • pkgs.splix — Drivers for printers supporting SPL (Samsung Printer Language).
  • pkgs.brlaser — Drivers for some Brother printers
  • pkgs.brgenml1lpr and pkgs.brgenml1cupswrapper — Generic drivers for more Brother printers [1]
  • pkgs.cnijfilter2 — Drivers for some Canon Pixma devices (Proprietary driver)

Search for other printer drivers in the NixOS package directory: the official list of packages is here. Add the driver to services.printing.drivers, not environment.systemPackages.


To get the specific string for model, run lpinfo -m which will produce output similar to

...
samsung/SCX-3200.ppd Samsung SCX-3200 Series
samsung/SCX-3400.ppd Samsung SCX-3400 Series
samsung/SCX-4100.ppd Samsung SCX-4100 Series
samsung/SCX-4200.ppd Samsung SCX-4200 Series
samsung/SCX-4300.ppd Samsung SCX-4300 Series
samsung/SCX-4500.ppd Samsung SCX-4500 Series
samsung/SCX-4500W.ppd Samsung SCX-4500W Series
samsung/SCX-4600.ppd Samsung SCX-4600 Series
samsung/SCX-4623.ppd Samsung SCX-4623 Series
...

The model string is the first column. For example, for the Samsung SCX-4300 series, set model = "samsung/SCX-4300.ppd";

Printer sharing

Enable network sharing of the default local printer, also known as "AirPrinting". Note that listenAddresses = [ "*:631" ];, allowFrom = [ "all" ]; and openFirewall = true; will enable anonymous access to your printer on all interfaces, you might want to restrict this.

services.avahi = {
  enable = true;
  nssmdns = true;
  openFirewall = true;
  publish = {
    enable = true;
    userServices = true;
  };
};
services.printing = {
  listenAddresses = [ "*:631" ];
  allowFrom = [ "all" ];
  browsing = true;
  defaultShared = true;
  openFirewall = true;
};

Once printer sharing is enabled, it could be additionally advertised in the home network via the Samba protocol, see.

Usage

After enabling the printing service you'll be able to configure and add network printers via http://localhost:631. You may need to authenticate with your local user when you add the printer.

Depending on your desktop environment, there are several graphical tools available which will connect to this backend service and allow you a more convenient printer management, for example system-config-printer.

Command line

List printers

# lpstat -p

Print test page for printer called HP-LaserJet-1020

# lp -o job-sheets=standard,none -d HP-LaserJet-1020 /dev/null

List jobs

# lpstat

Cancel job

# cancel 1

Tips and tricks

Manually supplying printer driver

Provide the PPD imperatively

If no driver is found for your printer, even when services.printing.drivers is correctly populated (see above), you can try to give cups a PPD file.

  • Download the required PPD file, for example from openprinting.org
  • Open the PPD as a text file, and check that it does not mention FHS paths like /usr/bin. If it does, this method is unlikely to work, as the PPD file depends on executables not present on your system. You can certainly install the binaries yourself and point to the new binary, but it is certainly easier to patch the executables in a derivation (see below) to avoid garbage collection of your binaries.
  • add the printer with system-config-printer (for example) and at the 'choose driver' screen choose 'provide PPD file'
Provide the PPD declaratively

You can also declaratively add the PPD as a new driver by creating a simple derivation. You just need to create a derivation that puts the PPD file in $out/share/cups/model/yourfile.ppd (you can also put it in a subfolder like $out/share/cups/model/HP/yourfile.ppd to limit conflicts between ppd having the same name). Note that the name of the file does not change the way cups will list it as the model/manufacturer is written inside the (text) ppd.

As in the imperative method, first check that your file does not contain any reference to binaries outside the store like /bin/ or /usr/. If it does not contain any reference then you should be able to simply do this:

{
  ...
  services.printing.enable = true;
  services.printing.drivers = [
    (writeTextDir "share/cups/model/yourppd.ppd" (builtins.readFile ./yourppd.ppd))
  ];
  ...
}

If your ppd contains links to external binaries, you can instead patch the file using for instance substituteInPlace. For that, create a file, say, myPrinter.nix containing something like:

{ stdenv }:
stdenv.mkDerivation rec {
  name = "myprinter-${version}";
  version = "1.0";

  src = ./.;

  installPhase = ''
    mkdir -p $out/share/cups/model/
    cp myprinter.ppd $out/share/cups/model/
    # If you need to patch the path to files outside the nix store, you can do it this way
    # (if the ppd also comes with executables you may need to also patch the executables)
    substituteInPlace $out/share/cups/model/myprinter.ppd \
      --replace "/usr/yourProgram/" "${yourProgram}/bin/yourProgram"
  '';
}

Of course update the name of the files and adapt the substituteInPlace command to your needs. Then add your driver as:

{
  ...
  services.printing.enable = true;
  services.printing.drivers = [
    (pkgs.callPackage ./myPrinter.nix {})
  ];
  ...
}

Your PPD file should now appear next to the other PPD files installed on your system when you add a new printer.

For debugging purpose, it may be interesting to note that the data folder used by cups (containing the drivers and more) can be obtained by looking in the environment $CUPS_DATADIR (the contents of $out/share/cups/ contained in your drivers are linked in this folder).

Troubleshooting

Upgrade required

Described in: Github issue 23993
Problem
Using the cups web interface, the page tells you "Upgrade Required" and then redirects you to a page that fails to load.

Cause
When you are using http and cups wants authentication it will redirect you to a https version by default.
In order to use https it needs ssl keys. However it is possible that cups fails to generate these keys, and then the page will fail to load.

Solution
Either we can help cups to get ssl keys, or we can tell it to not use https at all.
Generating ssl keys:
First make sure the directory /etc/cups/ssl exists:
sudo mkdir -p /etc/cups/ssl
Try restarting cups and using the web interface again. This might be enough to get it working.
If this didn't help, then check if cups has generated ssl keys in /etc/cups/ssl
Disabling ssl:
Edit your /etc/nixos/configuration.nix and add the following lines:

services.printing.extraConf = ''
    DefaultEncryption Never
  '';

Unable to launch Ghostscript: gs: No such file or directory

Described in: Github issue 20806 and issues 22062
Problem
When printing, cups will report an error: Unable to launch Ghostscript: gs: No such file or directory

Cause
Some drivers use the ghostscript binary.
Cups will look for the binary path in it's config file: cupsd.conf
This file is normally a link. But it can be overwritten, and consequentially become outdated.

Solution
You could try to manually fix the path variable in /var/lib/cups/cupsd.conf
Alternatively you could try to delete the file and run sudo nixos-rebuild switch

File is missing (Gnome 3)

When you add an printer in Gnome (using gnome-control-center printers) you create a profile for your printer.

Problem
But, later you may experience an error like "/nix/store/.../lib/cups/filter/pstospl not available: No such file or directory".

Cause
When you create a printer profile you get a freeze version of cups filter and when cups is updated, because you have upgraded your system, and garbage collected this version is gone.

Solution
Go into the gnome-control-center printers settings, remove the printer and recreate it.

Debugging a broken printer driver

Add to /etc/nixos/configuration.nix

services.printing.logLevel = "debug";

Rebuild

sudo nixos-rebuild switch

Watch the cups logs

$ journalctl --follow --unit=cups

or

$ journalctl --follow --unit=cups | grep -C10 --color=always -i -e 'No such file or directory' -e 'error:'

Start a print job

Now watch the cups logs for errors like No such file or directory