port และตัวแปร Environment
การเผยแพร่ port ด้วย -p
หัวข้อที่มีชื่อว่า “การเผยแพร่ port ด้วย -p”โดยค่าเริ่มต้น container ถูกแยกออกอย่างสมบูรณ์ — port ของตัวเองไม่สามารถเข้าถึงได้จาก host flag -p เผยแพร่ port โดยสร้าง mapping ระหว่าง port host กับ port container:
docker run -d -p 8080:80 nginx:alpineรูปแบบคือ -p <host-port>:<container-port> หลังจากคำสั่งนี้ การเปิด http://localhost:8080 ใน browser จะเข้าถึง port 80 ภายใน container
คุณสามารถเผยแพร่หลาย port ได้:
docker run -d -p 8080:80 -p 8443:443 nginx:alpineBind กับ IP เฉพาะของ host
หัวข้อที่มีชื่อว่า “Bind กับ IP เฉพาะของ host”# เข้าถึงได้เฉพาะจาก localhost ไม่ใช่จากเครือข่ายdocker run -d -p 127.0.0.1:8080:80 nginx:alpineการส่งตัวแปร environment ด้วย -e
หัวข้อที่มีชื่อว่า “การส่งตัวแปร environment ด้วย -e”Container อ่าน configuration จากตัวแปร environment ส่งด้วย -e:
docker run -d \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=myapp \ mysql:8แต่ละ -e กำหนดตัวแปรหนึ่งตัวภายใน container
การใช้ env file
หัวข้อที่มีชื่อว่า “การใช้ env file”สำหรับตัวแปรจำนวนมาก เก็บไว้ในไฟล์และใช้ --env-file:
MYSQL_ROOT_PASSWORD=secretMYSQL_DATABASE=myappMYSQL_USER=appMYSQL_PASSWORD=apppassdocker run -d --env-file .env mysql:8วิธีนี้ช่วยให้ secret ไม่ถูกบันทึกใน shell history
การตั้งชื่อ container ด้วย --name
หัวข้อที่มีชื่อว่า “การตั้งชื่อ container ด้วย --name”การตั้งชื่อที่คาดเดาได้ให้ container ทำให้ทุกคำสั่งถัดไปง่ายขึ้น:
docker run -d \ --name mysite \ -p 8080:80 \ nginx:alpineตอนนี้คุณสามารถใช้ mysite แทน random ID ในทุกคำสั่ง docker stop, docker logs, และ docker exec
นำมารวมกัน
หัวข้อที่มีชื่อว่า “นำมารวมกัน”docker run -d \ --name webserver \ -p 8080:80 \ -e NGINX_HOST=localhost \ nginx:alpine
# ตรวจสอบdocker pscurl http://localhost:8080# Run nginx with a port mapping and an env var
docker run -d \
--name webserver \
-p 8080:80 \
-e NGINX_HOST=localhost \
nginx:alpine
# Confirm the mapping
docker ps
# Fetch the default page (should return HTML)
curl -s http://localhost:8080 | head -5
# Inspect the env var inside the container
docker exec webserver env | grep NGINX
# Clean up
docker stop webserver && docker rm webserverข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
bind เฉพาะ 127.0.0.1 (-p 127.0.0.1:8080:80) | ปลอดภัยกว่า เข้าถึงได้เฉพาะจาก host เดียวกัน | เข้าถึงจากเครื่องอื่นในเครือข่ายไม่ได้ ต้องตั้งค่าเพิ่มถ้าจะแชร์ |
bind ทุก interface (-p 8080:80) | เข้าถึงได้จากเครือข่ายภายนอกทันที ใช้งานง่าย | เปิดกว้างเกินไป เสี่ยงถูกเข้าถึงโดยไม่ตั้งใจถ้าไม่มี firewall คุม |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- hardcode ค่า config อย่าง DB password หรือ host ไว้ใน Dockerfile ด้วย
ENVแทนที่จะส่งผ่าน-e/--env-fileตอนรัน ทำให้เปลี่ยนค่าทุกครั้งต้อง build image ใหม่ - commit ไฟล์
.envที่มี secret จริงเข้า git แทนที่จะใช้.env.exampleเป็น template - ลืมเผยแพร่ port ด้วย
-pแล้วสงสัยว่าทำไมcurlจาก host ถึงขึ้น connection refused ทั้งที่ container ทำงานปกติดี
💡 ตัวอย่างจากของจริง
Kubernetes ใช้ ConfigMap และ Secret เพื่อฉีดค่า configuration เข้า Pod ตอน runtime ที่เป็นแนวคิดเดียวกับ
-e/--env-fileของ Docker เพียงแต่จัดการแบบรวมศูนย์และหมุนเวียนค่าได้ในระดับ cluster