پرش به محتویات

آماده‌سازی VPS و Runtime

این Runbook پیش‌نیازهای VPS، مسیر برنامه، Secret PostgreSQL و دسترسی Pull از GHCR را آماده می‌کند.

مخاطب: DevOps/SRE دارای دسترسی sudo به VPS.

خارج از دامنه: نصب Docker، تغییر Stackهای موجود و آماده‌سازی Production.

۱. بررسی پیش‌نیازهای VPS

فرمان‌های زیر را روی VPS با کاربر دارای دسترسی sudo اجرا کنید:

docker version
docker compose version
docker network inspect dong_frontend
sudo -iu deploy docker version
  • docker version نسخه Client و Daemon را نشان می‌دهد و در دسترس بودن Docker Engine را بررسی می‌کند.
  • docker compose version وجود Compose v2 را تایید می‌کند. Workflow از docker compose up --wait استفاده می‌کند؛ بنابراین Compose باید به‌روز باشد.
  • docker network inspect dong_frontend وجود شبکه خارجی Reverse Proxy را بررسی می‌کند. inspect فقط اطلاعات می‌خواند و چیزی را تغییر نمی‌دهد.
  • sudo -iu deploy یک Login Shell واقعی با هویت کاربر deploy می‌سازد و فرمان بعدی را با همان کاربر اجرا می‌کند. این تست مهم است، چون Workflow نیز با همین کاربر Docker را اجرا می‌کند.

اگر فقط فرمان آخر با خطای Permission رد شد، دسترسی Docker را یک‌بار اضافه کنید و سپس Session کاربر deploy را کاملا بسته و دوباره باز کنید:

sudo usermod -aG docker deploy
  • usermod مشخصات کاربر را تغییر می‌دهد.
  • -G docker گروه تکمیلی docker را تعیین می‌کند.
  • -a به معنی Append است و مانع حذف سایر گروه‌های کاربر می‌شود؛ استفاده از -G بدون -a اشتباه و خطرناک است.
  • عضویت در گروه docker عملا دسترسی هم‌سطح Root ایجاد می‌کند؛ این دسترسی فقط باید به کاربر اختصاصی Deploy داده شود.

اگر شبکه dong_frontend وجود ندارد، شبکه مشابه جدید نسازید. ابتدا نام دقیق شبکه خارجی Reverse Proxy فعلی را پیدا کنید و همان نام را در PROXY_NETWORK قرار دهید.

۲. ساخت مسیرها، Secret و تنظیمات Runtime

مسیر برنامه و Secret را برای کاربر موجود deploy بسازید:

sudo install -d -m 0750 -o deploy -g deploy /opt/applications/tripylon-backend
sudo install -d -m 0700 -o deploy -g deploy /opt/applications/tripylon-backend/secrets
  • install -d دایرکتوری می‌سازد.
  • -m Permission را تعیین می‌کند؛ 0750 یعنی Owner دسترسی کامل، Group فقط Read/Execute و سایر کاربران بدون دسترسی هستند. مقدار 0700 مسیر Secret را فقط برای Owner قابل دسترسی می‌کند.
  • -o deploy -g deploy مالک و گروه را روی deploy قرار می‌دهد.
  • مسیر مطلق /opt/applications/tripylon-backend همان مقدار DEPLOY_PATH در GitHub است.

یک رمز تصادفی ۲۵۶ بیتی برای PostgreSQL بسازید:

