SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-10-14

วิธีตั้งค่า Docker Compose Networking อย่างละเอียด

เรียนรู้การทำงานของ Docker Compose Network ทั้งการเชื่อมต่อผ่าน service name การจัดการ bridge network และกรณีที่ควรใช้ host mode รวมถึงข้อควรระวังเรื่อง port ที่ข้าม UFW

สิ่งที่ Compose สร้างก่อนที่แอปพลิเคชันของคุณจะเริ่มทำงาน

การทำงานของเครือข่ายใน Docker Compose มีกฎพื้นฐานหนึ่งข้อ: docker compose up จะสร้างเครือข่ายส่วนตัวสำหรับโปรเจกต์ เชื่อมต่อทุกเซอร์วิสเข้ากับเครือข่ายนั้น และอนุญาตให้เซอร์วิสเหล่านั้นติดต่อสื่อสารกันได้ผ่านชื่อเซอร์วิส คุณไม่จำเป็นต้องเขียนบรรทัด networks: ใดๆ เพื่อให้ได้ฟังก์ชันนี้ ความสับสนส่วนใหญ่เกี่ยวกับเครือข่ายของ Compose เกิดจากการไม่ทราบว่าค่าเริ่มต้นนี้มีอยู่แล้ว

นี่คือไฟล์ตัวอย่างขนาดเล็ก ให้บันทึกไฟล์นี้เป็น compose.yaml ในไดเรกทอรีที่ชื่อว่า shop

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example

เริ่มการทำงานของโปรเจกต์และตรวจสอบสิ่งที่ Docker สร้างขึ้น:

docker compose up -d
docker network ls

รายการที่แสดงตอนนี้จะมีเครือข่ายที่ชื่อว่า shop_default อยู่ด้วย Compose จะตั้งชื่อเครือข่ายนี้ว่า <project>_default โดยชื่อโปรเจกต์จะใช้ชื่อไดเรกทอรีเป็นตัวพิมพ์เล็กโดยอัตโนมัติ คุณสามารถกำหนดชื่อใหม่ได้ด้วย docker compose -p myproject up -d หรือใช้คำสั่ง name: myproject ที่ระดับบนสุดของไฟล์ ไดรเวอร์ของเครือข่ายนี้คือ bridge ซึ่งทำหน้าที่เป็นสวิตช์เสมือนภายในโฮสต์ คอนเทนเนอร์แต่ละตัวจะได้รับที่อยู่บนซับเน็ตส่วนตัว และทราฟฟิกขาออกจะถูกแปลงที่อยู่ (NAT) ไปเป็นที่อยู่ของโฮสต์ในขณะที่ส่งออกไป

docker compose down จะลบเครือข่ายนั้นออก นี่คือสาเหตุที่คอนเทนเนอร์ที่ค้างมาจากโปรเจกต์เก่าอาจทำให้เครือข่ายยังคงเปิดอยู่: Docker จะปฏิเสธการทำงานพร้อมข้อความ error while removing network: network shop_default has active endpoints และวิธีแก้ไขคือการหยุดหรือลบคอนเทนเนอร์ที่ยังคงเชื่อมต่อกับเครือข่ายนั้นอยู่

หากคุณเพิ่งเริ่มใช้งาน Compose การอ่าน โครงสร้างไฟล์ Compose และคำสั่งวงจรชีวิต ก่อนถือเป็นเรื่องดี เพราะเนื้อหาทั้งหมดด้านล่างนี้ตั้งอยู่บนพื้นฐานที่คุณสามารถเริ่มและหยุดโปรเจกต์ได้แล้ว

DNS ตามชื่อ service คือส่วนที่ผู้เริ่มต้นมักพลาด

บน network ที่ผู้ใช้กำหนดเอง Docker จะเรียกใช้ DNS server ในตัว ซึ่งแต่ละ container จะมองเห็นที่ 127.0.0.11 DNS นี้จะแปลงชื่อ service เป็น address ปัจจุบันของ container ดังนั้น web จึงเชื่อมต่อไปยัง database ที่ hostname db และพอร์ต 5432 ได้โดยไม่ต้องตั้งค่าใด ๆ

docker compose exec web getent hosts db

คำสั่งนี้จะแสดงบรรทัดลักษณะ 172.18.0.2 db หากไม่แสดงผลใด ๆ แสดงว่า service ทั้งสองไม่ได้อยู่บน network เดียวกัน

ข้อผิดพลาดที่แทบทุกคนเคยทำอย่างน้อยครั้งหนึ่งคือการใช้ localhost ใน config ของแอปพลิเคชัน ภายใน container ค่า localhost หมายถึง container นั้นเอง ไม่ใช่ host และไม่ใช่ service อื่น Postgres client จะแจ้งเรื่องนี้อย่างชัดเจน:

could not connect to server: Connection refused
	Is the server running on host "localhost" (127.0.0.1) and accepting
	TCP connections on port 5432?

connection string ที่ควรใช้คือ postgresql://postgres:example@db:5432/postgres ส่วน host คือชื่อ service

มีรายละเอียด 2 ข้อที่ช่วยลดเวลาแก้ปัญหาในภายหลัง ชื่อจะถูกแปลงไปยังสิ่งที่กำลังทำงานอยู่ในขณะนั้น ดังนั้น docker compose up -d --scale web=3 จึงให้ชื่อเดียวที่มี 3 address และ client ที่ cache DNS ไว้ตลอดจะยังชี้ไปยัง container ที่ตายแล้ว นอกจากนี้ network แบบเก่า bridge ซึ่งถูกใช้โดย docker run แบบไม่มี --network ไม่สามารถแปลงชื่อ container ได้เลย container บน network นี้จะค้นหากันได้เฉพาะด้วย IP address และจะค้นหา hostname ภายนอกผ่านสำเนาของ /etc/resolv.conf จาก host นี่คือเหตุผลที่คำแนะนำเรื่อง container links จากปี 2016 ไม่ตรงกับสิ่งที่พบในปัจจุบัน

คุณไม่จำเป็นต้องใช้ ports: เพื่อเชื่อมต่อสองบริการเข้าด้วยกัน

ports: จะเผยแพร่พอร์ตของคอนเทนเนอร์ไปยังโฮสต์ ซึ่งใช้สำหรับทราฟฟิกที่มาจากภายนอก Docker เท่านั้น โดยไม่มีผลใดๆ ต่อทราฟฟิกที่สื่อสารระหว่างบริการด้วยกันเอง ซึ่งสามารถทำงานได้อยู่แล้วผ่านพอร์ตทุกช่วงบนเครือข่ายของโปรเจกต์

ดังนั้น ports: - "5432:5432" ที่หลายคนเพิ่มเข้าไปในบริการฐานข้อมูลจึงไม่มีประโยชน์และส่งผลเสียจริง เพราะเป็นการเปิดเผย Postgres บนอินเทอร์เฟซสาธารณะของเซิร์ฟเวอร์ ให้ลบออกเสีย หากคุณต้องการเข้าถึงฐานข้อมูลจากแล็ปท็อปเพื่อทำการย้ายข้อมูล ให้ผูกไว้กับ loopback ด้วย "127.0.0.1:5432:5432" แล้วเข้าถึงผ่าน SSH tunnel แทน ความแตกต่างระหว่าง listening socket, พอร์ตที่เผยแพร่ และกฎของไฟร์วอลล์ ได้รับการอธิบายไว้ใน วิธีการทำงานของพอร์ตและบริการที่รอรับการเชื่อมต่อบน Linux

expose: เป็นเพียงเอกสารประกอบภายใต้ Compose เท่านั้น มันไม่ได้เปิดการเชื่อมต่อใดๆ เนื่องจากไม่มีการปิดกั้นการสื่อสารระหว่างคอนเทนเนอร์ที่อยู่บนเครือข่ายเดียวกันอยู่แล้ว

เมื่อใดควรใช้ network_mode host และมีต้นทุนอย่างไร

โหมด host จะยกเลิก network namespace ของ container และให้ process ใช้ interface ของ host โดยตรง

services:
  probe:
    image: alpine:3.20
    network_mode: host
    command: sleep infinity

มีเหตุผลที่เหมาะสมสำหรับการใช้งานโหมดนี้ process ที่ต้องเห็น broadcast หรือ multicast traffic บน network ภายใน เช่น การค้นหาอุปกรณ์สำหรับ media server หรือ home automation hub จะไม่สามารถเห็น traffic เหล่านี้จากหลัง bridge ได้ เพราะ bridge ไม่ส่งต่อ traffic ดังกล่าวไปยัง container monitoring agent ที่อ่าน interface counter ของ host ก็จำเป็นต้องใช้ interface ของ host เช่นกัน นอกจากนี้ยังข้ามขั้นตอน address translation ซึ่งมีความสำคัญเมื่อมี packet rate สูง

