در کانتینر، localhost همان کانتینر است. امشب frontend به نام سرویس backend متصل می‌شود و با تغییر IP آن، درخواست‌های جدید همچنان مسیر درست را پیدا می‌کنند.

این جلسه بخشی از دورهٔ انجین‌اکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.

محیط: پوشهٔ container شب ۳۹، Docker Compose v2 و imageهای digest‌شده. این پروژه مستقل از WordPress میزبان است؛ backend صرفاً برنامهٔ آزمایشگاهی HTTP است.

تعریف سرویس‌ها#

image رسمی python:3.12-alpine را pull و digest آن را مثل شب قبل ثبت کن. در .env مقادیر واقعی NGINX_IMAGE و PYTHON_IMAGE را قرار بده. فایل compose.yaml:

services:
  frontend:
    image: ${NGINX_IMAGE:?set a verified image digest}
    user: "101:101"
    entrypoint: ["nginx"]
    command: ["-g", "daemon off;"]
    read_only: true
    cap_drop: [ALL]
    security_opt: ["no-new-privileges:true"]
    pids_limit: 100
    mem_limit: 256m
    tmpfs:
      - /tmp:uid=101,gid=101,mode=1770,size=64m
    ports:
      - "127.0.0.1:18081:8080"
    volumes:
      - ./conf/nginx.conf:/etc/nginx/nginx.conf:ro,Z
    networks: [appnet]
  backend:
    image: ${PYTHON_IMAGE:?set a verified image digest}
    user: "65534:65534"
    command: ["python", "-m", "http.server", "8080", "--bind", "0.0.0.0", "--directory", "/srv/content"]
    read_only: true
    cap_drop: [ALL]
    security_opt: ["no-new-privileges:true"]
    pids_limit: 100
    mem_limit: 128m
    volumes:
      - ./content:/srv/content:ro,Z
    networks: [appnet]
networks:
  appnet: {}

backend هیچ ports ندارد؛ فقط سرویس‌های عضو شبکه به آن وصل می‌شوند. شبکهٔ Compose به‌تنهایی firewall بین همهٔ اعضا نیست. internal: true خروج خارجی را نیز محدود می‌کند، ولی مسیر دسترسی frontend را باید با شبکهٔ ورودی جدا طراحی کنی؛ آن را بی‌آزمون به این نمونه اضافه نکن.

resolution هنگام درخواست#

config کامل شب ۳۹ را حفظ کن، root/location قبلی را بردار و در server به‌جای آن بنویس:

resolver 127.0.0.11 valid=10s ipv6=off;
set $backend backend:8080;
location / {
    proxy_pass http://$backend;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Connection "";
    proxy_connect_timeout 3s;
    proxy_read_timeout 15s;
}

127.0.0.11 resolver داخلی شبکهٔ سفارشی Docker است؛ آن را در VM بدون Docker کپی نکن. proxy_pass متغیردار با URI قواعد متفاوت دارد؛ اینجا URI اضافی ننوشته‌ایم تا مسیر درخواست حفظ شود. server backend:8080 resolve در upstreamهای OSS از نسخهٔ 1.27.3 عمومی شده است؛ برای سازگاری با نسخه‌های قدیمی‌تر، تمرین از متغیر و resolver استفاده می‌کند.

docker compose -p nginx-lab config --quiet
docker compose -p nginx-lab up -d
docker compose -p nginx-lab exec frontend nginx -t
curl --fail http://127.0.0.1:18081/
docker compose -p nginx-lab up -d --force-recreate backend

بعد از TTL DNS و آماده‌شدن backend، درخواست جدید باید دوباره موفق شود. هنگام replace، شکست کوتاه ممکن است؛ DNS پویا تضمین دسترس‌پذیری بی‌وقفه نیست. log frontend را برای resolve/connect error بررسی کن. IP قبل و بعد ممکن است تصادفاً برابر باشد؛ recreate به‌تنهایی اثبات تغییر IP نیست، آن‌ها را ثبت کن.

بازگشت: config قبلی را برگردان و recreate frontend کن. docker compose -p nginx-lab down فقط پروژهٔ آزمایشگاه را متوقف می‌کند؛ -v را بی‌نیاز اضافه نکن.

منبع: شبکهٔ Docker ، سرویس‌های Compose ، resolver و upstream .