پرش به مطلب اصلی

استقرار با Dockerfile

ویدیو: استقرار با Dockerfile سفارشیplaceholder — ویدیو را اینجا جایگزین کنید

ابرکلیک از استقرار مستقیم ظرف‌های نرم‌افزاری (Docker Containers) پشتیبانی می‌کند. اگر پروژه شما شامل فایل Dockerfile در ریشه مخزن باشد، سیستم بیلد ابرکلیک آن را شناسایی کرده و فرآیند بیلد را از روی آن اجرا می‌کند.


شروع سریع (Quick Start)

کافی است فایل Dockerfile خود را آماده کرده و دستور زیر را اجرا کنید:

abrclick deploy

پس از اجرای دستور، سیستم کارهای زیر را به‌صورت خودکار انجام می‌دهد:

  1. کدها را به سیستم بیلد ارسال کرده و تصویر کانتینر را با ابزار BuildKit می‌سازد.
  2. کانتینر نهایی را به ریجستری داخلی (Harbor) ارسال می‌کند.
  3. برنامه شما را روی پادهای کوبرنتیز مستقر می‌کند.

اصول پیشنهادی برای نوشتن Dockerfile

برای کارایی بالا، سرعت در دیپلوی‌های بعدی و حفظ امنیت، رعایت الگوهای زیر توصیه می‌شود:

۱. استفاده از بیلد چندمرحله‌ای (Multi-stage Builds)

این الگو حجم کانتینر نهایی شما را کاهش داده و مانع از انتشار فایل‌های بیلد اضافی روی کانتینر پروداکشن می‌شود:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# گام دوم: کانتینر زمان اجرا (Runtime Stage)
FROM node:20-alpine
WORKDIR /app
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
RUN npm ci --only=production
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]

۲. امنیت و دسترسی کاربر غیر ریشه (Non-root User)

اجرای فرآیندها با کاربر root داخل کانتینر خطرات امنیتی دارد. همیشه یک کاربر کم‌سطح بسازید و فرآیندها را تحت آن کاربر اجرا کنید:

# ایجاد گروه و کاربر غیراصل
RUN addgroup -g 1001 -S appuser && adduser -S appuser -u 1001
USER appuser

۳. بررسی سلامت (Health Checks)

مشخص کنید که کانتینر شما چطور باید بررسی سلامت شود تا کوبرنتیز پادهای خراب را شناسایی کرده و جایگزین کند:

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"

۴. پورت کانتینر (EXPOSE)

حتماً پورتی که برنامه شما روی آن گوش می‌دهد را مشخص کنید. توجه داشته باشید متغیر محیطی PORT به‌طور خودکار توسط ابرکلیک تزریق خواهد شد:

EXPOSE 3000

مدیریت متغیرهای محیطی و شبکه

متغیرهای محیطی در زمان اجرا (Runtime) به داخل کانتینر شما تزریق خواهند شد. در کدهای خود می‌توانید به راحتی به آن‌ها دسترسی داشته باشید:

const port = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;

برای تنظیم متغیرهای محیطی جدید از داشبورد یا ابزار CLI استفاده کنید:

abrclick env set PORT 3000
abrclick env set DATABASE_URL "postgresql://..."

بهینه‌سازی حجم کانتینر (Size Optimization)

کاهش لایه‌های بیلد (Minimize Layers)

هر دستور RUN یک لایه جدید و سنگین در داکربیلد ایجاد می‌کند. دستورات مرتبط را با کاراکتر && ادغام کنید:

# ✗ شیوه نادرست: ایجاد چندین لایه اضافی
RUN apt-get update
RUN apt-get install -y git
RUN apt-get clean