ต้นทุนมีดังนี้

ports: จะไม่ทำงาน Docker จะแจ้งเตือนว่า published port จะถูกละทิ้งเมื่อใช้ host network mode และ container จะ bind ตามที่ process ของ container bind ไว้ container แบบ host mode 2 ตัวที่ต้องการใช้พอร์ต 8080 จะชนกัน และตัวที่สองจะหยุดทำงานพร้อม bind: address already in use

การแปลงชื่อด้วยชื่อ service จะหายไปทั้ง 2 ทิศทาง container ไม่ได้อยู่บน project network จึงไม่สามารถแปลง db ได้ และ service อื่นก็ไม่สามารถแปลงชื่อของ container นี้ได้เช่นกัน อย่างไรก็ตาม container ยังเชื่อมต่อไปยัง service เหล่านั้นผ่านพอร์ตที่ publish บน host ได้ โดยปกติจะใช้ 127.0.0.1 บน Linux ยังสามารถเชื่อมต่อไปยัง bridge container ได้โดยตรงที่ IP address ของ container และพอร์ตที่กำลัง listen อยู่ เนื่องจาก host สามารถเข้าถึง container บน bridge network ของตนเองได้โดยตรง และ host mode container ใช้ network stack เดียวกับ host address เหล่านี้จะเปลี่ยนเมื่อสร้าง container ใหม่ ดังนั้นพอร์ตที่ publish บน loopback จึงเป็นเส้นทางที่คงที่กว่า

การแยก network จะหายไป process ที่ bind 0.0.0.0 ภายใน host mode container จะ listen อยู่บนทุก interface ของ server รวมถึง interface สาธารณะ เช่นเดียวกับ package ที่ติดตั้งด้วย apt ข้อดีอย่างหนึ่งคือ traffic นี้จะผ่าน input path ตามปกติ ดังนั้นกฎของ UFW จึงมีผลกับ traffic นี้ ซึ่งไม่เหมือนกับ published port

Host mode เป็นฟีเจอร์ของ Linux Docker Engine Docker Desktop รองรับฟีเจอร์นี้ตั้งแต่ version 4.34 เป็นต้นไป และต้องเปิดใช้งานก่อน โดยมีข้อจำกัดเพิ่มเติมว่า container ไม่สามารถ bind host IP address ได้ และรองรับเฉพาะ TCP กับ UDP หากทีมของคุณครึ่งหนึ่งใช้ Linux server และอีกครึ่งหนึ่งใช้ Docker Desktop ไฟล์เดียวกันอาจทำงานแตกต่างกัน

ให้เลือกใช้ host mode เมื่อจำเป็นต้องใช้ interface ของ host อย่าใช้เพื่อแก้ปัญหาการเชื่อมต่อ เพราะโดยทั่วไปจะเปลี่ยนปัญหาหนึ่งให้เป็นปัญหาที่แก้ยากกว่า

การเชื่อมต่อโปรเจกต์ Compose สองโปรเจกต์เข้ากับเครือข่ายภายนอก

เครือข่ายที่สร้างโดยโปรเจกต์หนึ่งจะไม่สามารถมองเห็นได้จากอีกโปรเจกต์หนึ่ง นี่คือเหตุผลที่ reverse proxy ใน proxy/compose.yaml ไม่สามารถมองเห็นแอปพลิเคชันใน app/compose.yaml ได้ แม้ว่าจะอยู่บนเซิร์ฟเวอร์เดียวกันก็ตาม วิธีแก้ไขคือการใช้เครือข่ายที่ไม่มีโปรเจกต์ใดเป็นเจ้าของ

สร้างเครือข่ายขึ้นมาหนึ่งครั้งด้วยตนเอง:

docker network create edge

จากนั้นประกาศเครือข่ายดังกล่าวว่าเป็น external ในแต่ละโปรเจกต์ สำหรับฝั่ง proxy:

services:
  proxy:
    image: traefik:v3.1
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - edge

networks:
  edge:
    name: edge
    external: true

สำหรับฝั่งแอปพลิเคชัน:

