0

I have a flask app that has the following app.py file that includes a flask_apscheduler:

from flask_apscheduler import APScheduler

app = Flask(__name__)
scheduler = APScheduler()
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:postgres@localhost/mydb'
db = SQLAlchemy(app)

#my sqlAlchemy models:
class RiskCountry(db.Model):
   id = ...

@app.route('/')
def dataToDb():
   #scrape data from website and update database
   ...

if __name__ == '__main__':
    scheduler.add_job(id = 'test', func = dataToDb, trigger = 'interval', minutes = 60)
    scheduler.start()
    app.run()

Now I would like to run this script as a service using systemd. I created the following myservice.service file in /etc/systemd/system:

[Unit]
Description=scraping data and push to DB
After=network.target network-online.target
Requires=network-online.target

[Service]
ExecStart="/home/geolic/my-app/env/bin/python /home/geolic/my-app/app.py"
Restart=always
WorkingDirectory=/home/geolic/my-app
User=root
Group=root

[Install]
WantedBy=multi-user.target

Now I went to my console and did

$ systemctl enable myservice
$ systemctl daemon-reload
$ systemctl start myservice
$ systemctl status myservice -l

However, my service fail to run with error message:

Loaded: loaded (/etc/systemd/system/myservice.service; enabled; vendor preset: disabled)
Active: failed (Result: start-limit) since Wed 2020-08-19 07:50:57 CEST; 6s agoProcess: 21863
ExecStart=/home/geolic/my-app/env/bin/python /home/geolic/my-app/app.py (code=exited, status=203/EXEC)
Main PID: 21863 (code=exited, status=203/EXEC)

The log tells me that systemd cannot find a file that I use in my ExecStart. However, when running the statement in my console it works as it should...

What am I doing wrong here?

1 Answer 1

1

That's because you tried to pass the entire command line as a single very long path, while it's supposed to consist of two separate paths.

The value specified in systemd's ExecStart is not given to a shell to be interpreted as a command. Rather, the option directly takes a list of space-separated words (the executable and its arguments). So the correct settings would be:

ExecStart="/home/geolic/my-app/env/bin/python" "/home/geolic/my-app/app.py"

ExecStart=/home/geolic/my-app/env/bin/python /home/geolic/my-app/app.py

Compare this to what happens when you quote the entire command line in an actual shell:

$ head -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash

$ "head -1 /etc/passwd"
bash: head -1 /etc/passwd: No such file or directory
1
  • Thank you so much! I was sure I tried exactly this. So I was sitting on this for over 2 days for something so trivial. But now it works!
    – JoeBe
    Commented Aug 20, 2020 at 7:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .