reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
20.52k stars 1.18k forks source link

Running Reflex via systemd with --env prod param only runs the frontend and not the backend. #2282

Open rushout09 opened 11 months ago

rushout09 commented 11 months ago

Describe the bug in systemd: env DEV work env PROD fails

running manually : both works

To Reproduce Steps to reproduce the behavior:

Create a systemd file

[Unit]
Description=Databees Website App
After=network.target

[Service]
ExecStart=/home/ubuntu/databees_website/venv/bin/reflex run --env prod
WorkingDirectory=/home/ubuntu/databees_website
User=ubuntu
Group=ubuntu
Restart=always

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload sudo systemctl start test.service

Expected behavior ubuntu@ip-172-31-41-251:~$ sudo lsof -i -P -n | grep LISTE systemd-r 325 systemd-resolve 14u IPv4 15785 0t0 TCP 127.0.0.53:53 (LISTEN) sshd 565 root 3u IPv4 17438 0t0 TCP :22 (LISTEN) sshd 565 root 4u IPv6 17449 0t0 TCP :22 (LISTEN) reflex 6894 ubuntu 13u IPv4 68388 0t0 TCP :8000 (LISTEN) python3 6927 ubuntu 13u IPv4 68388 0t0 TCP :8000 (LISTEN) next-serv 6957 ubuntu 20u IPv6 69656 0t0 TCP *:3000 (LISTEN)

Screenshots If applicable, add screenshots to help explain your problem.

Specifics (please complete the following information):

Additional context Add any other context about the problem here. https://discord.com/channels/1029853095527727165/1184109557946003576

jackie-pc commented 11 months ago

Thanks for the report.

When backend prod runs, it calls out to the program gunicorn. However gunicorn program is only available once the virtual env is activated by source venv/bin/activate. Simply calling venv/bin/reflex is insufficient as that takes care only of libraries within the Python process.

This exposes a bug in the way to propagate errors though - it should have been straightforward from logs ("gunicorn not found"). #2296 above will address this.

rushout09 commented 11 months ago

@jackie-pc is there a way to properly initialize venv using systemd?

jackie-pc commented 11 months ago

You would initialize like how you normally would. source ...../activate. E.g.

source ...../activate && reflex run. You can try that in ExecStart: (not sure about exact Systemd support for &&). Putting it in a custom run_from_systemd.sh script that contains the same shell snippet would definitely work. You would call run_from_systemd.sh from ExecStart

rushout09 commented 11 months ago

got it. thanks will try this

martincpt commented 1 month ago

I spent a day trying all possible solutions, and I can confirm that the only way to make this work is to create a custom Bash script that activates the environment first. Systemd does not support &&, cannot execute source, and cannot activate the virtual environment via poetry shell in ExecPreStart.

As mentioned, you must create a Bash script like this:

#!/bin/bash

# Navigate to the script's directory to ensure relative paths work correctly
cd "$(dirname "$0")"

# Activate the virtual environment using a relative path
source .venv/bin/activate

# Run the Reflex command with the 'prod' environment using a relative path
.venv/bin/reflex run --env prod

And then the systemd file like this:

[Unit]
Description=reflex daemon
After=network.target

[Service]
User=root
Group=www-data
WorkingDirectory=/your/app/path
ExecStart=/your/app/path/run_reflex.sh
Restart=always

[Install]
WantedBy=multi-user.target

I'm not 100% sure, but another solution could be to include the absolute path to the Gunicorn or Uvicorn binary when executing them via Reflex. However, this would require updating the codebase.

Cheers.