Skip to content

How to Start and Stop Nginx from a Batch Script

Learn how to automate Nginx lifecycle management on Windows using Batch scripts, including start, stop, reload, and graceful shutdown commands with code examples.

Nginx is a high-performance web server, reverse proxy, and load balancer renowned for its efficiency with static content and concurrent connections. While Nginx is primarily associated with Linux, it runs natively on Windows and can be fully managed from Batch scripts. Automating Nginx lifecycle operations is essential for deployment pipelines, configuration changes, and maintenance tasks.

In this guide, we will explore how to start, stop, reload, and manage Nginx from a Batch Script on Windows.

Prerequisites

Nginx for Windows is a standalone application (no installation required). Download and extract it to a directory like C:\nginx.

File Purpose
nginx.exe The Nginx executable
conf\nginx.conf Main configuration file
logs\error.log Error log
logs\access.log Access log
html\ Default web root

Key Nginx Signal Commands

Signal Command Description
Start nginx Launch Nginx
Stop (fast) nginx -s stop Immediately terminate
Quit (graceful) nginx -s quit Finish active requests, then stop
Reload nginx -s reload Reload configuration without downtime
Reopen logs nginx -s reopen Reopen log files (for rotation)

Method 1: Basic Start and Stop

@echo off
setlocal enabledelayedexpansion

set "NGINX_HOME=C:\nginx"

if "%~1"=="" (
    echo Usage: nginx.bat [start^|stop^|quit^|reload^|restart]
    pause
    exit /b 1
)

if not exist "%NGINX_HOME%\nginx.exe" (
    echo [ERROR] Nginx not found at %NGINX_HOME%\nginx.exe
    pause
    exit /b 1
)

pushd "%NGINX_HOME%"

set "handled=0"

if /i "%~1"=="start" (
    set "handled=1"
    tasklist /fi "imagename eq nginx.exe" 2>nul | findstr /i "nginx.exe" >nul
    if !errorlevel!==0 (
        echo [WARNING] Nginx is already running. Use reload or restart instead.
    ) else (
        echo Starting Nginx...
        start "" nginx.exe
        echo [OK] Nginx start initiated.
    )
)

if /i "%~1"=="stop" (
    set "handled=1"
    echo Stopping Nginx (fast^)...
    nginx.exe -s stop
    if !errorlevel!==0 (
        echo [OK] Nginx stopped.
    ) else (
        echo [ERROR] Stop failed. Is Nginx running?
    )
)

if /i "%~1"=="quit" (
    set "handled=1"
    echo Stopping Nginx (graceful^)...
    nginx.exe -s quit
    if !errorlevel!==0 (
        echo [OK] Graceful shutdown initiated.
    ) else (
        echo [ERROR] Graceful stop failed. Is Nginx running?
    )
)

if /i "%~1"=="reload" (
    set "handled=1"
    echo Reloading Nginx configuration...
    nginx.exe -s reload
    if !errorlevel!==0 (
        echo [OK] Configuration reloaded.
    ) else (
        echo [ERROR] Reload failed. Is Nginx running?
    )
)

if /i "%~1"=="restart" (
    set "handled=1"
    echo Restarting Nginx...
    nginx.exe -s quit 2>nul
    timeout /t 3 /nobreak >nul
    start "" nginx.exe
    echo [OK] Nginx restart initiated.
)

if "!handled!"=="0" (
    echo [ERROR] Unknown command: %~1
    echo Valid commands: start, stop, quit, reload, restart
)

popd
pause

Method 2: Start with Configuration Test and Health Check

@echo off
setlocal enabledelayedexpansion

set "NGINX_HOME=C:\nginx"
set "health_url=http://localhost:80"
set "max_retries=10"
set "retry_delay=2"

echo =============================================
echo   NGINX STARTUP
echo =============================================
echo.

if not exist "%NGINX_HOME%\nginx.exe" (
    echo [ERROR] Nginx not found at %NGINX_HOME%\nginx.exe
    pause
    exit /b 1
)

pushd "%NGINX_HOME%"

:: Step 1: Test configuration
echo [1/3] Testing configuration...
nginx.exe -t 2> "%temp%\nginx_test.txt"

if %errorlevel% neq 0 (
    echo   [FAIL] Configuration error:
    type "%temp%\nginx_test.txt"
    del "%temp%\nginx_test.txt" 2>nul
    popd
    pause
    exit /b 1
)
echo   Configuration OK.
del "%temp%\nginx_test.txt" 2>nul

:: Step 2: Check if already running
tasklist /fi "imagename eq nginx.exe" 2>nul | findstr /i "nginx.exe" >nul
if %errorlevel%==0 (
    echo [INFO] Nginx is already running. Use reload or restart.
    popd
    pause
    exit /b 0
)

:: Step 3: Start
echo [2/3] Starting Nginx...
start "" nginx.exe

:: Step 4: Health check
echo [3/3] Verifying...
set "attempt=0"

:check
set /a attempt+=1

