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

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Run uWSGI as a non-root systemd service, give it a Unix socket in /run/uwsgi/, and configure Nginx to proxy to that same socket. The reliable sequence is: create an isolated deployment user and virtual environment, install and verify uWSGI there, define the application in an INI file, start it with systemd, then point Nginx at the socket and test locally before opening the site to the Internet.

What the finished deployment looks like

A production-style Ubuntu VPS deployment has four cooperating pieces:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Your application lives in its own directory and virtual environment.
  • uWSGI imports the application and keeps a master process plus a configured number of workers.
  • systemd starts uWSGI at boot, restarts it when appropriate, and records service output in the journal.
  • Nginx accepts HTTP requests and forwards them through a Unix socket (or, deliberately, a loopback TCP port) to uWSGI.

For one application, a dedicated systemd unit is the simplest design. If one VPS hosts several applications, uWSGI Emperor mode can supervise separate “vassal” configurations. In either design, keep the application process unprivileged and restrict access to the socket.

Choose the process and socket design first

Decision Recommended starting point What changes operationally
One app or several One systemd unit for one app Each unit has an obvious log stream, service name, and failure boundary. Emperor mode is useful when many independent apps must be watched from one supervisor.
Unix socket or TCP socket Unix socket under /run/uwsgi/ A local socket avoids opening a network listener and lets filesystem ownership and mode bits control access. TCP is useful when Nginx and uWSGI are separated, but bind it to loopback unless there is a deliberate, firewalled reason to expose it.
Host service or container systemd-managed host service for this guide systemd integrates directly with the VPS boot process, users, permissions, and journal. Container packaging has different networking, lifecycle, and filesystem decisions and is outside this deployment path.

The socket path is not cosmetic: the path in the uWSGI INI file and the path in Nginx must be byte-for-byte identical. Most “502 Bad Gateway” errors in this setup reduce to a missing socket, a wrong path, or permissions that prevent Nginx from opening it.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application:Upgraded attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Warranty & Support: Our Electric air duster comes with 5 years warranty and 24/7 customer service. During this period, if you have any questions,pls kindly feel free to contact us.

Prepare a least-privileged application account

Do not run the application or uWSGI as root. Create a deployment account with access only to the application files, its virtual environment, and the data it genuinely needs. The exact account-creation command and group names vary with your VPS image, so use the account-management method documented for the Ubuntu release you installed.

Give the account a stable application directory, for example /srv/myapp, and place the source code and virtual environment below it. Keep secrets out of world-readable code and configuration files; provide them through the secret mechanism appropriate to your service and VPS.

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

Create and verify the virtual environment

  1. As the deployment account, create a Python virtual environment in the application directory using the Python interpreter selected for your application.
  2. Activate that environment, install the application’s dependencies, and install uWSGI into the same environment with your normal Python package workflow.
  3. While the environment is active, run which uwsgi. Record the absolute path it prints; use that exact path in systemd rather than relying on a shell’s PATH.
  4. Test an import using the same interpreter and working directory that uWSGI will use. For an application package named myapp, a minimal check is python -c "import myapp". A successful import does not prove that every request works, but it catches missing dependencies and incorrect module paths before Nginx is involved.

If the import fails, fix the virtual environment, source checkout, or module path first. Starting Nginx earlier only hides the original error behind a generic upstream failure.

Write the uWSGI INI configuration

Create an INI file owned by an administrator or deployment account and readable by the systemd service. The following is a complete pattern; replace the example paths and application callable with values for your project.

[uwsgi]
chdir = /srv/myapp
module = myapp:app
home = /srv/myapp/venv
master = true
processes = 2
socket = /run/uwsgi/myapp.sock
chmod-socket = 660
vacuum = true
die-on-term = true

Set the application entry point

chdir establishes the directory from which imports are resolved. module names the Python module and callable uWSGI must load; myapp:app is only an example. Frameworks often expose a different callable, so use the import path your application defines. Keep the module syntax consistent with the import test you performed in the virtual environment.

Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

Point uWSGI at the virtual environment

home tells uWSGI which virtual environment supplies Python packages. It must refer to the same environment in which you installed uWSGI and tested the application. A mismatch here can produce an apparently valid service that fails to import the application at startup.

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

Configure the master and workers

master = true gives uWSGI a supervising master process that manages workers. Set processes to a conservative number appropriate for the VPS’s available CPU and memory, then adjust from observed resource use and request behavior. There is no safe universal worker number: a configuration that fits a small VPS can exhaust memory on a different application or workload.

Use a protected Unix socket

The socket line creates the endpoint Nginx will consume. Place it under /run/uwsgi/, which is intended for runtime state and is normally cleared at boot. chmod-socket = 660 allows the socket owner and group to use it while denying access to unrelated users. Make sure the group assigned to the socket includes the account under which Nginx runs; otherwise Nginx will receive “permission denied” even when the path is correct.

