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.

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

Deploy a Bottle application on a VPS as a WSGI app behind Gunicorn or Waitress, with Nginx handling public HTTP and HTTPS traffic and systemd keeping the process running after reboots. Bottle’s built-in server is suitable for development and smoke tests, but its simple single-threaded server is not a production front end for a growing or public application.

What a production Bottle deployment looks like

A reliable deployment separates the application from the public web edge. Bottle creates the WSGI application object; a production WSGI server loads that object and manages application workers or threads; Nginx accepts connections on ports 80 and 443, serves suitable static files, and forwards dynamic requests; systemd starts, stops, restarts, and logs the application service.

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

A typical request travels through this chain:

  1. A browser resolves your domain to the VPS public IP address.
  2. Nginx receives the HTTP or HTTPS request.
  3. Nginx serves a static asset directly when configured to do so, or proxies the request to a private address such as 127.0.0.1:8000 or a Unix socket.
  4. Gunicorn, Waitress, or another WSGI adapter invokes the importable Bottle application.
  5. The response returns through Nginx to the client.

Keep the WSGI server bound to localhost or a Unix socket unless you have a specific reason to expose it. The public interface should be Nginx, not the application worker.

Prerequisites and design decisions

VPS and DNS

Use a Linux VPS with a public IPv4 address, or IPv6 if your intended clients and firewall policy support it. Create an A record for the application domain that points to the server’s public IPv4 address; add an AAAA record only when IPv6 is configured end to end. DNS changes can take time to appear at different resolvers, so verify resolution from an external network before diagnosing the web server.

#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: 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.
  • Economical &Reusable: Built durable materials with a long-lasting battery,our CAGIWIRU air duster it's a sustainable alternative to disposable air cans.

Operating-system access

You need an administrative account capable of installing packages and creating system services. Perform those administrative actions with sudo, but run the Bottle process as a dedicated unprivileged account. Bottle’s tutorial explicitly warns against running a web application with root or administrator rights. A compromised application should not automatically have permission to modify the operating system.

Public and private ports

Allow inbound TCP port 80 for HTTP and TCP port 443 for HTTPS at the VPS firewall and any provider-level firewall. Do not open the Gunicorn or Waitress port to the Internet when Nginx is on the same machine. If you use a Unix socket, there is no application TCP port to expose.

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

Choose a process layout

For most Linux VPS deployments, use Gunicorn behind Nginx and systemd. Bottle’s deployment documentation calls Gunicorn a very good production choice, and Gunicorn’s documentation includes service, socket, and Nginx examples. Waitress is a sound alternative when its multi-threaded model or cross-platform operation better fits your environment. Nginx Unit is another documented runtime option, but it uses its own application configuration model rather than the conventional Gunicorn-plus-systemd layout.

Create the application account and directory

Replace mybottleapp and myapp.example with your own names. The following example creates a system account with no interactive login and stores the deployment under /srv/mybottleapp.

sudo useradd --system --home /srv/mybottleapp --create-home --shell /usr/sbin/nologin mybottleapp
sudo mkdir -p /srv/mybottleapp
sudo chown -R mybottleapp:mybottleapp /srv/mybottleapp

On distributions that do not provide /usr/sbin/nologin, use the equivalent non-login shell supplied by that distribution. Keep source code, the virtual environment, logs managed by systemd, and any private configuration under controlled ownership. Give the service write access only to directories that genuinely need it, such as an upload or cache directory.

Create a virtual environment and lock dependencies

Install Python and the distribution’s virtual-environment package first. The exact package names vary by Linux distribution; use its supported package manager. Then create an isolated environment owned by the application account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo -u mybottleapp python3 -m venv /srv/mybottleapp/venv
sudo -u mybottleapp /srv/mybottleapp/venv/bin/python -m pip install --upgrade pip
sudo -u mybottleapp /srv/mybottleapp/venv/bin/pip install bottle gunicorn

If you choose Waitress instead, install it in the same 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
sudo -u mybottleapp /srv/mybottleapp/venv/bin/pip install bottle waitress

Record exact versions after validating the deployment. A simple locked file can be generated with:

