Docker network
Problems
จากข้อก่อนหน้า เราเอา Nextjs เรียกผ่าน host.docker.internal ซึ่งมันต้องเรียก data ย้อนออกมาที่เครื่อง host ก่อนแล้วย้อนกลับเข้าไปที่ backend
ถ้าเราใช้ network เราจะทำให้ nextjs สามารถเรียกไปที่ backend ได้ตรงๆเลย
Knowing Docker Network
มาทำความรู้จักกับ network command กันก่อน
docker network ls
❯ docker network ls
NETWORK ID NAME DRIVER SCOPE
62490c6249ac bridge bridge local
f995a98564a2 host host local
13fa6f2ef770 none null local
จะเห็นว่ามี network อยู่ 3 ตัว networks เหล่านี้จะเป็นเหมือนวงแลนวงนึง ใครเชื่อมต่อเข้ามาที่วงแล้วนี้ก็จะมองเห็นกันเหมือนที่เครื่องคอมอยู่ในวงแลนเดียวกัน
- null -> container ไหนเชื่อมมาที่ none จะไม่ถูกเข้าถึงจากภายนอกได้เลย
- host -> ก็คือเครื่องเรานี่แหละ network เส้นนี้จะเชื่อมต่อกับ host นี่แหละ ในหนึ่งเครื่องจะมี host ได้แค่อันเดียว
- bride เป็นวงแลนเส้นนึง
Create Network
เราสามารถสร้าง network ได้ด้วย ซึ่งจะมี driver เป็น bridge ได้เท่านั้นนะ
จากตัวอย่างของเราก่อนหน้า เราก็จะเอา Next มาต่อเข้าที่ network ที่ชื่อว่า my_bridge1 แล้วก็เอา Backend มาต่อเข้าที่ network ที่ชื่อว่า my_bridge1 เช่นกัน
เราจะสร้าง network ใน docker ด้วยคำสั่ง
docker network create my_bridge1
❯ docker network ls
NETWORK ID NAME DRIVER SCOPE
62490c6249ac bridge bridge local
f995a98564a2 host host local
22fb86b854db my_bridge1 bridge local
13fa6f2ef770 none null local
Connect container to network
connect when run container
docker run --name next -p 3000:3000 --network my_bridge1 -d next
ตรวจสอบว่า network มี container อะไร connect อยู่บ้างด้วยคำสั่ง
docker inspect <network name>
❯ docker inspect my_bridge1
[
{
"Name": "my_bridge1",
"Id": "22fb86b854db4e238e58c34f5a2f172840f8cdc0d35fe2e0c7aa5868dd4f1004",
"Created": "2024-07-01T20:18:10.448458201+07:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.228.0/24",
"Gateway": "192.168.228.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"39324b32c57efd54ebc1f779ec804ab5e3940550f729d3bf1dda3c43a6c2ed0d": {
"Name": "next",
"EndpointID": "e1111b7573e1dce638ff18bb3ccb4374cae2b5d754a30bcd13d0521c6383f896",
"MacAddress": "02:42:c0:a8:e4:02",
"IPv4Address": "192.168.228.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
จะเห็นว่ามี next อยู่ในนั้นแล้ว
เหลือ Backend อีกตัวนึง
รอบนี้เราจะ start backend ก่อน แล้วเราจะ connect container เข้าไปที่ network ภายหลัง
docker run --name hono -p 3333:3333 -v ./uploads:/app/uploads -d hono
connect backend to network
docker network connect <network name> <container name>
docker network connect my_bridge1 hono
แล้ว inspect network ดูอีกครั้งหนึง
❯ docker inspect my_bridge1
[
{
"Name": "my_bridge1",
"Id": "22fb86b854db4e238e58c34f5a2f172840f8cdc0d35fe2e0c7aa5868dd4f1004",
"Created": "2024-07-01T20:18:10.448458201+07:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.228.0/24",
"Gateway": "192.168.228.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"39324b32c57efd54ebc1f779ec804ab5e3940550f729d3bf1dda3c43a6c2ed0d": {
"Name": "next",
"EndpointID": "e1111b7573e1dce638ff18bb3ccb4374cae2b5d754a30bcd13d0521c6383f896",
"MacAddress": "02:42:c0:a8:e4:02",
"IPv4Address": "192.168.228.2/24",
"IPv6Address": ""
},
"5fd7e837549bee5ba7d1f581c897bcd06f9ff3791ed030bd06c05bf5f1d2f1c9": {
"Name": "hono",
"EndpointID": "940da611fb052999b73cdef031c2ab8c7f083b7ad7e314a4e65774e0c55189d3",
"MacAddress": "02:42:c0:a8:e4:03",
"IPv4Address": "192.168.228.3/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
เหลือแค่มาแก้ next app ของเราให้เรียกไปที่ backend ผ่าน network
ให้ใส่ชื่อของ container ลงไปตรงๆเลย ถ้าอยู่ใน network เดียวกัน docker จะพาไปที่ container นั้นได้ถูกต้องเองเลย
fetch("http://hono:3333/users").then(
(res) => res.json() as Promise<{ users: { name: string; age: number }[] }>,
);
ก็ให้ build image ใหม่อีกรอบนึง แล้ว run ต่อไปเลยนะ
docker build -t next .
docker run --name next -p 3000:3000 --network my_bridge1 -d next
ลองเปิด browser ดูจะต้องไม่ error นะ
สุดท้ายก็จะได้ภาพแบบนี้