Learning by breaking/ building a Waitress watchdog for Windows

If you’ve seen my previous guide on deploying Django on Windows with Nginx and Waitress, you know I’m a fan of making things work in a Windows environment. But let’s be real: being new to this, I didn’t get everything perfect on the first try.

The first few times my project crashed, it was a wake-up call. I realized that instead of just hoping Waitress stays up, I needed a way to make sure it’s actually alive, and if it’s not, to bring it back automatically.

Instead of manually checking the server every hour, I wrote a Python Watchdog script that monitors the server’s heartbeat and brings it back to life if it fails.

To understand how this “safety net” works, we need to look at how I organized the files in my main directory, C:\project(this is presented in the reference tutorial).

Before this, the core was made of:

  • C:\project\refresh_stack.bat: My main script that kicks everything on(Nginx, run waitress script).
  • C:\project\app\run_server.py: The heart of the system—the actual file that starts Waitress.

To automate the health checks, I’ve added two new pieces to the C:\project\app folder:

  • monitor_waitress_stop.py: The “guardian” that checks if the server is still responding.
  • restart_waitress.bat: A quick shortcut the guardian calls if it notices Waitress has frozen.

How it works in the background

While run_server.py handles the heavy lifting of serving web pages, monitor_waitress_stop.py runs quietly in the background, giving the server a virtual “nudge” every minute.

If the Waitress port (8080) is unresponsive, the monitor doesn’t panic or try to fix the whole server. It simply calls restart_waitress.bat. This specific batch file has one goal:

  1. Find and kill the existing Waitress/Python process.
  2. Launch a fresh instance of run_server.py.

By keeping the restart localized to Waitress, Nginx remains untouched and ready to pass traffic the second the app is back online.

Place this file in C:\project\app\monitor_waitress_stop.py:

import socket, time, subprocess, os

# CONFIGURATION
TARGET = ('127.0.0.1', 8080)
RESTART_CMD = r"C:\project\app\restart_waitress.bat"

def check_and_restart():
    """Check port status and trigger restart if unreachable."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(3)
        # connect_ex returns 0 if the connection is successful
        if s.connect_ex(TARGET) != 0:
            print(f"[{time.ctime()}] Port {TARGET[1]} unresponsive. Restarting...")

            # Kill process on port 8080 to free the socket
            os.system(f'for /f "tokens=5" %a in (\'netstat -aon ^| findstr :{TARGET[1]}\') do taskkill /f /pid %a 2>nul')
            time.sleep(2)

            # Execute restart batch file
            subprocess.Popen([RESTART_CMD], shell=True)
            return True # Restart triggered
    return False # Server is healthy

if __name__ == "__main__":
    print(f"Monitor active on {TARGET[0]}:{TARGET[1]}")
    while True:
        # If restarted, wait 30s for boot; otherwise, check every 5s
        time.sleep(30 if check_and_restart() else 5)

Now the file that will restart waitress C:\project\app\restart_waitress.bat:

@echo off
set APP_PATH=C:\project\app

:: [1/2] Terminate any process using port 8080
:: Extracts PID from netstat and kills it forcefully
for /f "tokens=5" %%a in ('netstat -aon ^| findstr :8080') do taskkill /f /pid %%a

:: Wait 2 seconds to ensure the OS releases the socket
timeout /t 2 /nobreak > nul

:: [2/2] Change directory and launch Waitress in a new window
cd /d %APP_PATH%
start "Waitress" venv\Scripts\python run_server.py

echo Restart successful.

Before you save everything, double-check your file extensions. We are working with two different types of files that need to talk to each other:

  • restart_waitress.bat – this is a Windows Batch file. Its job is to talk to the operating system, kill the old processes, and run run_server.py file that we created in the previous tutorial.
  • monitor_waitress_stop.py – this is a Python script. Its job is to check the server status and deciding when it’s time to call the batch file.

How to Run the Watchdog

Now that you have both files in C:\project\app, it’s time to start the monitor. You don’t need to do anything fancy, just open a new command prompt and run the Python script.

  • Open Command Prompt (cmd).
  • Navigate to your app folder: cd C:\project\app
  • Start the monitor: python monitor_waitress_stop.py

Once you press Enter, you’ll see the script start to “ping” your server. It will print a message every 5s letting you know that Waitress is healthy.

Running it in the background

If you don’t want to keep a command prompt window open all day, you can run it using pythonw.exe. This is the “windowless” version of Python that runs in the background without a visible console:

  • Launch background mode: start pythonw monitor_waitress_stop.py

This will keep the monitor active in the background. It stays there, quietly watching over your Waitress server, ready to trigger restart_waitress.bat and call your original run_server.py the moment anything goes wrong.

Final Thoughts

This setup isn’t just about fixing a bug; it’s about peace of mind. As a beginner, things will break, that’s part of the process. But building a system that can pick itself back up is a huge step toward professional deployment.

Now, even if Waitress hangs while I’m away from my desk, I know my watchdog has my back.

“How do you handle server crashes in your Windows deployments? Let me know in the comments if this watchdog saved your uptime!”

Comments

Leave a Reply

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