Можно использовать систему инициализации Systemd. Напишите unit-файл такого вида:
[Unit]
Description=My Script Service
After=multi-user.target
[Service]
User=user  # Имя пользователя, от имени которого будет запускаться команда, указанная в ExecStart
WorkingDirectory=/home/user/program  # Директория, в которую будет осуществлён переход перед запуском
ExecStart=/home/user/program/venv/bin/python /home/user/program/webui.py
Restart=always  # Всегда перезапускать скрипт при его падениях
[Install]
WantedBy=multi-user.target
и сохраните его в директории 
/etc/systemd/system с расширением 
.service, например, 
/etc/systemd/system/my_program.service.
Здесь не используется скрипт 
activate для активации виртуального окружения, но вместо этого указывается полный путь к интерпретатору Python внутри этого виртуального окружения.
Также важно указывать абсолютные пути к файлам и директориям, даже несмотря на то, что задана рабочая директория 
WorkingDirectory.
Если ваш скрипт опирается на сетевые соединение, в секции 
Unit в качестве 
After задайте 
network-online.target вместо 
multi-user.target:
After=network-online.target
После этого перезагрузите конфигурацию Systemd:
sudo systemctl daemon-reload
И запустите сервис с добавлением в автозагрузку:
sudo systemctl enable --now my_program.service