services:
  app:
    image: nginx:1.27
    networks:
      - edge
      - internal
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example
    networks:
      - internal

networks:
  edge:
    name: edge
    external: true
  internal:

external: true สั่งให้ Compose เชื่อมต่อเข้ากับเครือข่ายที่มีอยู่เดิมแทนที่จะสร้างเครือข่ายใหม่ และให้คงเครือข่ายนั้นไว้เมื่อใช้คำสั่ง docker compose down คีย์ name: ที่แยกออกมามีความสำคัญมากกว่าที่เห็น: หากไม่มีคีย์นี้ Compose จะมองหาเครือข่ายที่ชื่อ edge โดยตรง แต่เมื่อมีคีย์นี้ คุณสามารถตั้งชื่อเครือข่ายในไฟล์ของคุณอย่างหนึ่ง และใช้ชื่ออื่นบนโฮสต์ได้

หากเครือข่ายไม่มีอยู่จริง Compose จะปฏิเสธการเริ่มทำงานและแจ้งว่าเครือข่ายถูกประกาศว่าเป็น external แต่ไม่พบเครือข่ายดังกล่าว คุณต้องสร้างเครือข่ายก่อนเสมอ

สังเกตสิ่งที่ไฟล์แอปพลิเคชันทำกับ internal ฐานข้อมูลจะอยู่บนเครือข่ายเฉพาะของโปรเจกต์นั้นเท่านั้น ดังนั้น proxy จึงไม่สามารถเข้าถึงฐานข้อมูลได้ และมีเพียง app เท่านั้นที่เข้าถึงได้ การเพิ่ม internal: true ภายใต้เครือข่ายจะช่วยเพิ่มความปลอดภัยโดยการตัดเส้นทางออกสู่โลกภายนอกทั้งหมด นี่เป็นค่าเริ่มต้นที่ดีสำหรับฐานข้อมูล แต่มีข้อควรทราบก่อนตั้งค่าคือ คอนเทนเนอร์ที่อยู่บนเครือข่ายภายในจะไม่สามารถดาวน์โหลดสิ่งใดได้ ดังนั้น entrypoint ที่รัน apt-get update หรือ pip install ในระหว่างการเริ่มต้นระบบจะค้างและล้มเหลวเนื่องจากหมดเวลา (timeout)

สำหรับตัวอย่างการตั้งค่าที่สมบูรณ์พร้อมกฎการกำหนดเส้นทางและใบรับรอง โปรดดู การรันแอปพลิเคชันหลายตัวหลัง Traefik instance เดียวกัน

พอร์ตที่ถูกเผยแพร่ข้ามการทำงานของ UFW

นี่คือส่วนหนึ่งของระบบเครือข่ายใน Compose ที่อาจกลายเป็นเหตุการณ์ด้านความปลอดภัยได้ คุณเผยแพร่พอร์ต (publish) ตรวจสอบว่า UFW ทำงานอยู่และปฏิเสธการเชื่อมต่อทั้งหมดที่ไม่ใช่ SSH แต่บริการนั้นยังคงสามารถเข้าถึงได้จากอินเทอร์เน็ต

sudo ufw status
curl http://203.0.113.10:8080

UFW แจ้งว่าพอร์ตถูกบล็อกไว้ แต่ curl กลับแสดงหน้าเว็บออกมาได้ตามปกติ ไม่มีสิ่งใดเสียหาย Docker เขียนกฎการแปลงที่อยู่ (NAT) และการส่งต่อข้อมูลลงใน iptables โดยตรง ทำให้ทราฟฟิกที่มุ่งหน้าไปยังพอร์ตของคอนเทนเนอร์ที่ถูกเผยแพร่จะถูกส่งต่อไปยังคอนเทนเนอร์แทนที่จะส่งมายังโฮสต์ ดังนั้นทราฟฟิกดังกล่าวจึงไม่ผ่านเชนที่ UFW จัดการสำหรับทราฟฟิกที่มุ่งหน้ามายังโฮสต์โดยตรง นอกจากนี้ กฎของ Docker ยังถูกตรวจสอบก่อนกฎของ UFW อีกด้วย

วิธีแก้ไขระยะสั้นคือการเผยแพร่พอร์ตเฉพาะในจุดที่จำเป็นเท่านั้น:

    ports:
      - "127.0.0.1:8080:80"

