Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk10 min

How to Run a Python Script on Ubuntu as a Background Service

Learn how to run a Python script continuously on Ubuntu with systemd, including a secure unit file, virtual-environment paths, boot activation, restart policy, logs, and fixes for common failures.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.target when 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
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Write the systemd unit file

Create /etc/systemd/system/myscript.service as root:

Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【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]: Description identifies the service in status output. After=network-online.target orders startup after that target, and Wants=network-online.target asks 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] and WantedBy=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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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=1 helps 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
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Permission 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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:

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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 .service name.
  • 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 WorkingDirectory deliberately; do not depend on the directory used by an SSH shell.
  • Use Restart=on-failure and a delay such as RestartSec=5 for unexpected exits.
  • After every unit edit, run systemctl daemon-reload before restarting.
  • Use systemctl enable --now when you want both boot activation and an immediate start.
  • Check systemctl status first, then inspect journalctl -u myscript.service -b for the traceback.
  • After repeated failed starts, fix the cause and use systemctl reset-failed if 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.