sudo -u mybottleapp /srv/mybottleapp/venv/bin/pip freeze > /srv/mybottleapp/requirements.txt

For repeatable rebuilds, review that file, keep it with your deployment source, and install it with pip install -r requirements.txt during later releases. Do not copy a virtual environment from another operating system or Python installation; recreate it from the locked dependencies instead.

Make the Bottle application importable

Gunicorn and Waitress need a module path and an application object. For example, /srv/mybottleapp/myapp.py can contain:

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

app = Bottle()

@app.get('/')
def index():
    return 'Hello from Bottle'

@app.get('/health')
def health():
    return 'ok'

The expression myapp:app means “import the app object from the myapp module.” If your object is named application, use myapp:application instead. Bottle also supports an application created with default_app(); expose that object under a stable name and point the server at it.

Do not call Bottle’s run() function when Gunicorn or Waitress imports the module. Put development-only startup code behind a main guard:

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True, reloader=True)

Without the guard, importing the module can start a second development server, block the WSGI worker, or fail because the port is already in use. Keep debug mode disabled in production because it can reveal implementation details and sensitive data.

Smoke-test Bottle before adding Nginx

Run a local test as the application account. First test Bottle’s development server if you need to verify routing, then test the production WSGI adapter.

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.
Rank #3
Sale
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black | LED mouse pad with 14 lighting modes, covers keyboard & mouse, anti-slip rubber base, waterproof surface, USB powered
  • 【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.
sudo -u mybottleapp sh -c 'cd /srv/mybottleapp && /srv/mybottleapp/venv/bin/python myapp.py'

That command should bind only to a local development port if your main guard specifies one. Stop it before continuing. A Gunicorn smoke test using the private port from the deployment plan is:

sudo -u mybottleapp sh -c 'cd /srv/mybottleapp && /srv/mybottleapp/venv/bin/gunicorn --workers 4 --bind 127.0.0.1:8000 myapp:app'

From a second shell on the VPS, request the endpoint:

curl --fail http://127.0.0.1:8000/health

The four-worker command is the form shown in Bottle’s deployment documentation, not a universal capacity rule. Confirm that the endpoint responds, then stop Gunicorn with Ctrl+C before creating the permanent service.

Gunicorn, Waitress, or Nginx Unit?

All three can serve a Bottle WSGI application, but they solve operational problems differently. The official Bottle and Gunicorn documentation does not establish a universal performance winner, and no numeric capacity claim should be inferred from the following comparison.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Option Concurrency model and deployment fit When it is attractive Trade-offs to evaluate
Gunicorn Pre-fork worker model; supports multiple worker processes and documented systemd, Unix-socket, and Nginx arrangements. Linux VPS deployments that need a familiar process manager, independent worker processes, and extensive deployment controls. Each process has its own memory footprint; worker count must be sized for the VPS and application workload.
Waitress Multi-threaded WSGI adapter supported by Bottle and usable across common operating systems. Teams that prefer a threaded server or need the same adapter on Linux and other supported operating systems. Install it separately and validate thread safety, blocking I/O behavior, logging, and systemd integration for your application.
Nginx Unit Application server and runtime managed through Unit configuration, with a Bottle-specific deployment guide. Deployments that want Unit to manage the application runtime rather than assembling a separate Gunicorn service. It is a different operational model, so existing Gunicorn/systemd procedures and tooling do not transfer unchanged.

Consider operational familiarity, the worker or thread model, TLS termination, static-file handling, observability, package availability, and the VPS’s CPU and memory limits. Measure your own application under representative load before changing worker counts or selecting a different adapter.

Run Gunicorn under systemd

Create a service unit such as /etc/systemd/system/mybottleapp.service:

[Unit]
Description=Gunicorn service for my Bottle application
After=network.target

[Service]
User=mybottleapp
Group=mybottleapp
WorkingDirectory=/srv/mybottleapp
EnvironmentFile=-/etc/mybottleapp.env
ExecStart=/srv/mybottleapp/venv/bin/gunicorn --workers 4 --bind 127.0.0.1:8000 myapp:app
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

