دوكر واحدة من أقوى الأدوات اللي غيّرت طريقة تطوير ونشر التطبيقات. بالكورس هذا رح نغطي أساسيات Docker - من التعامل مع الـ CLI، بناء أول image، لحتى نشغّل Express server متصل مع قاعدة بيانات.
المواضيع اللي رح نمر فيها:
روحوا على docker.com واضغطوا على Get Started. بتنزلوا Docker application حسب نظامكم إن كان Mac أو Windows أو Linux. بعد ما تنزلوا، افتحوا الـ terminal وتأكدوا إنه نازل:
docker version
إذا طلعت الـ version فكل شيء تمام. مهم كمان يكون عندكم على الأقل 4 جيجا رام فاضيين.
قبل ما نبدأ، خلينا نفهم كيف Docker شاغل بشكل عام:
| الجزء | الوظيفة |
|---|---|
| Client | الـ terminal - بتكتبوا فيه docker build، docker pull، docker run |
| Docker Host | القلب - بيدير كل العمليات عبر الـ Docker Daemon |
| Registry | مستودع الـ images، أشهرها Docker Hub |
أي تطبيق بيتكون من ثلاثة أجزاء أساسية:
هاي أكثر مشكلة شايعة - الكود بيشتغل على جهاز المطور بس لما يروح على staging أو production ما بيشتغل. في عنا كمان ثلاث environments رئيسية - development على جهازك local، staging لـ QA للتأكد من كل شيء شاغل، وproduction اللي بيشوفه الناس فعلياً. كل environment ممكن يحتاج configuration مختلفة، مثلاً database connection مختلفة.
فرضاً بدك تنزّل Llama للـ speech detection على جهازك. هالأمر بطلب منك Python ونسخ packages محددة، وممكن يتعارض مع اللي موجود عندك. Docker بيحل هالمشكلة بأنه يعزل كل بيئة عن الثانية.
اشترك في النشرة البريدية
دروس جديدة، مقالات، وأدوات مباشرة لبريدك.
الـ virtualization موجودة من زمان، بس للـ virtual machines مشاكل:
| Virtual Machine | Container | |
|---|---|---|
| OS | تحمل OS كاملة لكل VM | تشارك الـ kernel مع الـ host |
| Startup time | دقيقتين أو أكثر | ثواني |
| الحجم | ثقيلة | خفيفة |
| الـ isolation | كاملة | isolated على نفس الـ kernel |
الـ containers خفيفة لأنها ما بتحمل OS كاملة - بتعتمد على الـ kernel للـ host machine. الـ startup time ثواني بدل دقائق، وفيك تشغّل عشرات الـ containers على نفس الجهاز.
Docker هو اللي خلى الـ containers mainstream بعد ما كانت موجودة من زمان بس مش مشهورة.
| Image | Container | |
|---|---|---|
| التعريف | Blueprint أو template | التطبيق الشغال فعلياً |
| المثال | وصفة الطبخ | الأكل المطبوخ |
| العلاقة | instructions محفوظة | نتيجة تشغيل الـ image |
كل image فيها instructions لتشغيل التطبيق. كل ما بنعمل docker run لهاي الـ image بيتكون container جديد. فيكن تشغّلوا أكثر من container من نفس الـ image في نفس الوقت.
Docker Hub هو الـ registry الرسمي. أي مطور يقدر يرفع images بناها، وأي شخص ثاني يقدر يسحبها. لما تختاروا image للتنزيل، تأكدوا إنها:
لا تشغّلوا image مش واثقين من مصدرها على جهازكم.
# عرض كل الـ images الموجودة
docker image list
# سحب image من Docker Hub
docker pull node:latest
# حذف image
docker image remove <image-name>
# إضافة tag لـ image
docker image tag <image-id> <username>/my-app:v1
# رفع image على Docker Hub
docker image push <username>/my-app:v1# عرض الـ containers الشغالين حالياً
docker container ls
# عرض كل الـ containers (حتى المتوقفة)
docker container ls -a
# تشغيل container
docker run -it ubuntu:latest
# إيقاف container
docker container stop <container-id>رن Ubuntu:
docker run -it ubuntu:latestالـ flag -it يفتح لك interactive session. مجرد ما يشتغل بتلاقي نفسك جوات Linux environment كامل:
root@a3b2c1d4:/# ls
bin boot dev etc home lib ...رن Node.js:
docker run -it node:latestبتفوت مباشرةً على Node REPL وفيك تكتب JavaScript:
let message = "hello from docker"
console.log(message)
// hello from dockerلبناء image لتطبيقك، بتنشئ ملف اسمه Dockerfile بجذر المشروع:
FROM node:latest
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "start"]كل سطر بالـ Dockerfile له وظيفة محددة:
| الأمر | الوظيفة |
|---|---|
FROM | تحديد الـ base image |
WORKDIR | الـ working directory جوات الـ container |
COPY | نسخ ملفات من جهازك للـ container |
RUN | تشغيل أوامر وقت البناء |
CMD | الأمر اللي يشتغل لما يبدأ الـ container |
لبناء الـ image وتشغيلها:
docker build -t my-app .
docker run my-appلو شغّلت Express server جوات Docker وحاولت تفوت على localhost:3000 بالمتصفح، ما رح يشتغل. سبب المشكلة هو إن الـ application شغالة جوات الـ container، والـ port مش مكشوف على جهازك.
الحل هو عمل port mapping عبر الـ flag -p:
# -p <port على جهازك>:<port جوات الـ container>
docker run -p 3000:3000 my-appهلأ لما تفوت على localhost:3000 بالمتصفح، رح تلاقي الـ app شغالة.
فيكن كمان تعملوا mapping لـ port مختلف:
# الـ app على port 3000 جوات الـ container، بتوصلوها من 8080 على جهازكم
docker run -p 8080:3000 my-appلتشغيل تطبيق Node متصل مع MongoDB، محتاجين Docker Network تجمع الـ containers مع بعض.
1. إنشاء Docker Network:
docker network create app-network2. تشغيل MongoDB:
docker run -d \
--name mongo-test \
--network app-network \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongo:latest3. تشغيل Express Server:
docker run -d \
--name express-test \
--network app-network \
-p 3000:3000 \
my-express-appبما إن الـ containers على نفس الـ network، فالـ Express server يقدر يتصل بـ MongoDB عن طريق اسم الـ container (mongo-test) بدل localhost. يعني بالـ connection string تكتبوا mongodb://admin:password@mongo-test:27017.
بالإعداد الافتراضي، لما بتوقف الـ container كل الـ data اللي جواتها بتضيع. الحل هو استخدام Volumes:
docker run -d \
--name mongo-test \
--network app-network \
-v mongo-data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongo:latestالـ -v mongo-data:/data/db بتخلي Docker يحفظ الـ data بمكان على جهازك. هيكي الـ data بتضل محفوظة حتى بعد ما توقف الـ container وترجع تشغله.
بعد ما تبني image، فيك ترفعها على Docker Hub لحتى يقدر أي شخص يسحبها:
# تحقق من الـ image الموجودة
docker image list
# أضف tag بشكل صحيح
docker image tag <image-id> <username>/hello-node:latest
# ارفع الـ image
docker push <username>/hello-node:latestبعد ما ترفع، أي شخص يقدر يسحب الـ image:
docker pull <username>/hello-node:latestوهيكي عرفتوا أساسيات Docker كاملة - من فهم الـ architecture، لحتى بناء images ورفعها، وربط الـ containers مع بعض عبر Networks.