SSD Nodes Learn 🎉 VPS החל מ־$5.50/חודש
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-13

Nginx לעומת Caddy לעומת Traefik: מה לבחור ל-VPS?

מתלבטים בין Nginx, Caddy ו-Traefik עבור ה-VPS שלכם? השוואה מעשית בין הכלים מבחינת ניהול תעודות TLS, הגדרות Docker, תמיכה ב-Websockets ועלות תחזוקה לכל יישום.

Nginx לעומת Caddy לעומת Traefik: התשובה הקצרה

Nginx, Caddy ו־Traefik מבצעים כולם את אותה עבודה כ־reverse proxy: הם מאזינים בפורט 443, קוראים את שם המתחם בכל בקשה ומעבירים אותה לשירות המתאים ב־VPS שלכם. כל אחד משלושת הכלים יאפשר לכם להציב ארבעה יישומים ב־self-hosting מאחורי כתובת IP ציבורית אחת, וכולם מהירים מספיק כך שהיישומים שלכם יהיו צוואר הבקבוק. ההבדל טמון בדרך שבה כל כלי מנפיק תעודת TLS (אבטחת שכבת תעבורה) ובכמות התצורה הנדרשת עבור כל יישום נוסף. הבדל נוסף מתגלה בהמשך, ביום שתזדקקו למשהו שמדריכים סטנדרטיים מדלגים עליו.

בחרו ב־Caddy אם אתם רוצים שנושא ה־HTTPS ינוהל עבורכם ושירותיכם הם יישומי אינטרנט רגילים. בחרו ב־Traefik אם הכל רץ בתוך Docker Compose ואתם מוסיפים שירות חדש מדי כמה שבועות. בחרו ב־Nginx אם אתם כבר מריצים אותו, או אם אתם זקוקים ל־caching של תגובות, תעודות לקוח, העברת TCP גולמית (raw TCP forwarding), או אם יש לכם תצורה קיימת גדולה שאתם מעדיפים לא לשכתב.

כיצד כל אחד מהם מקבל תעודת TLS?

ציר זה הוא הקובע עבור רוב המשתמשים, לכן כדאי להתחיל כאן. שלושתם מסיימים עם אותה תעודה מאותה רשות מאשרת (CA), אך העבודה הנדרשת כדי להגיע לכך שונה.

Caddy מבקש את התעודה מכיוון שהגדרת שם מארח (hostname). כתבו את app.example.com ככתובת האתר, ו-Caddy יבקש תעודה באמצעות פרוטוקול ACME (סביבת ניהול תעודות אוטומטית) מ-Let's Encrypt. אם הבקשה נכשלת, הוא ינסה את ZeroSSL, יגיש הפניה (redirect) מ-HTTP ל-HTTPS בפורט 80, ויבצע חידוש באופן עצמאי. אין צורך בכלי נוסף או בטיימר לבדיקה. התעודות נשמרות בספריית הנתונים של המשתמש caddy, בנתיב /var/lib/caddy/.local/share/caddy בהתקנה מחבילה, לכן יש להוסיף נתיב זה לגיבויים או לקבל הנפקה מחדש לאחר בנייה מחדש. עבור שם מארח שאינו ציבורי, tls internal חותם את התעודה באמצעות רשות מאשרת מקומית של Caddy. התוצאה זהה ל-יצירת תעודה בחתימה עצמית ב-Ubuntu, אך עם טיפול אוטומטי בחידוש.

ל-Nginx אין לקוח ACME מובנה. הכלי Certbot משיג את התעודה, והתוסף --nginx שלו משכתב את בלוק ה-server שלכם כדי להוסיף את המאזין בפורט 443 ואת ההפניה. החידוש מתבצע באמצעות טיימר של systemd המותקן עם החבילה, כך שיש שני רכיבים ושני דברים שיש לוודא: systemctl list-timers | grep certbot מציג את קיום הטיימר, ו-sudo certbot renew --dry-run מוודא שנתיב החידוש עדיין תקין. המדריך המפורט נמצא ב-Certbot ב-Ubuntu 24.04 עם Nginx, ואותו כלי תומך ב-תעודת wildcard דרך אתגר DNS-01 כאשר יש לכם יותר תת-מתחמים ממה שתרצו לפרט.