sudo -u deploy sh -c 'umask 077; openssl rand -hex 32 > /opt/applications/tripylon-backend/secrets/postgres_password'
sudo chown root:65532 /opt/applications/tripylon-backend/secrets/postgres_password
sudo chmod 0440 /opt/applications/tripylon-backend/secrets/postgres_password
  • sudo -u deploy فرمان را بدون ساخت Login Shell و با هویت deploy اجرا می‌کند.
  • sh -c متن داخل کوتیشن را به‌عنوان یک فرمان Shell اجرا می‌کند.
  • umask 077 اجازه ایجاد فایل قابل خواندن برای Group یا Other را حذف می‌کند.
  • openssl rand -hex 32 تعداد ۳۲ بایت تصادفی را به ۶۴ کاراکتر Hex تبدیل می‌کند.
  • > خروجی را در فایل Secret می‌نویسد.
  • chown root:65532 مالک را Root و گروه را برابر GID فرایند غیر Root سرویس API قرار می‌دهد. Docker Compose فایل Secret میزبان را به‌صورت Bind Mount متصل می‌کند و UID/GID فایل حفظ می‌شود.
  • chmod 0440 فایل را فقط برای Root و گروه Runtime API خواندنی می‌کند. PostgreSQL در Entry Point با Root و API با GID برابر 65532 فایل را می‌خوانند.

تنظیمات غیرحساس Runtime را بسازید:

sudo -u deploy sh -c 'cat > /opt/applications/tripylon-backend/.env <<"EOF"
PROXY_NETWORK=dong_frontend
APP_ENV=development
LOG_LEVEL=info
DATABASE_NAME=tripylon
DATABASE_USER=tripylon
DATABASE_MIN_CONNS=2
DATABASE_MAX_CONNS=20
API_MEMORY_LIMIT=512m
API_CPU_LIMIT=1.0
POSTGRES_MEMORY_LIMIT=768m
POSTGRES_CPU_LIMIT=1.0
EOF
chmod 600 /opt/applications/tripylon-backend/.env'
  • cat > file فایل را با محتوای جدید می‌سازد یا جایگزین می‌کند.
  • <<"EOF" یک Here Document است و کوتیشن از گسترش ناخواسته متغیرهای Shell جلوگیری می‌کند.
  • این فایل رمز PostgreSQL یا Token ندارد؛ رمز فقط در secrets/postgres_password باقی می‌ماند.
  • محدودیت‌های CPU و Memory مقدار شروع هستند و پس از مشاهده Metrics واقعی باید بازتنظیم شوند.

PostgreSQL و API در Compose هیچ Port عمومی روی Host منتشر نمی‌کنند. Volume دیتابیس پایدار ولی محلی به VPS است؛ پیش از Production باید Backup رمزنگاری‌شده خارج از سرور و Restore Test واقعی اضافه شود.

۳. اجازه Pull از GHCR

اگر Package خصوصی است، برای یک GitHub Machine Account اختصاصی یک Classic Personal Access Token با Scope حداقلی read:packages بسازید. آن Account باید به Repository و Package دسترسی Read داشته باشد. در صورت فعال بودن SSO سازمان، Token را برای سازمان Authorize کنید.

روی VPS به‌صورت امن Login کنید:

sudo -iu deploy
read -r -s -p 'GHCR token: ' GHCR_TOKEN
printf '\n'
printf '%s' "$GHCR_TOKEN" | docker login ghcr.io --username YOUR_GITHUB_MACHINE_USER --password-stdin
unset GHCR_TOKEN
exit
  • read ورودی را می‌خواند؛ -r تفسیر Backslash را غیرفعال، -s نمایش Token را مخفی و -p Prompt را چاپ می‌کند.
  • printf '%s' Token را بدون Newline به ورودی فرمان بعدی می‌فرستد.
  • | خروجی فرمان سمت چپ را به Standard Input فرمان سمت راست متصل می‌کند.
  • docker login ... --password-stdin از قرار گرفتن Token در آرگومان Process و History جلوگیری می‌کند.
  • unset GHCR_TOKEN مقدار موقت را از Shell حذف می‌کند.
  • exit از Session کاربر deploy خارج می‌شود.

به‌جای YOUR_GITHUB_MACHINE_USER نام Machine Account را قرار دهید. Token توسعه‌دهنده شخصی یا Token دارای دسترسی Write روی VPS نگهداری نشود. برای Token تاریخ انقضا و یادآور Rotation تعیین کنید.

مرحله بعد: SSH Deploy و GitHub Environment