powershell -noprofile -command ^
  "try { $r = Invoke-WebRequest -Uri '%health_url%' -UseBasicParsing -TimeoutSec 2; ^
   if ($r.StatusCode -eq 200) { exit 0 } else { exit 1 } } catch { exit 1 }" >nul 2>&1

if !errorlevel!==0 (
    echo.
    echo [SUCCESS] Nginx is running at %health_url%
    popd
    exit /b 0
)

if !attempt! geq %max_retries% (
    echo.
    echo [ERROR] Nginx did not respond after %max_retries% attempts.
    echo Check: %NGINX_HOME%\logs\error.log
    popd
    pause
    exit /b 1
)

echo   Attempt !attempt!/%max_retries%...
timeout /t %retry_delay% /nobreak >nul
goto check

Method 3: Nginx Management Console

@echo off
title Nginx Manager
setlocal enabledelayedexpansion

set "NGINX_HOME=C:\nginx"

if not exist "%NGINX_HOME%\nginx.exe" (
    echo [ERROR] Nginx not found at %NGINX_HOME%\nginx.exe
    pause
    exit /b 1
)

:menu
cls
echo =============================================
echo   NGINX MANAGER
echo   Home: %NGINX_HOME%
echo =============================================
echo.

:: Check status
tasklist /fi "imagename eq nginx.exe" 2>nul | findstr /i "nginx.exe" >nul
if %errorlevel%==0 (
    echo   Status: RUNNING
    for /f %%C in ('tasklist /fi "imagename eq nginx.exe" 2^>nul ^| find /c "nginx.exe"') do echo   Processes: %%C
) else (
    echo   Status: STOPPED
)

echo.
echo   [1] Start
echo   [2] Stop (graceful^)
echo   [3] Stop (fast^)
echo   [4] Reload configuration
echo   [5] Restart
echo   [6] Test configuration
echo   [7] View error log (last 30 lines^)
echo   [8] View access log (last 20 lines^)
echo   [9] Show version and compile info
echo   [0] Exit
echo.
set /p "choice=Select: "

pushd "%NGINX_HOME%"

if "!choice!"=="1" (
    tasklist /fi "imagename eq nginx.exe" 2>nul | findstr /i "nginx.exe" >nul
    if !errorlevel!==0 (
        echo   Nginx is already running. Use Reload or Restart instead.
        pause
    ) else (
        echo Starting...
        start "" nginx.exe
        timeout /t 2 /nobreak >nul
    )
)
if "!choice!"=="2" (
    echo Graceful stop...
    nginx.exe -s quit
    timeout /t 3 /nobreak >nul
)
if "!choice!"=="3" (
    echo Fast stop...
    nginx.exe -s stop
    timeout /t 2 /nobreak >nul
)
if "!choice!"=="4" (
    echo Testing config first...
    nginx.exe -t
    if !errorlevel!==0 (
        nginx.exe -s reload
        if !errorlevel!==0 (
            echo [OK] Reloaded.
        ) else (
            echo [ERROR] Reload failed. Is Nginx running?
        )
    ) else (
        echo [ERROR] Config invalid. Not reloaded.
    )
    pause
)
if "!choice!"=="5" (
    echo Restarting...
    nginx.exe -s quit 2>nul
    timeout /t 3 /nobreak >nul
    start "" nginx.exe
    timeout /t 2 /nobreak >nul
)
if "!choice!"=="6" (
    echo.
    nginx.exe -t
    pause
)
if "!choice!"=="7" (
    echo.
    powershell -noprofile -command "Get-Content '%NGINX_HOME%\logs\error.log' -Tail 30"
    pause
)
if "!choice!"=="8" (
    echo.
    powershell -noprofile -command "Get-Content '%NGINX_HOME%\logs\access.log' -Tail 20"
    pause
)
if "!choice!"=="9" (
    echo.
    nginx.exe -V
    pause
)

popd
if "!choice!"=="0" exit /b 0

goto menu

Method 4: Configuration Reload (Zero-Downtime Updates)

The most common production operation is reloading configuration after changes:

@echo off
setlocal

set "NGINX_HOME=C:\nginx"

echo =============================================
echo   NGINX CONFIG RELOAD
echo =============================================
echo.

if not exist "%NGINX_HOME%\nginx.exe" (
    echo [ERROR] Nginx not found at %NGINX_HOME%\nginx.exe
    pause
    exit /b 1
)

pushd "%NGINX_HOME%"

:: Verify Nginx is running
tasklist /fi "imagename eq nginx.exe" 2>nul | findstr /i "nginx.exe" >nul
if %errorlevel% neq 0 (
    echo [ERROR] Nginx is not running. Start it before reloading.
    popd
    pause
    exit /b 1
)

:: Test before reloading
echo Testing configuration...
nginx.exe -t 2>&1

if %errorlevel% neq 0 (
    echo.
    echo [ABORT] Configuration has errors. Not reloading.
    echo Fix the configuration and try again.
    popd
    pause
    exit /b 1
)