Traefik כולל לקוח ACME משלו. מגדירים פותר תעודות (certificate resolver) אחד בתצורה הסטטית, וכל נתב (router) יכול להשתמש בו. כל המצב, כולל מפתח החשבון והתעודות, נשמר בקובץ acme.json יחיד. Traefik יסרב להשתמש בקובץ אם הוא קריא למי שאינו הבעלים שלו, והוא יתריע על כך לפני שיבטל את הפותר:

The ACME resolver "le" is skipped from the resolvers list because: unable to get ACME account: permissions 660 for /letsencrypt/acme.json are too open, please use 600

עגנו (mount) ספרייה ואפשרו ל-Traefik ליצור את הקובץ בעצמו. אם תיצרו אותו תחילה באמצעות touch, הוא יירש את ה-umask שלכם, וזו הדרך שבה רוב המשתמשים נתקלים בשגיאה זו.

דבר אחד נכון לגבי שלושתם: אתגר HTTP-01 דורש שפורט 80 יהיה נגיש מהאינטרנט, כיוון שהרשות המאשרת מתחברת אליו בחזרה. פתיחת פורט 443 בלבד תגרום לכשל בהנפקה שייראה כשגיאת DNS.

אותה משימת ניתוב לשני יישומים בשלוש תצורות

המשימה: app.example.com מופנה לשירות ב-127.0.0.1:8080, ו-files.example.com מופנה לשירות ב-127.0.0.1:8081, שניהם מעל HTTPS. להלן היישום המלא בכל אחד מה-proxy, כדי להמחיש את ההבדל ברמת המלל במקום לטעון לקיומו.

Nginx

# /etc/nginx/sites-available/app.example.com
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
    }
}

לאחר מכן יש ליצור קישור, לבצע בדיקה, לטעון מחדש ולהוסיף את התעודה.

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d app.example.com

הרצת nginx -t עם syntax is ok ו-test is successful היא הבדיקה שיש לבצע לפני כל טעינה מחדש. היישום השני הוא אותו בלוק עם שינוי שם המארח והפורט. השורות proxy_set_header אינן קישוט: כאשר proxy_pass מציין כתובת, Nginx שולח כברירת מחדל את Host: 127.0.0.1:8080 ל-upstream, לכן יישום שבונה כתובות URL מוחלטות מתוך ה-Host header ישלח את המשתמשים שלכם ל-localhost.

Caddy

app.example.com {
	reverse_proxy 127.0.0.1:8080
}

files.example.com {
	reverse_proxy 127.0.0.1:8081
}
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

זהו הקובץ המלא. reverse_proxy מגדיר את X-Forwarded-For, X-Forwarded-Proto ו-X-Forwarded-Host בעצמו, ובברירת מחדל הוא מתעלם מכל מה שהלקוח שלח ב-headers אלו, כך שבקשה לא יכולה להטעות את ה-backend לגבי מקורה. תעודות, הפניה מפורט 80 וחידוש תעודות – הכל נגזר משתי כתובות האתר. שום דבר אחר בקובץ לא דורש הגדרה נוספת עבורם.

Traefik

Traefik דורש תצורה סטטית לפני שהוא מנתב דבר מה. כשירות ב-Compose, עם תגית ה-image העדכנית לאוגוסט 2026:

services:
  traefik:
    image: traefik:v3.7
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.le.acme.email=you@example.com"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt

כל יישום נושא לאחר מכן את הניתוב שלו, באמצעות labels, בתוך קובץ ה-compose שלו:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.example.com`)"
      - "traefik.http.routers.app.entrypoints=websecure"
      - "traefik.http.routers.app.tls.certresolver=le"
      - "traefik.http.services.app.loadbalancer.server.port=8080"

loadbalancer.server.port הוא הפורט בתוך ה-container, לא פורט חשוף, כיוון ש-Traefik מגיע ל-container דרך רשת Docker משותפת. היישום אינו זקוק לשורת ports: כלל, וזהו היתרון הממשי: רק Traefik חשוף החוצה. המבנה המלא, כולל הרשת המשותפת ו-middleware ההפניה, נמצא ב-ניתוב מספר יישומים עם Traefik ו-Docker Compose.

מה העלות התפעולית של הגדרת יישום נוסף?

ChartNon-blank config lines for the same two-app routing job
The data behind this chart
[
  {
    "tool": "Nginx",
    "proxy_setup_lines": 0,
    "lines_per_app": 11
  },
  {
    "tool": "Caddy",
    "proxy_setup_lines": 0,
    "lines_per_app": 3
  },
  {
    "tool": "Traefik",
    "proxy_setup_lines": 17,
    "lines_per_app": 5
  }
]

החישוב מתבסס על הבלוקים שלעיל. בלוק השרת של Nginx כולל 11 שורות שאינן ריקות, ואתם נדרשים לכתוב אותו מחדש עבור כל שם מתחם. בלוק האתר של Caddy כולל 3 שורות. Traefik דורש 17 שורות של תצורה סטטית לפני שהוא מגיש בקשה ראשונה, ולאחר מכן 5 תוויות (labels) לכל יישום.

בחנו את הפשרה, לא את המנצח. Traefik הוא היקר ביותר לפני היישום הראשון, אך הזול ביותר עבור כל יישום נוסף, ושני הסכומים נפגשים סביב האתר השלישי. מתחת לרף זה, התצורה הסטטית היא תקורה מיותרת. מעליו, התוויות הופכות ליעילות יותר, כיוון שהניתוב נמצא לצד השירות שאותו הוא מנתב. מחיקת השירות גוררת את מחיקת הניתוב שלו, וזהו היתרון המרכזי על פני קובץ תצורה מרכזי: מניעת בלוקים של שרתים "יתומים" עבור יישומים שכבר אינם קיימים חודשים.

ספירת השורות מחמיאה ל־Nginx באופן חלקי בלבד. כל בלוק כזה דורש יצירת symlink, הרצת nginx -t, טעינה מחדש (reload) והרצת certbot, בעוד שעדכון ב־Caddy דורש טעינה מחדש בלבד, ועדכון ב־Traefik אינו דורש הרצת פקודה כלל. שלושתם מבצעים טעינה מחדש ללא ניתוק חיבורים פעילים. ההבדל טמון במספר הצעדים הנפרדים שעליכם לזכור לבצע בשלוש לפנות בוקר.

מי מודע למכולות שלך?

Traefik מנטר את ה-socket של Docker ובונה נתבים (routers) מתוך תוויות (labels) של מכולות בזמן שהן עולות או נעצרות. שום כלי אחר כאן לא מבצע זאת. Nginx ו-Caddy דורשים שניהם עריכה של קובץ התצורה וביצוע reload בכל פעם שמכולה חדשה מופיעה, והם זקוקים לכתובת שאליה יוכלו להגיע: או פורט שפורסם ב-loopback, או רשת Docker משותפת שה-proxy מחובר אליה.

לתכונה הזו יש מחיר, וכדאי לציין זאת בבירור. Traefik קורא את /var/run/docker.sock. כל מי שיכול לתקשר עם ה-socket הזה יכול להפעיל מכולה עם מערכת הקבצים של ה-host ממופית (mounted) בתוכה, מה שמעניק הרשאות root על ה-host. מיפוי במצב לקריאה בלבד (read-only) מפחית את הסיכון אך לא מבטל אותו. אם זה רלוונטי למודל האיומים שלך, הצב socket proxy בתווך שיחשוף רק את נקודות הקצה של רשימת המכולות ש-Traefik זקוק להן.

Caddy יכול לבצע גילוי מבוסס תוויות באמצעות תוסף קהילה, אך תוספי Caddy עוברים הידור (compile) לתוך התוכנה, לכן עליך לבנות קובץ בינארי מותאם אישית או image מותאם אישית עם xcaddy, ואז האחריות על הבנייה הזו ועל העדכונים שלה עוברת אליך. עבור שלושה או ארבעה שירותים, עריכת Caddyfile דורשת פחות עבודה.

Websockets וסטרימינג: מה משתבש ומדוע

Nginx הוא זה שזקוק לעזרה. חיבור WebSocket מתחיל כבקשת HTTP הנושאת את Upgrade: websocket, ו-Nginx אינו מעביר כותרות hop-by-hop לשרת ה-upstream אלא אם כן הוגדר לו לעשות זאת.

# /etc/nginx/conf.d/upgrade-map.conf
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

לאחר מכן, בתוך בלוק ה-location, יש להוסיף שלושה שורות שחייבות להופיע כולן:

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

השמטת שורות אלו תגרום למסוף הדפדפן להציג WebSocket connection to 'wss://app.example.com/ws' failed, בעוד לוג ה-backend יציג בקשת GET רגילה. ה-map קיים מכיוון ש-Connection: upgrade מקודד קשיח יישלח בכל בקשה, כולל בקשות רגילות שאמורות לציין close.

שתי הגדרות ברירת מחדל נוספות ב-Nginx עלולות להוות מכשול. proxy_read_timeout מוגדר כ-60 שניות והוא חל על המנהרה (tunnel) לאחר ה-upgrade, כך שחיבור WebSocket ללא תעבורה למשך דקה ייסגר על ידי ה-proxy. בנוסף, אירועים שנשלחים מהשרת (Server-sent events) מגיעים באיחור או בצרורות עד שמגדירים proxy_buffering off; באותו location, כיוון ש-Nginx מחזיק את התגובה ב-buffer בזמן שהדף ממתין לה.

Caddy מבצע את ה-upgrade ומעביר את החיבור למנהרה דו-כיוונית ללא צורך בהנחיות נוספות. הוא גם מבצע flush מיידי כאשר התגובה היא text/event-stream או ללא אורך ידוע, כך שסטרימינג עובד ללא שינוי. Traefik מעביר בקשות upgrade ומבצע buffering לתגובות רק אם מוסיפים ידנית את ה-middleware מסוג buffering. אם השירותים שלכם כוללים צ'אט, מסוף אינטרנטי, צפייה בלוגים בזמן אמת או לוחות בקרה חיים, מדובר בהבדל משמעותי בכמות התצורה שתצטרכו לכתוב ולנפות.

בלוק ה-server המלא של Nginx, כולל websockets ו-SSE
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name app.example.com;
    client_max_body_size 64m;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 3600s;
        proxy_buffering off;
    }
}

ה-map שייך להקשר ה-http, ולא לתוך server, לכן יש לשמור אותו בקובץ נפרד תחת /etc/nginx/conf.d/. כבו את proxy_buffering רק ב-locations שמבצעים סטרימינג, שכן ה-buffering הוא מה שמאפשר ל-Nginx לשחרר את ה-worker של ה-backend מוקדם בתגובות רגילות. Certbot משכתב את הבלוק הזה בעת הרצתו, לכן קראו את הקובץ שוב לאחר מכן.

מה קורה כשצריך משהו לא שגרתי?

כאן Nginx מצדיק את שורות הקוד הנוספות שלו.

  • תעודות לקוח, המכונות גם mTLS (mutual TLS), שבהן הלקוח חייב להציג תעודה משלו. Nginx דורש את ssl_client_certificate /etc/ssl/ca.pem; ו-ssl_verify_client on; בתוך בלוק ה-server. Caddy דורש בלוק client_auth בתוך tls. ב-Traefik לא ניתן להגדיר זאת באמצעות labels בלבד: עליך להגדיר אפשרות TLS ב-file provider ולהפנות אליה את ה-router באמצעות traefik.http.routers.app.tls.options=mtls@file. מודל ה-everything-in-labels נתקל בחריגה הראשונה ברגע שצריך יכולת זו.
  • העלאות קבצים גדולות. Nginx מגביל את גוף הבקשה ל-1 MB כברירת מחדל. העלאה גדולה יותר תחזיר 413 Request Entity Too Large, ויומן השגיאות יציג client intended to send too large body. יש להגדיל את client_max_body_size. ב-Caddy וב-Traefik אין הגבלת גודל גוף בקשה כברירת מחדל, לכן הבקשה מגיעה ליישום והמגבלה של היישום עצמו היא הקובעת.
  • Caching של תגובות. ל-Nginx יש את proxy_cache, והוא בשל מאוד. Caddy דורש תוסף (plugin) שעבר הידור (compile). בגרסת הקוד הפתוח של Traefik אין כלל HTTP cache, עובדה שמפתיעה אנשים שמניחים שכל proxy מבצע caching.
  • TCP או UDP גולמי, עבור פורט של מסד נתונים או שרת משחקים. ל-Nginx יש את מודול stream. ל-Traefik יש routers מסוג TCP ו-UDP על גבי ה-entrypoints שלהם. Caddy דורש תוסף נוסף, ולכן דורש הידור מותאם אישית.
  • שרת אינטרנט שכבר נמצא מאחורי ה-proxy. אם השירות הוא יישום PHP קלאסי, הרי ש-מחסנית LAMP על Ubuntu 24.04 כבר כוללת את Apache, והצבת proxy לפניו יוצרת שני מקומות שקובעים headers ושניים שיכולים לבצע rewrite ל-URL. החליטו מי מהם יבצע TLS termination, והשאירו את השני על HTTP רגיל המאזין ל-loopback בלבד.

מלכודת ה-firewall שנובעת מבחירה זו

המטרה של reverse proxy היא שרק פורטים 80 ו-443 יהיו פתוחים. Docker מבטל זאת בשקט. פרסום פורט באמצעות -p 8080:80 כותב חוק DNAT לתוך טבלת ה-nat, וחוק זה מוערך לפני חוקי ה-INPUT ש-ufw מנהל. לכן, ufw deny 8080 לא חוסם אותו והיישום שלכם חשוף לאינטרנט הציבורי לצד ה-proxy שהגדרתם בקפידה. בצעו Bind לפורטים מפורסמים אל ה-loopback באמצעות 127.0.0.1:8080:80, או וותרו על ports: לחלוטין ואפשרו ל-proxy להגיע למכולה דרך רשת Docker, כפי שנעשה בדוגמת ה-Traefik לעיל. המנגנון והפתרון מפורטים ב-מדוע פורטים מפורסמים של Docker עוקפים את ufw.

בצעו את הבדיקה ממכונה שאינה ה-VPS, כיוון שבדיקה שמורצת על השרת עצמו תמיד תצליח:

curl --max-time 5 http://your.server.address:8080

Connection refused או timeout הם התוצאה הרצויה. תגובת HTTP משמעותה שהיישום נגיש ללא מעבר דרך ה-proxy, וכל מה שהגדרתם לעיל הוא קישוט בלבד.

באיזה proxy כדאי לבחור?

אתרים סטטיים בעיקר, בתוספת יישום אחד או שניים: Caddy. תכונת ה-HTTPS האוטומטי חוסכת את המטלה החוזרת המעיקה ביותר. התצורה נשארת קצרה מספיק כדי להיקרא במסך אחד, ואתר סטטי דורש רק שורת root ושורת file_server בתוך אותו בלוק של האתר. המחיר הוא מאגר קטן יותר של פתרונות "העתק-הדבק" במקרה של תקלות חריגות.

סביבת homelab מבוססת docker-compose שמתרחבת כל הזמן: Traefik. מעבר לשירות השלישי, שימוש ב-labels דורש פחות עבודה מעריכת קובץ מרכזי, ושירות שנמחק לוקח איתו את נתיב הגישה שלו. הקצו אחר-צהריים אחד להגדרה הראשונית, כיוון ש-entrypoints, routers, services ו-middlewares הם מושגים חדשים. שגיאת הקלדה ב-label תופיע בדרך כלל כ-404 מצד Traefik במקום ככשל בהפעלה, לכן קראו את docker logs traefik כדי לאתר שגיאות ניתוח (parse error) לפני שתניחו שהיישום עצמו תקול.

תצורת Nginx קיימת, או כל דרישה אחרת מהרשימה לעיל: Nginx. ל-Nginx כבר יש פתרונות מובנים ל-caching של תגובות ולתעודות לקוח, וכמעט כל מדריך צד-שלישי מניח שזהו הכלי שבו אתם משתמשים. המחיר הוא שתעודות ותמיכה ב-websocket הם דברים שצריך להגדיר ידנית, במקום לקבל אותם כברירת מחדל.

כלל אחד תקף ללא קשר לבחירה שלכם: תהליך אחד בלבד מאזין לממשק הציבורי, וכל השאר מאזינים ל-loopback או לרשת Docker פנימית.

FAQ

איזה reverse proxy הוא הטוב ביותר עבור כמה יישומי Docker על שרת VPS יחיד?

עבור שלושה או ארבעה שירותים שאתם מוסיפים מדי פעם, Traefik מחזיר את ההשקעה, כיוון שכל יישום נושא את תוויות הניתוב שלו ואין צורך לערוך קובץ מרכזי. אם השירותים יציבים ואתם בעיקר רוצים להפסיק להתעסק עם HTTPS, ל־Caddy יש עקומת למידה מתונה יותר ופחות נקודות כשל. בחרו ב־Nginx אם אתם כבר מכירים אותו, או אם אתם זקוקים לתכונה שחסרה בשניים האחרים, כגון caching לתגובות או מאזין TCP פשוט.

האם Caddy באמת לא דורש הגדרת תעודות?

במקרה הסטנדרטי, כן. ציון שם מתחם ציבורי ככתובת האתר הוא כל התצורה הנדרשת: Caddy מבקש את התעודה דרך ACME, מגיש הפניה מפורט 80, ומחדש אותה לפני פקיעת התוקף. שני תנאים חייבים להתקיים: פורט 80 חייב להיות נגיש מהאינטרנט עבור ה־HTTP-01 challenge, ורשומת ה־DNS מסוג A או AAAA של שם המתחם חייבת להצביע על ה־VPS, כיוון שרשות התעודות פותרת את השם ומתחברת חזרה לשרת.

האם ניתן להריץ את Nginx ו־Traefik על אותו שרת VPS?

לא על אותם פורטים. מי שיעלה שני יכשל בביצוע ה־bind, ו־Nginx יציג bind() to 0.0.0.0:443 failed (98: Address already in use) בעוד Traefik יתעד שגיאת bind דומה ויסתיים. הריצו proxy אחד על פורטים 80 ו־443, והעבירו את כל השאר מאחוריו. אם אתם בתהליך הגירה, העבירו שמות מתחם אחד בכל פעם: תנו ל־proxy הקדמי להעביר תעבורה לזה הישן דרך פורט loopback עד שכל האתרים יועברו.

מדוע חיבורי WebSocket מתנתקים אחרי 60 שניות מאחורי Nginx?

proxy_read_timeout מוגדר כברירת מחדל ל-60 שניות והוא חל על ה־tunnel ברגע שה־upgrade הושלם, לכן חיבור ללא תעבורה במשך דקה נסגר על ידי ה־proxy ולא על ידי היישום שלכם. הגדילו את הערך במיקום הרלוונטי באמצעות proxy_read_timeout 3600s;, או גרמו ליישום לשלוח ping frame בכל 30 שניות. Caddy ו־Traefik אינם סוגרים חיבורים משודרגים (upgraded) בטיימר של דקה, וזו הסיבה שאותו יישום יכול להיראות יציב מאחוריהם ולא יציב מאחורי Nginx.