การทำเช่นนี้จะผูกฝั่งโฮสต์เข้ากับ loopback ทำให้พอร์ตสามารถเข้าถึงได้จากตัวเซิร์ฟเวอร์เอง หรือผ่าน SSH tunnel เท่านั้น และไม่สามารถเข้าถึงจากที่อื่นได้ ให้วางจุดเชื่อมต่อสาธารณะไว้หลัง reverse proxy ที่เผยแพร่พอร์ต 80 และ 443 อย่างตั้งใจ คำอธิบายฉบับเต็ม รวมถึงเชน DOCKER-USER สำหรับกรณีที่คุณจำเป็นต้องกรองพอร์ตที่เผยแพร่อยู่ สามารถดูได้ที่ เหตุผลที่ Docker เผยแพร่พอร์ตโดยข้าม UFW และวิธีแก้ไข

วิธี debug ด้วย 4 คำสั่ง

เริ่มจากตรวจว่าแต่ละ container อยู่บน network ใดจริง:

docker network inspect shop_default

block Containers จะแสดง container ที่เชื่อมต่ออยู่ทั้งหมดพร้อม address ของแต่ละรายการ หาก service ไม่อยู่ในรายการ แสดงว่า service นั้นอยู่บน network อื่น ใช้ host mode หรือไม่ได้ทำงานอยู่

ทดสอบการแปลงชื่อจาก throwaway container ที่เชื่อมต่อกับ network เดียวกัน วิธีนี้ไม่จำเป็นต้องมีเครื่องมือภายใน image ของคุณเอง:

docker run --rm --network shop_default busybox nslookup db
docker run --rm --network shop_default busybox nc -zv db 5432

nslookup ที่ล้มเหลวชี้ไปที่ปัญหาการแปลงชื่อหรือการเป็นสมาชิกของ network หาก nslookup สำเร็จขณะที่ nc ล้มเหลว แสดงว่าชื่อและ network ถูกต้อง และปัญหาอยู่ที่การเชื่อมต่อเอง หาก nc รายงาน Connection refused สาเหตุที่พบบ่อยคือ service ไม่ได้ listen อยู่บนพอร์ตนั้น หรือกำลัง listen อยู่บน 127.0.0.1 ภายใน container ของตนเองแทนที่จะเป็น 0.0.0.0 กรณีหลังพบได้บ่อยกับ development server และต้องแก้ที่ bind address ของแอปพลิเคชัน ไม่ใช่ที่ Docker หาก nc ค้างและ timeout แทน ให้ตรวจหาสิ่งที่กำลังทิ้ง traffic ระหว่างทาง เช่น firewall rule หรือ container ที่ถูก pause หรือไม่ตอบสนอง

ยังมีปัญหาอีกกรณีหนึ่งที่ดูเหมือนเป็น bug ของ Docker หาก container ติดต่อกันได้ แต่ไม่สามารถเชื่อมต่อไปยังเครื่องบน office หรือ VPN network ได้ แสดงว่า Docker subnet น่าจะซ้อนทับกับ network ดังกล่าว โดยค่าเริ่มต้น Docker จะจัดสรรจาก 172.17.0.0/16 ขึ้นไป ให้ย้าย pool ใน /etc/docker/daemon.json:

{
  "default-address-pools": [
    { "base": "10.200.0.0/16", "size": 24 }
  ]
}

จากนั้นเรียกใช้ sudo systemctl restart docker และสร้าง network ที่ได้รับผลกระทบขึ้นใหม่ เนื่องจาก network ที่มีอยู่แล้วจะยังคงใช้ subnet ที่กำหนดไว้ตอนสร้าง

FAQ

เหตุใดคอนเทนเนอร์ของฉันจึงไม่สามารถติดต่อกันผ่านชื่อเซอร์วิสได้?

คอนเทนเนอร์เหล่านั้นไม่ได้อยู่บนเครือข่ายเดียวกัน Compose จะนำทุกเซอร์วิสไปไว้บน <project>_default โดยอัตโนมัติ แต่ทันทีที่คุณเพิ่มรายการ networks: ให้กับเซอร์วิส รายการนั้นจะกลายเป็นชุดเครือข่ายทั้งหมดสำหรับเซอร์วิสนั้น และค่าเริ่มต้นจะไม่ถูกนำมาใช้โดยอัตโนมัติอีกต่อไป ให้รันคำสั่ง docker network inspect <network> และตรวจสอบว่าคอนเทนเนอร์ทั้งสองปรากฏอยู่ในบล็อก Containers นอกจากนี้ ให้ตรวจสอบว่าไม่มีเซอร์วิสใดใช้ network_mode: host เนื่องจากคอนเทนเนอร์ที่อยู่ในโหมด host จะไม่ได้อยู่บนเครือข่าย Docker ใดๆ และไม่สามารถแก้ไขชื่อเซอร์วิสได้