echo.
echo Configuration is valid. Reloading...
nginx.exe -s reload

if %errorlevel%==0 (
    echo [SUCCESS] Nginx reloaded with new configuration.
    echo Active connections were not interrupted.
) else (
    echo [ERROR] Reload command failed.
)

popd
pause

Method 5: Deploy and Reload

Update web content and reload Nginx:

@echo off
setlocal

set "NGINX_HOME=C:\nginx"
set "web_root=%NGINX_HOME%\html\mysite"
set "source=C:\Build\Output\frontend"

echo =============================================
echo   DEPLOY AND RELOAD
echo =============================================
echo.

:: Step 1: Deploy new files
echo [1/3] Deploying files...
robocopy "%source%" "%web_root%" /mir /r:2 /w:3 /np /ndl /nfl >nul

if %errorlevel% gtr 7 (
    echo [ERROR] File copy failed.
    pause
    exit /b 1
)
echo   Files updated.

:: Step 2: Test config
echo [2/3] Testing configuration...
pushd "%NGINX_HOME%"
nginx.exe -t 2>"%temp%\nginx_test.txt"
if %errorlevel% neq 0 (
    echo [ERROR] Configuration error after deploy:
    type "%temp%\nginx_test.txt"
    del "%temp%\nginx_test.txt" 2>nul
    popd
    pause
    exit /b 1
)
del "%temp%\nginx_test.txt" 2>nul
echo   Config OK.

:: Step 3: Reload
echo [3/3] Reloading Nginx...
nginx.exe -s reload
set "reload_rc=%errorlevel%"
popd

if %reload_rc%==0 (
    echo.
    echo [SUCCESS] Deployment complete. Nginx reloaded.
) else (
    echo.
    echo [ERROR] Reload failed. Is Nginx running?
)

pause

Log Rotation

Nginx on Windows does not rotate logs automatically. Use a script to rotate them:

@echo off
setlocal enabledelayedexpansion

set "NGINX_HOME=C:\nginx"
set "log_dir=%NGINX_HOME%\logs"

for /f "tokens=2 delims==" %%T in ('wmic os get LocalDateTime /value') do set "dt=%%T"
set "timestamp=%dt:~0,8%"

:: Rename current logs
set "rotated=0"
if exist "%log_dir%\access.log" (
    move "%log_dir%\access.log" "%log_dir%\access_%timestamp%.log" >nul 2>&1
    if !errorlevel!==0 (set /a rotated+=1) else (echo [WARNING] Could not rotate access.log)
)
if exist "%log_dir%\error.log" (
    move "%log_dir%\error.log" "%log_dir%\error_%timestamp%.log" >nul 2>&1
    if !errorlevel!==0 (set /a rotated+=1) else (echo [WARNING] Could not rotate error.log)
)

if !rotated!==0 (
    echo [INFO] No logs were rotated.
) else (
    :: Tell Nginx to reopen log files (creates new ones)
    pushd "%NGINX_HOME%"
    nginx.exe -s reopen
    popd
    echo [OK] !rotated! log file(s^) rotated.
)

:: Clean old logs (keep 30 days)
forfiles /p "%log_dir%" /m "access_*.log" /d -30 /c "cmd /c del @path" 2>nul
forfiles /p "%log_dir%" /m "error_*.log" /d -30 /c "cmd /c del @path" 2>nul

echo [OK] Old logs cleaned up.

Common Mistakes

The Wrong Way: Starting Multiple Nginx Instances

:: WRONG - Running start multiple times creates duplicate processes
start "" nginx.exe
start "" nginx.exe
:: Two master processes, port conflict

Output Concern: Always check if Nginx is already running before starting. Multiple instances cause port binding conflicts and unpredictable behavior. Use tasklist to verify before starting.

The Wrong Way: Reloading Without Config Test

:: WRONG - Bad config causes reload to fail and may stop serving
nginx.exe -s reload
:: If nginx.conf has errors, worker processes may not restart

Always run nginx.exe -t to validate the configuration before reloading. Unlike Apache, Nginx's reload on Windows can behave unpredictably with invalid configurations.

Best Practices

  1. Always test config before reload/restart: Run nginx.exe -t to catch syntax errors.
  2. Use graceful quit (-s quit) over fast stop (-s stop): Allows active requests to complete.
  3. Use reload for config changes: -s reload applies changes without dropping connections.
  4. Run from the Nginx directory: Use pushd/popd or -p prefix to ensure correct path resolution.
  5. Implement log rotation: Nginx on Windows does not auto-rotate logs. Schedule rotation scripts.

Conclusion

Starting and stopping Nginx from a Batch Script involves running nginx.exe with signal commands (-s stop, -s quit, -s reload). The key to reliable Nginx management on Windows is always validating configuration with nginx.exe -t before any reload or restart, checking for existing instances before starting, and using graceful quit to avoid dropping active connections. By combining configuration testing, health checks, deployment workflows, and log rotation into management scripts, administrators maintain robust Nginx operations on Windows servers.

Navigation