Search code examples
pythonfastapigunicornsystemduvicorn

Way to pass arguments to FastAPI app via command line


I'm using python 3.8.0 for my FastAPI app. It uses the .env file located on the root of a project directory. I am using the dotenv package, and the location of the .env file is hardcoded within the app. Here is my unit file

[Unit]
Description=Gunicorn instance for my_app
After=network.target

[Service]
User=nginx
Group=nginx
WorkingDirectory=/usr/share/nginx/html/my_app/
Environment="PATH=/usr/share/nginx/html/my_app/venv/bin"
ExecStart=/usr/share/nginx/html/my_app/venv/bin/gunicorn --bind unix:/usr/share/nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app

[Install]
WantedBy=multi-user.target

The challenge is to run two versions (production and test) of the same app using two different .env on two different ports. I'll have to create a second unit file. But how can I pass the name of two diffeent env file names to the app for further usage. These files contain database connections, etc. I imagine it roughly like this 1st unit file

ExecStart=/usr/share/nginx/html/my_app/venv/bin/gunicorn 
--bind unix:/usr/share/nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app --env_file_name=".env.prod"

2nd unit file

ExecStart=/usr/share/nginx/html/my_app/venv/bin/gunicorn 
--bind unix:/usr/share/nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app --env_file_name=".env.dev"

Solution

  • You can set the path from which systemd will read the environment for your process exactly in unit file configuration. The setting is called EnvironmnetFile=. Just set the option to the path for .env.prod in one unit file and for the path to .env.test for another.