شبکه در Docker Compose
فصل 1 — شبکه در Docker چیست؟
وقتی چند کانتینر اجرا میکنی، آنها باید بتوانند:
- با هم حرف بزنند
- ولی هر چیزی نباشد به هر چیزی دسترسی داشته باشد
- معماریات امن و تمیز باشد
Docker دقیقاً مثل یک WiFi خصوصی برای کانتینرها شبکه ایجاد میکند.
هر کانتینر:
- یک IP میگیرد
- نامش به عنوان hostname شناخته میشود
- میتواند سرویسهای دیگر را با اسمشان صدا بزند
نام سرویس = hostname = آدرس شبکه داخلی
فصل 2 — رفتار پیشفرض Compose
اگر یک فایل Compose داشته باشی، Docker خودش یک شبکه میسازد:
myproject_default
و همه سرویسها داخل آن هستند.
مثال:
services:
api:
image: myapi
db:
image: postgres
در شبکه:
hostname: api → 172.x.x.x
hostname: db → 172.x.x.x
در کد API:
DB_HOST=db
تمام.
هیچ port mapping داخلی لازم نیست.
فصل 3 — ارتباط داخلی vs ارتباط بیرونی
| مفهوم | توضیح |
|---|---|
| Network | ارتباط کانتینر ←→ کانتینر |
| Ports | ارتباط بیرون ←→ کانتینر (مثلاً مرورگر → API) |
یعنی:
ports:
- "5432:5432"
فقط دسترسی از کامپیوترت به Postgres را میدهد، نه دسترسی کانتینرهای دیگر.
ارتباط کانتینرها فقط و فقط از طریق network است.
فصل 4 — ساختن شبکههای جداگانه (Isolation)
این از مهمترین بخشهاست.
شبیه خانه با دو منطقه:
- پذیرایی (مهمان فقط همین را میبیند)
- اتاق خواب (خصوصی)
در Docker:
services:
nginx:
networks:
- public
api:
networks:
- public
- private
db:
networks:
- private
networks:
public:
private:
نتیجه:
✔ nginx → api
✘ nginx → db
✔ api → db
معماری استاندارد وب دقیقاً همین است.
فصل 5 — Network Aliases (اسم مستعار شبکه)
این بخش برای load balancing یا داشتن نام مشترک برای چند سرویس استفاده میشود.
دو API داری:
services:
api1:
networks:
backend:
aliases:
- app
api2:
networks:
backend:
aliases:
- app
networks:
backend:
در شبکه Docker:
app → api1
app → api2
یعنی اگر یک سرویس بگوید:
curl http://app:3000
Docker یکی از این دو را انتخاب میکند.
مثل یک دامنه:
app.local → سرور A
app.local → سرور B
چند سرویس → یک hostname
فصل 6 — اتصال کانتینرها به چند شبکه (Dual-Homed)
گاهی یک سرویس باید روی ۲ شبکه باشد:
- backend (فقط برای API و DB)
- monitoring (مثلاً برای Prometheus)
مثال:
services:
api:
networks:
- backend
- monitoring
این یعنی API در هر دو شبکه عضو است و میتواند به هر دو گروه دسترسی داشته باشد.
این الگو برای reverse-proxy ها خیلی رایج است (nginx → frontend + backend).
فصل 7 — External Networks
وقتی دو پروژه کاملاً جدا میخواهند با هم حرف بزنند:
docker network create sharednet
Project A:
networks:
sharednet:
external: true
Project B:
networks:
sharednet:
external: true
الان کانتینرهای دو پروژه در یک شبکه مشترک هستند.
فصل 8 — Network Modes (کماستفاده ولی مهم)
سه حالت مهم:
bridge (پیشفرض)
جداسازی کامل بین کانتینرها
کانتینرها فقط از طریق شبکه Docker با هم حرف میزنند.
host
کانتینر = خود سیستم
بدون ایزولهسازی
پورتها به اشتراک گذاشته میشوند
معمولاً برای Redis یا Elasticsearch که latency حساس دارند.
none
کاملاً بدون شبکه
کاملاً ایزوله
تقریباً هیچوقت استفاده نمیشود جز امنیت شدید.
فصل 9 — Debug شبکه
دستورات مهم:
docker network ls
نمایش همه شبکهها
docker network inspect <network-name>
نمایش لیست کانتینرهای عضو، IP ها، alias ها
docker exec -it <container> sh
ping api
کانتینر به کانتینر دیگر ping میزند.
فصل 10 — معماری شبکه حرفهای برای پروژه واقعی
یک الگوی واقعی:
frontend-network:
nginx
frontend
backend-network:
nginx
api
auth-service
cache
private-network:
api
auth-service
postgres
redis
monitor-network:
prometheus
grafana
exporter
فواید:
- frontend نمیتواند مستقیم DB را ببیند
- monitoring به همه چیز دسترسی دارد
- API چند کانال دارد
- امنیت + معماری تمیز + توسعهپذیری
در 5 خط کل روح شبکه Docker این است:
- هر سرویس یک hostname است.
- فقط سرویسهایی که در یک شبکه مشترک هستند همدیگر را میبینند.
- ports فقط برای ارتباط با خارج از Docker هستند.
- alias اجازه میدهد چند سرویس با یک نام دیده شوند.
- با شبکههای جداگانه میتوان معماری تمیز، امن و قابل توسعه ساخت.