fix: lack of SIGTERM handling.

This commit is contained in:
2026-05-09 20:05:34 +02:00
parent 286fcdbe5b
commit 2699efc773
4 changed files with 33 additions and 17 deletions
+1 -1
View File
@@ -3,5 +3,5 @@ WORKDIR /app
COPY ./ok-server.py . COPY ./ok-server.py .
COPY ./entrypoint.sh /entrypoint.sh COPY ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh RUN chmod +x /entrypoint.sh
EXPOSE 8000 EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]
+4 -4
View File
@@ -36,7 +36,7 @@ node ok-server.mjs --bind 127.0.0.1 --port 8080 --look bootstrap
Connect to the server using a web browser or a tool like `curl`: Connect to the server using a web browser or a tool like `curl`:
```bash ```bash
curl -si "http://localhost:8000" curl -si "http://localhost:8080"
``` ```
### Docker ### Docker
@@ -45,7 +45,7 @@ Use the included `Dockerfile` to build and run the server in a Docker container:
```bash ```bash
docker build -t ok-server . docker build -t ok-server .
docker run --rm -d --name ok-server --cpus=1 --memory=256m -p 8000:8000 ok-server docker run --rm -d --name ok-server --cpus=1 --memory=256m -p 8080:8080 ok-server
``` ```
### Container CLI on a Mac ### Container CLI on a Mac
@@ -54,10 +54,10 @@ docker run --rm -d --name ok-server --cpus=1 --memory=256m -p 8000:8000 ok-serve
container builder stop container builder stop
container builder start -c 4 -m 1G container builder start -c 4 -m 1G
container build -t ok-server . container build -t ok-server .
container run --rm -d --name ok-server -c 1 -m 256m -p 8000:8000 ok-server container run --rm -d --name ok-server -c 1 -m 256m -p 8080:8080 ok-server
``` ```
This will start the server and expose it on port 8000. This will start the server and expose it on port 8080.
## License ## License
+12 -4
View File
@@ -205,7 +205,7 @@ function getClientIp(req) {
function parseArgs(argv) { function parseArgs(argv) {
let bind = "0.0.0.0"; let bind = "0.0.0.0";
let port = 8000; let port = 8080;
let look = "nice"; let look = "nice";
for (let i = 0; i < argv.length; i += 1) { for (let i = 0; i < argv.length; i += 1) {
@@ -253,7 +253,7 @@ function parseArgs(argv) {
"", "",
"Defaults:", "Defaults:",
" --bind 0.0.0.0", " --bind 0.0.0.0",
" --port 8000", " --port 8080",
" --look nice", " --look nice",
].join("\n"); ].join("\n");
console.log(help); console.log(help);
@@ -267,6 +267,7 @@ function parseArgs(argv) {
} }
function run(bind, port, look) { function run(bind, port, look) {
let isShuttingDown = false;
const server = http.createServer((req, res) => { const server = http.createServer((req, res) => {
const method = req.method || "GET"; const method = req.method || "GET";
@@ -309,10 +310,17 @@ function run(bind, port, look) {
console.log(`Serving on ${bind}:${port} (default look=${look}) (Ctrl-C to stop)`); console.log(`Serving on ${bind}:${port} (default look=${look}) (Ctrl-C to stop)`);
}); });
process.on("SIGINT", () => { function handleShutdownSignal() {
if (isShuttingDown) {
return;
}
isShuttingDown = true;
console.log("\nShutting down server"); console.log("\nShutting down server");
server.close(() => process.exit(0)); server.close(() => process.exit(0));
}); }
process.on("SIGINT", handleShutdownSignal);
process.on("SIGTERM", handleShutdownSignal);
} }
try { try {
+16 -8
View File
@@ -15,19 +15,20 @@ Behavior:
for that request only. Values are case-insensitive and must be one of basic,nice,bootstrap. for that request only. Values are case-insensitive and must be one of basic,nice,bootstrap.
Usage: Usage:
python3 ok_server.py # binds 0.0.0.0:8000, nice look python3 ok_server.py # binds 0.0.0.0:8080, nice look
python3 ok_server.py --look basic python3 ok_server.py --look basic
python3 ok_server.py -b 127.0.0.1 -p 8080 --look bootstrap python3 ok_server.py -b 127.0.0.1 -p 8080 --look bootstrap
Test: Test:
curl -i http://localhost:8000/ # text/plain for curl curl -i http://localhost:8080/ # text/plain for curl
curl -i "http://localhost:8000/?look=basic" # request-level override curl -i "http://localhost:8080/?look=basic" # request-level override
curl -I http://localhost:8000/ # HEAD (headers only) curl -I http://localhost:8080/ # HEAD (headers only)
wget -S -O - http://localhost:8000/ # text/plain for wget wget -S -O - http://localhost:8080/ # text/plain for wget
open http://localhost:8000/ # browser gets HTML variant per look open http://localhost:8080/ # browser gets HTML variant per look
""" """
import argparse import argparse
import signal
import sys import sys
from html import escape from html import escape
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
@@ -254,6 +255,13 @@ def run(bind: str, port: int, look: str):
addr = (bind, port) addr = (bind, port)
try: try:
with ThreadingHTTPServer(addr, OkHandler) as httpd: with ThreadingHTTPServer(addr, OkHandler) as httpd:
def _handle_termination(signum, _frame):
_ = signum
raise KeyboardInterrupt
signal.signal(signal.SIGINT, _handle_termination)
signal.signal(signal.SIGTERM, _handle_termination)
# attach chosen look to server so handlers can use it as default # attach chosen look to server so handlers can use it as default
httpd.look = look httpd.look = look
print(f"Serving on {bind}:{port} (default look={look}) (Ctrl-C to stop)") print(f"Serving on {bind}:{port} (default look={look}) (Ctrl-C to stop)")
@@ -269,8 +277,8 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="HTTP OK test server") parser = argparse.ArgumentParser(description="HTTP OK test server")
parser.add_argument("-b", "--bind", default="0.0.0.0", parser.add_argument("-b", "--bind", default="0.0.0.0",
help="Address to bind to (default: 0.0.0.0)") help="Address to bind to (default: 0.0.0.0)")
parser.add_argument("-p", "--port", type=int, default=8000, parser.add_argument("-p", "--port", type=int, default=8080,
help="Port to listen on (default: 8000)") help="Port to listen on (default: 8080)")
parser.add_argument("--look", choices=VALID_LOOKS, default=VALID_LOOKS[1], parser.add_argument("--look", choices=VALID_LOOKS, default=VALID_LOOKS[1],
help="Default HTML look for non-cli agents (basic, nice, bootstrap). Default: nice") help="Default HTML look for non-cli agents (basic, nice, bootstrap). Default: nice")
args = parser.parse_args() args = parser.parse_args()