ฉันจำเป็นต้องเปิดพอร์ตเพื่อให้เซอร์วิสหนึ่งติดต่อกับอีกเซอร์วิสหนึ่งหรือไม่?

ไม่จำเป็น บนเครือข่ายของ Compose ทุกพอร์ตของทุกคอนเทนเนอร์สามารถเข้าถึงได้โดยคอนเทนเนอร์อื่นๆ ที่อยู่บนเครือข่ายเดียวกัน ports: มีไว้เพื่อเปิดให้คอนเทนเนอร์รับทราฟฟิกจากภายนอก Docker เท่านั้น ส่วน expose: เป็นเพียงการระบุเอกสารประกอบ การเปิดพอร์ตฐานข้อมูลเป็นนิสัยที่พบบ่อยและมีความเสี่ยงสูง เนื่องจากเป็นการนำฐานข้อมูลไปวางไว้บนอินเทอร์เฟซสาธารณะของเซิร์ฟเวอร์คุณ

ความแตกต่างระหว่างเครือข่ายแบบ bridge และ host คืออะไร?

Bridge จะให้เนมสเปซเครือข่ายและที่อยู่ของตัวเองแก่คอนเทนเนอร์บนสวิตช์เสมือน พร้อมการแก้ไขชื่อระหว่างคอนเทนเนอร์โดยอัตโนมัติและการแปลทราฟฟิกขาออก ส่วน Host จะให้คอนเทนเนอร์ใช้สแต็กเครือข่ายของโฮสต์โดยตรง: ไม่มีที่อยู่แยกต่างหาก ไม่มีการแก้ไขชื่อผ่านชื่อเซอร์วิส ไม่มีการเปิดพอร์ต และไม่มีการแยกส่วนจากผู้ฟัง (listener) อื่นๆ บนโฮสต์ Bridge เป็นค่าเริ่มต้นและเป็นตัวเลือกที่เหมาะสมที่สุด เว้นแต่ว่าโปรเซสของคุณจำเป็นต้องใช้อินเทอร์เฟซของโฮสต์โดยตรง

ฉันจะเชื่อมต่อคอนเทนเนอร์จากไฟล์ Compose สองไฟล์ที่แตกต่างกันได้อย่างไร?

สร้างเครือข่ายที่ใช้ร่วมกันด้วย docker network create edge จากนั้นประกาศเครือข่ายดังกล่าวในไฟล์ทั้งสองด้วย external: true และเชื่อมต่อเซอร์วิสที่ต้องการสื่อสารกันเข้ากับเครือข่ายนั้น Compose จะไม่สร้างหรือลบเครือข่ายนี้ หากคุณข้ามขั้นตอนการสร้าง Compose จะปฏิเสธการทำงานและแจ้งว่าเครือข่ายถูกประกาศเป็นแบบ external แต่ไม่พบเครือข่ายดังกล่าว

เหตุใดคอนเทนเนอร์ของฉันจึงเข้าถึงได้จากอินเทอร์เน็ตทั้งที่ UFW บล็อกพอร์ตนั้นไว้?

เนื่องจากพอร์ตที่ถูกเปิดใช้งาน (published port) จะถูกจัดการโดยกฎการส่งต่อ (forwarding rules) ที่ Docker เพิ่มเข้าไปใน iptables กฎเหล่านั้นจะถูกตรวจสอบก่อนกฎของ UFW และทราฟฟิกที่ถูกส่งต่อจะไม่ผ่านเชนที่ UFW กรองอยู่แล้ว ให้ผูก (bind) ฝั่งโฮสต์เข้ากับ loopback ด้วย "127.0.0.1:8080:80" และวางบริการที่ต้องการเปิดเผยต่อสาธารณะไว้หลัง reverse proxy บนพอร์ต 80 และ 443 แทน

บทความนี้มีประโยชน์หรือไม่