Change:
I use enabled. I also have a web server service that specifies: Because my web server is a bit long to start, the timeout and its systemd unit fails. To Reproduce Use the following example module: Expected behavior The acme systemd units created by  should wait that nginx is started before starting. Metadata Maintainer information:
Should adding to what is already to  fix the issue?
Making a note that has the same code and presumably the same issue so any fix on should likely be ported to .
Thank you for the issue and reproducer. I'll have a closer look at this today
what exactly do you mean by "timeout" here by the way. could you provide some journal logs of this failure? I can try reproduce when I'm home, but maybe the logs are enough to understand what is going wrong
I mean "Timeout during connect (likely firewall problem)" in the logs below. Note that the hostname, email and domain have been redacted. Also notice the long time between and . nginx was not started when the Let's Encrypt tried to retrieve the challenge:
I'm scared that won't work. The lack of here is very deliberate pulls in (Through and ) to create fake certs, as nginx crashes hard when certificate paths aren't present. We want to start up before the acme challenge is initiated, as nginx is responsible for serving the director to complete it. If starts before nginx, it will always fail. It's all a bit mind-boggling and the dependencies are a bit complicated. I wish it was a bit more simpler too. However; isn't what we want here instead? We want to guarentee that is running before the certificate request is fired off. So adding a to might work? I'll see if that fixes it..
Absolutely, that is what I meant but I wrote it wrongly.
Should we go for the solution proposed?
Yep. I have a PR in the works on my machine. I'll try to get it out this week

Discussion:
wantedBy = [ "multi-user.target" ]; wants = concatLists (map (hostOpts: [ "acme-${hostOpts.hostName}.service" "acme-selfsigned-${hostOpts.hostName}.service" ]) vhostsACME); after = [ "network.target" "fs.target" ] ++ map (hostOpts: "acme-selfsigned-${hostOpts.hostName}.service") vhostsACME; <ins> before = map (hostOpts: "acme-${hostOpts.hostName}.service") vhostsACME; </ins> path = [ pkg pkgs.coreutils pkgs.gnugrep ];

wantedBy = [ "multi-user.target" ]; wants = concatLists (map (vhostConfig: ["acme-${vhostConfig.serverName}.service" "acme-selfsigned-${vhostConfig.serverName}.service"]) acmeEnabledVhosts); after = [ "network.target" ] ++ map (vhostConfig: "acme-selfsigned-${vhostConfig.serverName}.service") acmeEnabledVhosts; <ins> # Nginx needs to be started in order to be able to request certificates # (it's hosting the acme challenge after all) # This fixes https://github.com/NixOS/nixpkgs/issues/81842 before = map (vhostConfig: "acme-${vhostConfig.serverName}.service") acmeEnabledVhosts; </ins> stopIfChanged = false; preStart = '' ${cfg.preStart}

security.acme.certs."standalone.test" = { webroot = "/var/lib/acme/acme-challenges"; }; <del> systemd.targets."acme-finished-standalone.test" = {}; systemd.services."acme-standalone.test" = { wants = [ "acme-finished-standalone.test.target" ]; before = [ "acme-finished-standalone.test.target" ]; </del> <ins> systemd.targets."acme-finished-standalone.test" = { after = [ "acme-standalone.test.service" ]; wantedBy = [ "acme-standalone.test.service" ]; </ins> }; services.nginx.enable = true; services.nginx.virtualHosts."standalone.test" = {

# A target remains active. Use this to probe the fact that # a service fired eventhough it is not RemainAfterExit <del> systemd.targets."acme-finished-a.example.test" = {}; systemd.services."acme-a.example.test" = { wants = [ "acme-finished-a.example.test.target" ]; before = [ "acme-finished-a.example.test.target" ]; after = [ "nginx.service" ]; </del> <ins> systemd.targets."acme-finished-a.example.test" = { after = [ "acme-a.example.test.service" ]; wantedBy = [ "acme-a.example.test.service" ]; </ins> }; services.nginx.enable = true;

security.acme.server = "https://acme.test/dir"; specialisation.second-cert.configuration = {pkgs, ...}: { <del> systemd.targets."acme-finished-b.example.test" = {}; systemd.services."acme-b.example.test" = { wants = [ "acme-finished-b.example.test.target" ]; before = [ "acme-finished-b.example.test.target" ]; after = [ "nginx.service" ]; </del> <ins> systemd.targets."acme-finished-b.example.test" = { after = [ "acme-b.example.test.service" ]; wantedBy = [ "acme-b.example.test.service" ]; </ins> }; services.nginx.virtualHosts."b.example.test" = { enableACME = true;

''; }; }; specialisation.dns-01.configuration = {pkgs, config, nodes, lib, ...}: { security.acme.certs."example.test" = { domain = "*.example.test";

user = config.services.nginx.user; group = config.services.nginx.group; }; <del> systemd.targets."acme-finished-example.test" = {}; </del> <ins> systemd.targets."acme-finished-example.test" = { after = [ "acme-example.test.service" ]; wantedBy = [ "acme-example.test.service" ]; }; </ins> systemd.services."acme-example.test" = { <del> wants = [ "acme-finished-example.test.target" ]; before = [ "acme-finished-example.test.target" "nginx.service" ]; </del> <ins> before = [ "nginx.service" ]; </ins> wantedBy = [ "nginx.service" ]; }; services.nginx.virtualHosts."c.example.test" = {

''; }; }; <ins> # When nginx depends on a service that is slow to start up, requesting used to fail # certificates fail.  Reproducer for https://github.com/NixOS/nixpkgs/issues/81842 specialisation.slow-startup.configuration = { pkgs, config, nodes, lib, ...}: { systemd.services.my-slow-service = { wantedBy = [ "multi-user.target" "nginx.service" ]; before = [ "nginx.service" ]; preStart = "sleep 5"; script = "${pkgs.python3}/bin/python -m http.server"; }; systemd.targets."acme-finished-d.example.com" = { after = [ "acme-d.example.com.service" ]; wantedBy = [ "acme-d.example.com.service" ]; }; services.nginx.virtualHosts."d.example.com" = { forceSSL = true; enableACME = true; locations."/".proxyPass = "http://localhost:8000"; }; }; </ins> }; client = {nodes, lib, ...}: {

client.succeed( "curl --cacert /tmp/ca.crt https://c.example.test/ | grep -qF 'hello world'" ) <ins> with subtest("Can request certificate of nginx when startup is delayed"): webserver.succeed( "${switchToNewServer}" ) webserver.succeed( "/run/current-system/specialisation/slow-startup/bin/switch-to-configuration test" ) webserver.wait_for_unit("acme-finished-d.example.com.target") client.succeed("curl --cacert /tmp/ca.crt https://d.example.com/") </ins> ''; })