# ✓ شیوه درست: ادغام در یک لایه و پاک‌سازی کش در همان گام
RUN apt-get update && apt-get install -y git && apt-get clean && rm -rf /var/lib/apt/lists/*

ساخت فایل .dockerignore

برای جلوگیری از ارسال پوشه‌های سنگین محلی (مانند node_modules یا فایل‌های توکن شخصی) به سرور بیلد، یک فایل با نام .dockerignore در ریشه پروژه خود بسازید:

node_modules
npm-debug.log
.git
.env
.env.local
*.md
tests
coverage

دسترسی به وابستگی‌های خصوصی (Private Dependencies)

اگر فایل Dockerfile شما برای دیپلوی نیاز به دانلود پکیج‌های خصوصی (مثلاً توکن خصوصی npm) دارد، می‌توانید آن توکن را به شکل بیلد سکرت ایمن ارسال کنید تا روی داکربیلد سوار شود:

abrclick deploy --secret npm-token=your_token_here

سپس در فایل Dockerfile خود به شکل زیر آن را فراخوانی کنید تا در بیلد نهایی کانتینر اثری از توکن شما باقی نماند:

RUN --mount=type=secret,id=npm-token \
npm config set //registry.npmjs.org/:_authToken=$(cat /run/secrets/npm-token) && \
npm ci

آینه‌سازی خودکار مخازن (Automatic Mirroring)

زیرساخت ابرکلیک در دیتاسنتر داخلی میزبانی می‌شود و دسترسی مستقیم به مخازن عمومی اینترنت (مانند registry.npmjs.org، pypi.org، deb.debian.org و dl-cdn.alpinelinux.org) در محیط بیلد وجود ندارد. سیستم بیلد به‌صورت خودکار فایل Dockerfile شما را پیش‌پردازش کرده و مدیران بسته (npm, pip, go, composer, apt, apk) را از طریق آینه داخلی ابرکلیک هدایت می‌کند. این کار شفاف انجام می‌شود و نیازی به تغییر در Dockerfile شما ندارد.

این پیش‌پردازش هوشمند است:

  • متغیرهای محیطی شما در اولویت هستند. اگر خودتان ENV NPM_CONFIG_REGISTRY=... یا مشابه آن را تعریف کرده باشید، ابرکلیک آن را بازنویسی نمی‌کند.
  • مخازن سفارشی دست‌نخورده می‌مانند. فقط میزبان‌های عمومی شناخته‌شده بازنویسی می‌شوند؛ مخزن اختصاصی شما (RUN echo "deb https://mycorp...") لمس نخواهد شد.

غیرفعال‌سازی (Opt-out)

اگر آینه‌سازی خودتان را مدیریت می‌کنید و می‌خواهید Dockerfile کاملاً بدون تغییر باقی بماند، این نشانه را در هر جای فایل قرار دهید:

# abrclick:no-mirror

با وجود این نشانه، ابرکلیک فایل شما را بایت‌به‌بایت دست‌نخورده رها می‌کند.

توجه

با غیرفعال‌سازی آینه‌سازی، مسئولیت دسترسی به بسته‌ها بر عهده شماست. از آنجا که محیط بیلد به مخازن عمومی اینترنت دسترسی ندارد، باید مسیر جایگزینی برای دریافت وابستگی‌ها فراهم کنید (مثلاً استفاده از همان آینه داخلی به‌صورت دستی).


بهینه‌سازی کش لایه‌ها (Layer Caching)

ابزار BuildKit لایه‌ها را به‌صورت هوشمند کش می‌کند. برای استفاده بهینه از سیستم کش:

  • دستوراتی که به‌ ندرت تغییر می‌کنند (مانند نصب ابزارها و پکیج‌ها) را در لایه‌های ابتدایی قرار دهید.
  • فایل‌هایی که همواره دستخوش تغییر می‌شوند (کدهای سورس پروژه) را در لایه‌های پایانی کپی کنید.
# ✓ مثال بهینه: اول دریافت پکیج‌ها و سپس کپی کدهای اصلی
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .

مشاهده لاگ‌ها

برای بررسی لاگ‌های برنامه Docker خود، از دستور زیر استفاده کنید:

abrclick logs <app>

این دستور لاگ‌های خروجی کانتینر (stdout/stderr) را به‌صورت زنده نمایش می‌دهد. لاگ‌های بیلد نیز در حین اجرای abrclick deploy استریم می‌شوند.

همچنین می‌توانید لاگ‌ها را از داشبورد مشاهده کنید: وارد صفحه برنامه شوید و بر روی تب لاگ‌ها کلیک کنید.

نکته فنی

لاگ‌های سالم بستگی به برنامه شما دارد. برای برنامه‌های Node.js، پیام‌هایی مانند Server listening on :3000 را خواهید دید. برای Python، Booting worker از gunicorn. اگر لاگی دریافت نمی‌کنید، احتمالاً فرآیند اصلی کانتینر شروع نشده است.

برای اطلاعات بیشتر، راهنمای کامل لاگ‌ها را مطالعه کنید.


رفع خطاهای رایج

کانتینر بالا نمی‌آید / پورت اشتباه

علت: برنامه داخل کانتینر بر روی پورت ثابت یا آدرس 127.0.0.1 گوش می‌دهد. پلتفرم متغیر محیطی PORT را تزریق می‌کند و ترافیک را به آن پورت هدایت می‌کند. همچنین برنامه باید بر روی 0.0.0.0 گوش بدهد تا از خارج کانتینر قابل دسترسی باشد.

راه‌حل: مطمئن شوید برنامه شما از متغیر PORT استفاده می‌کند و بر روی 0.0.0.0 گوش می‌دهد. در Dockerfile خود EXPOSE را اضافه کنید:

EXPOSE 3000
CMD ["node", "server.js"]

و در کد برنامه:

const PORT = process.env.PORT || 3000;
app.listen(PORT, '0.0.0.0');

بیلد ناموفق / تصویر بیش از حد بزرگ

علت: تصویر نهایی حجم زیادی دارد یا فرآیند بیلد از محدودیت حافظه فراتر رفته است. همچنین حجم tarball آپلودی (سورس + context) نمی‌تواند بیشتر از ۱۰۰ مگابایت باشد.

راه‌حل: از multi-stage builds استفاده کنید تا حجم نهایی را کاهش دهید. همچنین فایل .dockerignore بسازید و پوشه‌های سنگین مانند node_modules را در آن قرار دهید:

node_modules
.git
.env
*.log

آینه خودکار مشکل ایجاد می‌کند / مخازن سفارشی

علت: بیلدپک ابرکلیک به‌صورت خودکار مخازن عمومی (مانند registry.npmjs.org یا deb.debian.org) را به آینه داخلی هدایت می‌کند. اگر شما از مخازن سفارشی یا پیکربندی خاص استفاده می‌کنید، این پیش‌پردازش ممکن است مشکل ایجاد کند.

راه‌حل: اگر می‌خواهید Dockerfile خود را بدون تغییر نگه دارید، نشانه # abrclick:no-mirror را در هر جای فایل اضافه کنید:

# abrclick:no-mirror
FROM node:20-alpine
# ...

توجه داشته باشید با این کار، مسئولیت دسترسی به وابستگی‌ها بر عهده شماست.

کانتینر با کاربر root اجرا می‌شود (خطای امنیتی)

علت: فرآیندهای داخل کانتینر به‌عنوان کاربر root اجرا می‌شوند که خطرات امنیتی دارد.

راه‌حل: یک کاربر غیر-root بسازید و از آن استفاده کنید:

RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
USER nodejs

OOMKilled / خطای حافظه

علت: فرآیند بیلد یا برنامه زمان اجرا از حافظه بیشتر از محدودیت تعریف‌شده (پیش‌فرض ۵۱۲Mi) استفاده کرده است.

راه‌حل: محدودیت حافظه برنامه را از طریق داشبورد یا تغییر پلن افزایش دهید. همچنین می‌توانید فرآیند بیلد را بهینه کنید (مثلاً استفاده از تصاویر پایه کوچک‌تر).