Gunicorn as a systemd service

Hi all,

I would like to set up a python flask based website on a NixOS server.

As I am pretty new in both in NixOS and in setting up a server, I got stuck with gunicorn.

I am following this digital ocean tutorial:

I tried to set up a systemd service for my project in the configuration.nix.
This is the part related to gunicorn:

Gunicorn versike_project

systemd.services.versike_project = {
enable = true;
description = “Gunicorn instance to serve versike_project”;
after = [“network.target”];
serviceConfig = {
User = “picibucor”;
# Group = “???”;
ExecStart = “/home/picibucor/versike_project/versike_projectenv/bin/gunicorn --workers 3 --bind unix:versike_project.sock -m 007 wsgi:app”;
};
environment = {
PATH = lib.mkForce “/home/picibucor/versike_project/versike_projectenv/bin”;
};
wantedBy = [“multi-user.target”];
};

After the commands:

sudo nixos-rebuild switch
sudo systemctl status versike_project

I received the following status report:

versike_project.service - Gunicorn instance to serve versike_project
Loaded: loaded (/etc/systemd/system/versike_project.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Tue 2024-09-17 11:09:29 CEST; 4min 11s ago
Duration: 5.236s
Process: 13444 ExecStart=/home/picibucor/versike_project/versike_projectenv/bin/gunicorn --workers 3 --bind unix:versike_project.sock -m 007 wsgi:app (code=exited,>
Main PID: 13444 (code=exited, status=1/FAILURE)
IP: 0B in, 0B out
CPU: 229ms

Sep 17 11:09:24 nixos systemd[1]: Started Gunicorn instance to serve versike_project.
Sep 17 11:09:24 nixos gunicorn[13444]: [2024-09-17 11:09:24 +0200] [13444] [INFO] Starting gunicorn 23.0.0
Sep 17 11:09:24 nixos gunicorn[13444]: [2024-09-17 11:09:24 +0200] [13444] [ERROR] connection to versike_project.sock failed: [Errno 13] Permission denied
Sep 17 11:09:25 nixos gunicorn[13444]: [2024-09-17 11:09:25 +0200] [13444] [ERROR] connection to versike_project.sock failed: [Errno 13] Permission denied
Sep 17 11:09:26 nixos gunicorn[13444]: [2024-09-17 11:09:26 +0200] [13444] [ERROR] connection to versike_project.sock failed: [Errno 13] Permission denied
Sep 17 11:09:27 nixos gunicorn[13444]: [2024-09-17 11:09:27 +0200] [13444] [ERROR] connection to versike_project.sock failed: [Errno 13] Permission denied
Sep 17 11:09:28 nixos gunicorn[13444]: [2024-09-17 11:09:28 +0200] [13444] [ERROR] connection to versike_project.sock failed: [Errno 13] Permission denied
Sep 17 11:09:29 nixos gunicorn[13444]: [2024-09-17 11:09:29 +0200] [13444] [ERROR] Can’t connect to versike_project.sock
Sep 17 11:09:29 nixos systemd[1]: versike_project.service: Main process exited, code=exited, status=1/FAILURE
Sep 17 11:09:29 nixos systemd[1]: versike_project.service: Failed with result ‘exit-code’.

Do I follow the right tutorial?
Could you help me to resolve the permission denied issue?
Is the “versike_project.sock” file automatically generated or should I create it?

Thanks in advance

1 Like

You specify just versike_project.sock, which is a relative path. By default, systemd units run in the / directory, which means that gunicorn is trying to create /versike_project.sock, which naturally an unprivileged user does not have permissions to do.

Either set WorkingDirectory for the unit to something like /home/picibucor/versike_project, or specify the socket as an absolute path like /home/picibucor/versike_project/versike_project.sock.

@justinas: Thank you for your response.

I tried out the suggestions with the following results:

1.)
Adding WorkingDirectory = /home/picibucor/versike_project does not resolve the Permission denied problem. I tried sudo chmod 755 /home/picibucor, with and without -R flag as well. Nothing has changed.

2.)
So instead of 1.) I changed the path of the *.sock file in ExecStart.

sudo systemctl status versike_project gave me a the following error:

× versike_project.service - Gunicorn instance to serve versike_project
     Loaded: loaded (/etc/systemd/system/versike_project.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Tue 2024-09-17 23:07:25 CEST; 22min ago
   Duration: 463ms
    Process: 2797 ExecStart=/home/picibucor/versike_project/versike_projectenv/bin/gunicorn --workers 3 --bind unix:/home/picibucor/versike_project/versike_pr>
   Main PID: 2797 (code=exited, status=3)
         IP: 0B in, 0B out
        CPU: 359ms

Sep 17 23:07:25 nixos gunicorn[2886]:   File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
Sep 17 23:07:25 nixos gunicorn[2886]:   File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
Sep 17 23:07:25 nixos gunicorn[2886]:   File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
Sep 17 23:07:25 nixos gunicorn[2886]: ModuleNotFoundError: No module named 'wsgi'
Sep 17 23:07:25 nixos gunicorn[2886]: [2024-09-17 23:07:25 +0200] [2886] [INFO] Worker exiting (pid: 2886)
Sep 17 23:07:25 nixos gunicorn[2797]: [2024-09-17 23:07:25 +0200] [2797] [ERROR] Worker (pid:2886) exited with code 3
Sep 17 23:07:25 nixos gunicorn[2797]: [2024-09-17 23:07:25 +0200] [2797] [ERROR] Shutting down: Master
Sep 17 23:07:25 nixos gunicorn[2797]: [2024-09-17 23:07:25 +0200] [2797] [ERROR] Reason: Worker failed to boot.
Sep 17 23:07:25 nixos systemd[1]: versike_project.service: Main process exited, code=exited, status=3/NOTIMPLEMENTED
Sep 17 23:07:25 nixos systemd[1]: versike_project.service: Failed with result 'exit-code'.

I also tried to add a wsgi diectory with an empty __init__.py file to resolve the No module named 'wsgi' issue, but did not help either.

Neither in case 1.) nor in case 2.) was the file versike_project.sock generated.

Do you have any further suggestions?

You start gunicorn with an argument wsgi:app, meaning it expects a Python module called wsgi that would have a WSGI application called app. Please follow Creating the WSGI Entry Point in the tutorial you linked. Delete the empty wsgi folder, if any.

You probably need to keep the WorkingDirectory set to your project’s directory, as gunicorn will look up that wsgi module relative to the working directory, if I remember correctly.