User, Group, and WorkingDirectory prevent accidental execution from the wrong account or directory. The executable path points into the virtual environment, so the service does not depend on an administrator’s shell configuration. The optional environment file is useful for non-public settings; protect it with restrictive ownership and permissions.

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.

Load and start the unit:

sudo systemctl daemon-reload
sudo systemctl enable --now mybottleapp.service
sudo systemctl status mybottleapp.service
sudo journalctl -u mybottleapp.service -e

enable --now both enables startup at boot and starts the service immediately. Use journalctl -u mybottleapp.service -f while sending a request to watch live logs. After a code or dependency release, restart deliberately and verify the status:

sudo systemctl restart mybottleapp.service
sudo systemctl is-active mybottleapp.service

Use a Unix socket when you prefer filesystem permissions

A Unix socket avoids a local TCP listener and lets Nginx connect through a filesystem path. Create a dedicated runtime directory, then use a service command such as:

ExecStart=/srv/mybottleapp/venv/bin/gunicorn --workers 4 --bind unix:/run/mybottleapp/gunicorn.sock myapp:app

The service must create /run/mybottleapp at boot and give Nginx permission to access the socket. A systemd-managed runtime directory can be declared with:

RuntimeDirectory=mybottleapp
RuntimeDirectoryMode=0750

Set the socket group to the Nginx account using Gunicorn’s supported socket options or an appropriate systemd configuration. If Nginx reports “permission denied,” inspect both the directory and socket permissions; granting access to the socket alone is not enough if Nginx cannot traverse the parent directory.

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

Configure Nginx as the reverse proxy

Install Nginx using your distribution’s supported packages and create a server block for the domain. This TCP example proxies to the service above:

server {
    listen 80;
    listen [::]:80;
    server_name myapp.example www.myapp.example;

    location /static/ {
        alias /srv/mybottleapp/static/;
        try_files $uri =404;
    }

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8000;
    }
}

Adjust the static directory to match your project. The trailing slash behavior of alias matters: the URL prefix and filesystem path should correspond exactly. If the application does not have a static directory, remove that location instead of pointing it at an arbitrary path.

For a Unix socket, replace the proxy target with a socket URL:

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.
proxy_pass http://unix:/run/mybottleapp/gunicorn.sock;

On distributions that use a sites-enabled directory, link the configuration into that directory according to the distribution’s convention. Test and reload safely:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo nginx -t
sudo systemctl enable --now nginx
sudo systemctl reload nginx

The standard proxy headers preserve the original host, client address chain, and HTTP-versus-HTTPS scheme. Your application should treat forwarded headers as trustworthy only because requests reach it through your controlled Nginx proxy; do not expose the backend directly while relying on those headers.

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

Add HTTPS and verify the public path

First confirm that the domain resolves to the VPS and that Nginx answers on port 80. Then use the certificate and renewal process supported by your Linux distribution or VPS environment. Configure the certificate for the domain, redirect plain HTTP to HTTPS after validating the secure virtual host, and enable automatic renewal. Test renewal before the certificate’s expiration window rather than assuming it is configured.

Use local and external checks that isolate each layer:

  1. On the VPS, run curl --fail http://127.0.0.1:8000/health to test Gunicorn and Bottle.
  2. On the VPS, run curl --fail -H 'Host: myapp.example' http://127.0.0.1/health to test Nginx routing without relying on public DNS.
  3. From another network, request https://myapp.example/health to test DNS, firewall rules, TLS, Nginx, and the application together.

Use a simple health endpoint that does not expose credentials, stack traces, or database contents. If your application depends on a database or another service, decide whether the health check should report only process availability or also dependency readiness.

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

Handle configuration, files, and secrets safely

Environment-specific settings

Keep development and production settings separate. Put the production secret key, database URL, and other private values in a root-owned environment file readable by the service account, or use the secret-management facility provided by your VPS platform. Never commit credentials to the application repository or place them in a public static directory.

Static assets and uploads

