The durable way to run a Python script in the background on Ubuntu is to create a native systemd service. A unit file gives systemd an absolute Python command, a working directory, a least-privileged user, restart behavior, and boot activation. After creating it, reload systemd, run systemctl enable --now, and use systemctl status and journalctl to operate and troubleshoot the process.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
Why systemd is the right tool
A command started from an SSH shell belongs to that session unless you deliberately detach it. Closing the terminal, losing the connection, or logging out can therefore stop the process. Commands such as & and nohup can keep a process around temporarily, but they do not provide a complete service lifecycle: there is no native boot activation, consistent privilege boundary, dependency ordering, crash policy, or central log view.
As an Amazon Associate I earn from qualifying purchases.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Ubuntu’s native service supervisor is systemd. Its unit files describe background tasks, startup behavior, and interactions with the operating system. For one long-running Python process on one Ubuntu host, systemd normally offers the strongest integration with the operating system:
- Boot integration: the service can start when the system reaches the normal multi-user target.
- Supervision: systemd knows whether the Python process is running and can restart it after an unexpected failure.
- Privilege isolation: the process can run as a dedicated account rather than as root.
- Logging: standard output, standard error, and startup failures are available through the journal.
- Ordering: the unit can be ordered after
network-online.targetwhen the application needs network connectivity.
This guide assumes a script that is intended to stay alive, such as a worker, polling loop, API process, or queue consumer. A finite task that should run at a particular time is usually a better fit for a scheduler such as cron.
#1 Best Overall
- [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
- [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
- [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
- [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
- [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.
Prepare the application and service account
Use a stable directory and a dedicated account before writing the unit. The example below uses /opt/myapp, the account myapp, and a virtual environment at /opt/myapp/.venv. Substitute your own names consistently; the service will not work if even one path points somewhere else.
Create a least-privileged account
Create the account with no interactive shell and give it ownership of the application directory. The exact account-management command can vary by Ubuntu release, but this common form creates a system account and group:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorssudo adduser --system --group --home /opt/myapp myapp
sudo install -d -o myapp -g myapp /opt/myapp
If the account already exists, keep the second command and check ownership with ls -ld /opt/myapp. The service user must be able to enter the working directory, read the script and virtual environment, read configuration files, and write every directory used for data, sockets, caches, or application logs.
Copy the script and install dependencies
Place the application under the directory that will be named by WorkingDirectory. For example:
sudo cp app.py /opt/myapp/
# install dependencies into /opt/myapp/.venv using your normal deployment process
sudo chown -R myapp:myapp /opt/myapp
Before involving systemd, confirm that the interpreter you plan to call actually exists:
ls -l /opt/myapp/.venv/bin/python
Calling the virtual environment’s interpreter by its absolute path is more reliable than trying to activate the environment from a shell. A service does not start in your interactive shell, so shell aliases, an interactive $PATH, and source .venv/bin/activate should not be prerequisites.
Write the systemd unit file
Create /etc/systemd/system/myscript.service as root:
Rank #2
- 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
- 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
- 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
- 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
- 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.
sudo nano /etc/systemd/system/myscript.service
Paste this unit and adjust the description, account, directory, interpreter, and script name:
[Unit]
Description=My Python background service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/.venv/bin/python /opt/myapp/app.py
Restart=on-failure
RestartSec=5
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
What each section does
[Unit]:Descriptionidentifies the service in status output.After=network-online.targetorders startup after that target, andWants=network-online.targetasks systemd to bring the target in as part of the transaction.Type=simple: the Python process remains in the foreground, allowing systemd to supervise it directly. Do not add a shell background operator.User=myapp: runs the process without root privileges. This limits the damage a compromised or faulty application could cause.WorkingDirectory=/opt/myapp: establishes the current directory expected by code that opens relative paths. Absolute paths in the Python application are still preferable for important files.ExecStart=...: directly invokes the intended Python executable and script. Every path should be absolute. systemd command lines do not provide shell redirection, pipelines, or an&background operator.Restart=on-failure: asks systemd to restart the service after an unexpected non-success exit or signal. This is the recommended policy for a long-running service, but it does not replace fixing an exception.RestartSec=5: waits five seconds before attempting a restart, avoiding an immediate tight loop when the same startup error repeats.Environment=PYTHONUNBUFFERED=1: makes Python write output without normal buffering, so diagnostic lines appear promptly in the journal.[Install]andWantedBy=multi-user.target: define the boot target used when you enable the service.
Do not daemonize the Python process yourself. A program that forks into the background can make a Type=simple unit appear to have exited, preventing systemd from supervising the real worker correctly.
Load, start, and enable the service
After saving the unit file, tell systemd to reread unit definitions. Then enable the service for future boots and start it immediately:
Recommended Free Tools
sudo systemctl daemon-reload
sudo systemctl enable --now myscript.service
enable --now performs two separate jobs in one command: it creates the boot-time activation relationship and starts the service now. If you prefer to separate those actions while testing, use sudo systemctl enable myscript.service followed by sudo systemctl start myscript.service.
Check the current state
sudo systemctl status myscript.service
A healthy long-running service normally reports active (running). The status view also shows the main process ID, the last few journal lines, and whether systemd has recently restarted the unit.
Follow live output
sudo journalctl -u myscript.service -f
Press Ctrl+C to leave the live view; this does not stop the service. To inspect messages from the current boot without following new entries, run:
sudo journalctl -u myscript.service -b --no-pager
Python tracebacks, import errors, permission failures, and messages printed to standard output or standard error generally appear here. You do not need to create a separate log file just to see startup diagnostics.
Rank #3
- [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
- [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
- [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
- [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
- [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by
Operate the service safely
Stop, start, and restart
sudo systemctl stop myscript.service
sudo systemctl start myscript.service
sudo systemctl restart myscript.service
Stopping a service prevents its process from running until you start it again. Restarting is useful after changing application files or environment values.
Change the unit definition
Whenever you edit /etc/systemd/system/myscript.service, run both commands below. The first loads the new definition; the second applies it to the running process:
sudo systemctl daemon-reload
sudo systemctl restart myscript.service
Inspect exactly what systemd has loaded with:
systemctl cat myscript.service
This is especially useful when a similarly named unit exists elsewhere or an edit was saved to the wrong directory.
Disable boot activation
sudo systemctl disable --now myscript.service
This stops the current process and removes its automatic boot activation. It does not delete the unit file.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Make the script service-friendly
A script that works from an SSH prompt often depends on details that are absent under systemd. Review these assumptions before blaming the supervisor:
- Environment variables: interactive shell profiles are not automatically loaded. Put required values in the unit with explicit
Environment=entries or use a deliberately managed environment file, and avoid putting secrets directly in a world-readable script. - Current directory: relative paths resolve from
WorkingDirectory, not from the directory where you happened to run the command over SSH. - Display access: GUI programs may require a display server and related variables that do not exist in a headless service session.
- Prompts: a service cannot answer an interactive password or confirmation prompt. Supply configuration non-interactively or fail with a clear message.
- Output: write useful startup and failure information to standard output or standard error so it is visible through
journalctl.PYTHONUNBUFFERED=1helps those lines appear immediately. - Permissions: test access as
myapp, not as your login account. The account needs execute permission on every parent directory in a path, not merely read permission on the final file.
Network ordering also needs careful interpretation. After=network-online.target controls ordering relative to that target; it does not prove that a particular database, API, DNS service, or remote host is ready. Long-running code should catch connection errors and retry with a sensible delay.
Troubleshoot the common failures
203/EXEC or “command not found”
This means systemd could not execute the first program in ExecStart. Check the interpreter and every path:
Rank #4
- Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
- Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
- All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
- Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
- Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.
ls -l /opt/myapp/.venv/bin/python
systemctl cat myscript.service
Use the actual absolute interpreter path, not python, python3, a shell alias, or a path that only exists in your login environment. If the interpreter is a symlink, verify that its target also exists and is executable.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Permission denied
Confirm that User=myapp can read the script, traverse /opt/myapp, load configuration, and write required data or log directories. A quick diagnostic is to run the exact command as that account:
sudo -u myapp /opt/myapp/.venv/bin/python /opt/myapp/app.py
If this fails with a permission error, fix ownership or narrowly grant the required access. Do not solve an application permission problem by changing the service to run as root unless the application genuinely requires it.
The script works over SSH but fails as a service
Compare the two execution contexts. Remove dependencies on $PATH, aliases, activated virtual environments, the current directory, display variables, and interactive prompts. Replace them with absolute paths, WorkingDirectory, explicit environment settings, and non-interactive configuration.
The service starts and immediately exits
Run the exact ExecStart command as myapp, then inspect the current-boot journal:
Free tools Windows power users keep installed
One-click scans. No signup required.
sudo -u myapp /opt/myapp/.venv/bin/python /opt/myapp/app.py
sudo journalctl -u myscript.service -b --no-pager
The Python traceback usually identifies an import error, missing configuration, invalid working-directory assumption, or application exception. Restart=on-failure may make the unit appear to be repeatedly starting while the underlying exception remains unchanged.
The service is in a constant restart loop
First fix the exception or configuration error. Systemd rate-limits repeated starts using StartLimitIntervalSec and StartLimitBurst. Once the cause is corrected, clear the failed-start counter and start again:
Best Value
sudo systemctl reset-failed myscript.service
sudo systemctl restart myscript.service
Avoid switching blindly to Restart=always. That setting can hide a program that is intentionally exiting or make a persistent configuration failure harder to notice. Use it only when the workload is explicitly designed for that behavior.
Network-dependent startup fails
Keep the ordering directives, but add connection retry logic in Python. The target may be reached before the specific remote application is accepting connections. A service should treat a transient network failure as recoverable rather than assuming one successful startup attempt proves network readiness.
Updating code without losing supervision
For a simple file-based deployment, copy the new files into the application directory, ensure ownership is still correct, and restart the unit:
sudo cp app.py /opt/myapp/
sudo chown myapp:myapp /opt/myapp/app.py
sudo systemctl restart myscript.service
sudo systemctl status myscript.service
If you change only the Python code, a daemon reload is not normally needed; restart the service so the interpreter loads the new file. If you change the unit itself—such as ExecStart, User, or an environment value—run daemon-reload before restarting. Always check the journal after deployment because a successful systemd restart only proves that the process was launched, not that the application completed its initialization.
Systemd compared with other ways to keep Python running
| Approach | Boot integration | Crash restart | Dependency ordering | Privilege isolation | Logs | Best fit |
|---|---|---|---|---|---|---|
| systemd | Native enablement through targets | Built in with Restart=on-failure |
Unit relationships such as After= and Wants= |
Dedicated User= |
Journald via journalctl |
A durable service on one Ubuntu host |
| cron | Scheduled invocation | Not a service supervisor | Limited | Runs as the configured cron user | Requires separate handling | Finite or periodic jobs rather than a continuously running process |
| tmux or screen | Not automatic unless separately scripted | Manual or separately configured | Minimal | Runs under the session user | Terminal-oriented | Interactive work that you want to detach temporarily |
| Docker or another container runtime | Depends on runtime and host configuration | Container policy dependent | Useful for packaged multi-component deployments | Container and host policy dependent | Runtime-specific | When packaging and environment isolation are the primary concern |
| External process manager | Depends on its integration | Usually available | Depends on the manager | Depends on its configuration | Manager-specific | When a larger application stack already standardizes on that supervisor |
For a single Python service on Ubuntu, adding another supervisor often creates two competing owners for the same process. Choose one authority: if systemd launches the script, let systemd handle restarts, logs, and startup instead of wrapping it in a second background mechanism.
Operational checklist
- Store the unit in
/etc/systemd/system/and give it a unique.servicename. - Use an absolute virtual-environment interpreter in
ExecStart. - Keep the Python process in the foreground with
Type=simple. - Run under a dedicated account and verify ownership and directory traversal.
- Set
WorkingDirectorydeliberately; do not depend on the directory used by an SSH shell. - Use
Restart=on-failureand a delay such asRestartSec=5for unexpected exits. - After every unit edit, run
systemctl daemon-reloadbefore restarting. - Use
systemctl enable --nowwhen you want both boot activation and an immediate start. - Check
systemctl statusfirst, then inspectjournalctl -u myscript.service -bfor the traceback. - After repeated failed starts, fix the cause and use
systemctl reset-failedif the start-rate limit has been reached. - Keep network retry logic in the application even when the unit is ordered after
network-online.target.
Removing the service
When the application is retired, stop and disable it before deleting the unit. Removing the file while a process is still running can leave the current process and systemd’s loaded definition out of sync.
sudo systemctl disable --now myscript.service
sudo rm /etc/systemd/system/myscript.service
sudo systemctl daemon-reload
sudo systemctl reset-failed myscript.service
The last command is useful if the removed unit had accumulated a failed state. Delete the application directory and account separately only after confirming that no other process or service uses them.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