vacuum = true asks uWSGI to remove its socket when the process exits. die-on-term = true makes a normal termination signal end the master cleanly, which is important when systemd stops or restarts the service.

Keep runtime-directory ownership deliberate

The directory /run/uwsgi/ must exist before uWSGI creates the socket. Prefer systemd’s RuntimeDirectory=uwsgi in the unit shown below where your Ubuntu/systemd combination supports it. If that facility is unavailable, create the directory through the host’s supported runtime-directory or tmpfiles mechanism and assign ownership and mode explicitly. Do not leave a manually created directory with permissive access merely to make the first start succeed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.

Create a systemd unit for uWSGI

Create a unit such as /etc/systemd/system/myapp-uwsgi.service. The service account, group, and paths below are examples; substitute the account that owns the application and the absolute uWSGI path returned by which uwsgi.

[Unit]
Description=uWSGI service for myapp
After=network.target

[Service]
Type=notify
User=deploy
Group=www-data
WorkingDirectory=/srv/myapp
RuntimeDirectory=uwsgi
RuntimeDirectoryMode=0750
ExecStart=/srv/myapp/venv/bin/uwsgi --ini /etc/uwsgi/myapp.ini
Restart=on-failure

[Install]
WantedBy=multi-user.target

Why these directives matter

  • Type=notify uses uWSGI’s systemd notification support so systemd can distinguish startup from a process that merely exists. uWSGI’s documentation describes uWSGI as “a new-style daemon for systemd.”
  • User and Group prevent the application from running as root. The selected group must also make the socket readable and writable by Nginx, either through the service identity or through the socket’s configured group.
  • WorkingDirectory matches the application’s expected filesystem context.
  • RuntimeDirectory=uwsgi asks systemd to create and clean the volatile runtime directory. The resulting directory is beneath /run.
  • ExecStart calls the virtual environment’s uWSGI binary directly and passes the INI path explicitly. This avoids differences between an interactive shell and systemd’s restricted environment.
  • Restart=on-failure recovers from crashes without turning every intentional stop into an immediate restart loop.

If your uWSGI build lacks systemd notification support, Type=notify may prevent a successful startup. Confirm the capabilities of the installed build and use the service type supported by that build rather than adding daemonization flags. The systemd guide’s warning is explicit: “Do not daemonize the Emperor (or the master) unless you know what you are doing!!!” A systemd unit should normally keep the master in the foreground for systemd to supervise.

Load, enable, and inspect the unit

  1. Ask systemd to reread unit files after creating or editing the service: sudo systemctl daemon-reload.
  2. Start the service: sudo systemctl start myapp-uwsgi.service.
  3. Inspect the result immediately: sudo systemctl status myapp-uwsgi.service.
  4. If the start succeeds, enable it for boot: sudo systemctl enable myapp-uwsgi.service.
  5. After every configuration change, repeat the status check and inspect the journal for this unit with sudo journalctl -u myapp-uwsgi.service.

A healthy status result is not enough by itself. Confirm that the expected socket exists, has the intended owner and mode, and is located at exactly /run/uwsgi/myapp.sock. If the socket is absent, read the uWSGI startup error before changing Nginx.

Configure Nginx to proxy to the socket

In the relevant Nginx server block, include the standard uWSGI parameter set and pass requests to the same Unix socket:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
location / {
    include uwsgi_params;
    uwsgi_pass unix:/run/uwsgi/myapp.sock;
}

The include uwsgi_params; line supplies the request variables uWSGI applications commonly expect. The uwsgi_pass value must match the INI file’s socket value exactly, including the leading unix: prefix in Nginx.

Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.

Use TCP only deliberately

Nginx can instead forward to a loopback address and port, following the same pattern as the official Nginx example that uses uwsgi_pass localhost:9000;. If you choose TCP, configure uWSGI to listen on the corresponding loopback address and port, ensure no public interface is bound, and apply a firewall policy appropriate to the VPS. A Unix socket is usually the simpler local boundary because filesystem permissions determine which processes can connect.

Validate Nginx before reloading

  1. Run Nginx’s configuration test using the command provided by your Ubuntu installation.
  2. Correct syntax, include-path, or upstream errors reported by that test.
  3. Reload Nginx only after the test passes.
  4. Request the site locally through Nginx, for example with a local HTTP client, before testing from another network.

Keep Nginx’s error log available while making the first request. It distinguishes a refused upstream connection, a missing socket, and a permission failure far more clearly than a browser’s generic 502 page.

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.

Verify the complete request path