Serve immutable CSS, JavaScript, and image assets from Nginx when practical. This removes static traffic from the Bottle workers. Store user uploads outside the source tree, validate filenames and content, and grant the application write permission only to the upload directory. Back up uploads separately from code because a redeployment should not delete user data.

Logs and observability

Let systemd collect service output in the journal or configure a deliberate log destination. Include enough request and application context to diagnose failures, but redact passwords, tokens, session cookies, and personal data. Watch Nginx access and error logs alongside the Gunicorn journal; a 502 response often means the proxy cannot connect to the backend, while a 500 response usually means the backend application raised an error.

Deploy updates without losing control

  1. Build or fetch the new release in a separate directory when possible.
  2. Install the locked dependencies into the release’s virtual environment, or update the existing environment during a controlled maintenance window.
  3. Run import and endpoint smoke tests as the unprivileged account.
  4. Check ownership and permissions for code, templates, static files, uploads, and environment files.
  5. Restart the systemd service and inspect its status and recent journal entries.
  6. Run the local health check, then the Nginx host-header check, then an external HTTPS check.
  7. Keep the previous release available until the new process has passed those checks, so you can roll back code and dependencies if needed.

Use systemctl reload nginx for Nginx configuration changes when a graceful reload is sufficient. Use systemctl restart mybottleapp.service when the Python code or virtual environment changed. A restart is not a substitute for a migration plan if your application changes database schemas.

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

Troubleshoot by layer

The service will not start

  • Run sudo systemctl status mybottleapp.service and sudo journalctl -u mybottleapp.service -b.
  • Copy the ExecStart command and run it as the configured user from the configured working directory.
  • Check that the virtual-environment binary exists and is executable.
  • Verify the module path, object name, and Python import dependencies. A message such as “failed to find attribute” usually indicates that myapp:app does not match the code.
  • Confirm that another process is not already using port 8000 or the Unix socket path.

Gunicorn reports an import or application error

  • Ensure WorkingDirectory is the directory containing the module, or use the correct Python package path.
  • Check that files are readable by mybottleapp.
  • Install every dependency into the same virtual environment referenced by ExecStart.
  • Remove top-level code that starts a development server, opens an interactive prompt, or assumes a developer-only environment variable.

Nginx returns 502 Bad Gateway

  • Check that the systemd service is active.
  • Confirm that Nginx’s proxy_pass target exactly matches Gunicorn’s bind address or socket path.
  • For a socket, inspect parent-directory traversal and socket group permissions.
  • Read the Nginx error log and the Gunicorn journal at the same timestamp.

The domain cannot be reached

  • Use a DNS lookup from outside the VPS and verify the returned address.
  • Check both the VPS provider firewall and the operating-system firewall for ports 80 and 443.
  • Confirm that Nginx is listening on the expected IPv4 and IPv6 addresses.
  • Test the site by IP and Host header locally to separate DNS problems from Nginx configuration errors.

HTTPS or redirects behave unexpectedly

  • Verify that the certificate covers the exact hostname users request.
  • Check the X-Forwarded-Proto handling when the application generates absolute URLs or secure redirects.
  • Make sure the HTTP-to-HTTPS redirect does not create a loop between Nginx and application middleware.
  • Confirm that renewal is enabled and that the renewed certificate is loaded after a successful Nginx reload.

Production readiness checklist

  • The application exposes an importable WSGI object and does not call run() during import.
  • Bottle, the chosen WSGI server, and all application dependencies are installed in a virtual environment.
  • Dependencies are recorded in a reviewed, repeatable requirements file.
  • The service runs under a dedicated unprivileged user, never root.
  • Gunicorn or Waitress listens only on localhost or a protected Unix socket.
  • systemd starts the service at boot, restarts it after failure, and provides usable logs.
  • Nginx proxies dynamic requests, serves configured static files, and passes the standard proxy headers.
  • Only the necessary public ports are open in both provider and operating-system firewalls.
  • DNS points to the correct VPS address, and HTTPS certificates renew automatically.
  • Secrets, uploads, backups, and logs have deliberate ownership, retention, and recovery procedures.
  • You have tested a local health endpoint, an Nginx-local request, an external HTTPS request, and a rollback.

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.