Test each layer in order so a failure has one likely cause:

  1. Application import: the virtual-environment interpreter imports the configured module and callable.
  2. uWSGI process: systemctl status shows the service running, and the journal has no startup traceback.
  3. Socket: the file exists under /run/uwsgi/, its mode is consistent with chmod-socket, and its group permits the Nginx account to connect.
  4. Nginx configuration: the configuration test passes and the service reloads cleanly.
  5. Local HTTP request: Nginx returns the application response when queried on the VPS itself.
  6. External access: only after local success should you apply the public listener, TLS configuration, and VPS firewall policy required for your deployment.

When a request fails, check the component that owns the failing boundary rather than restarting everything. uWSGI import errors belong in the uWSGI journal; socket access errors usually appear in the Nginx error log; an invalid Nginx directive is caught by the configuration test.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot the common failure modes

The service exits immediately

  • Read the unit journal for a Python traceback, an invalid INI option, or an incorrect ExecStart path.
  • Run the import test inside the same virtual environment named by home.
  • Confirm that chdir is the directory containing the package named by module.
  • Check whether the installed uWSGI build supports systemd notification when using Type=notify.

Nginx reports a missing socket or “connection refused”

  • Compare the INI socket and Nginx uwsgi_pass paths character for character.
  • Use systemctl status and the journal to determine whether uWSGI ever created the socket.
  • Remember that /run is volatile; a directory or socket created manually may disappear after reboot unless systemd or the host’s runtime-directory mechanism recreates it.

Nginx reports “permission denied”

  • Inspect the socket owner, group, and mode.
  • Identify the account Nginx actually uses on this VPS and ensure it belongs to the socket’s group, or choose a service/group arrangement that grants access without making the socket world-readable.
  • Check permissions on every parent directory, not only the socket file. Nginx needs traversal permission on /run/uwsgi/.

The service repeatedly restarts

Restart=on-failure is useful only after the underlying failure is understood. Read the latest journal entries, correct the application or configuration error, then restart deliberately. Repeatedly restarting an unchanged, failing unit can obscure the first useful traceback.

Best Value
Sale
Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
  • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
  • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
  • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
  • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
  • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.

Requests reach uWSGI but return application errors

At this point the socket and proxy path are working. Inspect application logs and verify environment variables, filesystem permissions, database connectivity, and framework-specific deployment settings. Those settings are application-specific and should not be guessed from a generic uWSGI template.

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.

Run several applications with Emperor mode

For multiple uWSGI applications, Emperor mode watches a directory of vassal configuration files. Point the Emperor at that directory and give each application its own INI file, socket, working directory, virtual environment, and least-privileged user/group.

The documented behavior is event-driven: adding a new vassal configuration starts a vassal, modifying one reloads its application, and removing one stops it. This makes onboarding and retirement consistent, but it also means that an accidental file copy or edit can start or reload a service. Restrict write access to the vassals directory and review changes like code deployments.

Manage the Emperor itself with systemd and keep it in the foreground. Do not add a daemonization option to the Emperor or to its masters merely because older init-script examples did so; systemd must retain ownership of the supervised process tree.

Characteristic Standalone unit Emperor with vassals
Best fit One application or a small number requiring explicit units Several independent uWSGI applications on one VPS
Configuration event Edit a unit/INI and restart or reload deliberately Adding, changing, or removing a vassal file starts, reloads, or stops that app
Isolation Clear per-service ownership and logs Still requires per-vassal uid/gid and socket permissions
Operational caution Keep the master foregrounded for systemd Never daemonize the Emperor or master unless you fully understand the supervision consequences

Security and maintenance checklist

  • Run the application under a dedicated non-root account.
  • Keep uWSGI on a Unix socket or a loopback TCP listener unless there is a documented reason to expose a network listener.
  • Use explicit socket ownership and mode; do not solve a permission error by making the socket world-readable.
  • Keep the application, virtual environment, and service paths consistent so systemd and interactive tests use the same code.
  • After each change, check the systemd status, read the unit journal, verify the socket, and inspect Nginx’s error log.
  • Test locally through Nginx before enabling public traffic.
  • Apply TLS and firewall rules appropriate to the Ubuntu release and VPS provider only after the local path works.
  • Record the worker count, socket path, service name, and deployment account so another administrator can diagnose the host without guessing.

Deployment decision summary

For a single application, use one systemd unit, a virtual-environment uWSGI binary, an INI file with a master process and conservatively sized workers, and a Unix socket beneath /run/uwsgi/. Let systemd create the runtime directory, keep uWSGI in the foreground with Type=notify, and grant Nginx access through deliberate group and mode settings. For multiple applications, use Emperor mode with one least-privileged vassal configuration per app, while preserving the same socket, logging, and foreground-process rules. The deployment is complete only when the application imports, the service stays healthy, the socket permissions are correct, Nginx passes its configuration test, and a local request succeeds.

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

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.