← شروع آموزش

WIUNIX ACADEMY

آموزش مانیتورینگ با Prometheus، Grafana و Docker Compose

صفحهٔ 2 از 6؛ مراحل قبلی و پیش‌نیازها را پیش از ادامه مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخه را انتخاب کن تا مراحل، دستورها و راه‌حل‌ها برای همان محیط نمایش داده شوند.

Ubuntu 26.10بررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

مقادیر نمونه را برای محیط خودت تنظیم کن؛ متن و دستورهای مرتبط با هم تغییر می‌کنند. رمز، کلید خصوصی و توکن وارد نکن. مقادیر فقط در همین زبانه نگهداری می‌شوند و به سرور یا لینک اشتراک‌گذاری فرستاده نمی‌شوند. پیش از اجرا، DNS، گواهی‌ها و سیاست شبکهٔ واقعی را بررسی کن.

آی‌پی، دامنه یا پورت مثال‌ها با محیط تو فرق دارد؟ دکمهٔ زیر را باز کن، مقادیر را تغییر بده و «اعمال در آموزش» را بزن؛ سپس دستورهای به‌روز‌شده را کپی کن.

تنظیم مقادیر برای محیط من11 مقدار قابل‌تغییر
03

قدم بعدی

Engine و افزونهٔ Compose را نصب کنید

بسته‌های رسمی را نصب کنید؛ دستور قدیمی docker-compose مبتنی بر Python مسیر این آموزش نیست. نسخهٔ پایدار بررسی‌شدهٔ Compose در ۲۰ اکتبر ۲۰۲۶ برابر 5.6.0 است؛ نسخهٔ بستهٔ APT می‌تواند بین توزیع‌ها متفاوت باشد. نصب از candidate پشتیبانی‌شدهٔ همان مخزن انجام می‌شود و نسخهٔ واقعی ثبت می‌شود؛ pin مشترک و ناموجود برای همهٔ توزیع‌ها فرض نشده است. Engine نگهداری‌شده و حداقل 28 و Compose جدید لازم است. عضویت ساده در گروه docker پیشنهاد نمی‌شود، چون عملاً اختیار root می‌دهد. عملیات daemon در ادامه با sudo انجام می‌شود.

Bash

سرور اختصاصی لینوکس؛ پوستهٔ Bash

sudo apt-get install --no-install-recommends docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl is-active docker
sudo docker version
sudo docker compose version
dpkg-query -W docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo docker network ls
sudo docker network inspect $(sudo docker network ls -q)
از کجا بدانم درست انجام شد؟

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

04

قدم بعدی

فقط پوشه‌های تازه و اختصاصی بسازید

این guard مسیر موجود و تودرتو را رد می‌کند، اما ایمنی symlink والد را ثابت نمی‌کند؛ والدها را پیش‌تر بررسی کنید. تنظیمات با root مدیریت می‌شود؛ دادهٔ پرومتئوس متعلق به UID/GID برابر 65534 و دادهٔ گرافانا متعلق به UID 472 و GID 0 است که در Compose صریح آمده‌اند. برای رفع مجوز، 777 یا اجرای سرویس با root به کار نبرید. دیسک محلی POSIX لازم است؛ TSDB پرومتئوس را روی NFS نگذارید.

Bash

سرور اختصاصی لینوکس؛ پوستهٔ Bash

sudo bash -eu <<'SETUP'
paths=('/srv/academy-monitor' '/srv/academy-monitor-backups')
[[ 'academy-monitor' =~ ^[a-z0-9][a-z0-9_-]*$ ]]
for a in "${paths[@]}"; do
  [[ "$a" = /* && "$a" != / && ! -e "$a" && ! -L "$a" ]]
  for b in "${paths[@]}"; do
    [[ "$a" = "$b" ]] && continue
    case "$a/" in "$b/"*) exit 1;; esac
  done
done
install -d -m 0755 '/srv/academy-monitor' '/srv/academy-monitor/config' '/srv/academy-monitor/config/targets' '/srv/academy-monitor/config/datasources' '/srv/academy-monitor/config/dashboards' '/srv/academy-monitor/dashboards'
install -d -m 0700 '/srv/academy-monitor/secrets' '/srv/academy-monitor-backups'
install -d -m 0750 -o 65534 -g 65534 '/srv/academy-monitor/prometheus-data'
install -d -m 0750 -o 472 -g 0 '/srv/academy-monitor/grafana-data'
SETUP
از کجا بدانم درست انجام شد؟

پوشه‌های تازه با مالکیت مشخص ساخته شده‌اند و دادهٔ نامرتبط ندارند.

05

قدم بعدی

ایمیج رسمی را با digest ثابت کنید

digestهای زیر فهرست چندمعماری نسخهٔ مشخص Prometheus 3.15.0 و Grafana OSS 13.2.4 را ثابت می‌کنند. مسیر OSS گرافانا اکنون grafana/grafana است و مخزن grafana-oss به‌روزرسانی نمی‌شود. tag نام خواناست؛ digest فایل واقعی را تعیین می‌کند. پیش از استفادهٔ بعدی، معماری و هشدارهای امنیتی سازنده را دوباره ببینید. HTTPS و digest، امضای مستقل یا تضمین نبود آسیب‌پذیری نیستند. مسیر آموزش فقط amd64 و arm64 لینوکس است و emulation پنهانی ندارد. دریافت ایمیج با خروجی شبکهٔ daemon انجام می‌شود، نه شبکهٔ داخلی سرویس‌ها.

Bash

سرور اختصاصی لینوکس؛ پوستهٔ Bash

sudo docker buildx imagetools inspect prom/prometheus:v3.15.0@sha256:efd719c99d83b060d9daefdcf00360461adf279f45ef5391f8d111892118753e
sudo docker buildx imagetools inspect grafana/grafana:13.2.4@sha256:dbbc38ea21103cefb50396340cd88afec779c7e070b0a7bf5a75b4ce46651d3f
از کجا بدانم درست انجام شد؟

digest و معماری بومی لینوکس با فهرست بررسی‌شده یکسان‌اند.

06

قدم بعدی

رمز اولیه را فقط در ویرایشگر محافظت‌شده وارد کنید

رمز قوی، یکتا و تازهٔ مدیر گرافانا را در یک خط در ویرایشگر محافظت‌شده بنویسید. رمز نباید در آرگومان دستور، فایل env، فیلد آموزش، Git، اسکرین‌شات یا لاگ ترمینال اشتراکی باشد. فایل فقط به گرافانا mount می‌شود. secret در Compose معمولی یک bind mount فایل محلی است و ذخیرهٔ رمزنگاری‌شدهٔ Swarm نیست؛ مجوز میزبان اهمیت دارد. remap کردن uid/gid/mode برای secret فایل‌محور انجام نمی‌شود. مالک root و گروه 0 با مجوز 0440 به گرافانای UID472/GID0 اجازهٔ خواندن فایل mountشده می‌دهد؛ والد 0700 منبع میزبان را محافظت می‌کند. این رمز فقط دیتابیس تازه را مقداردهی اولیه می‌کند و تغییر فایل، رمز مدیر موجود را عوض نمی‌کند.

Bash

سرور اختصاصی لینوکس؛ پوستهٔ Bash

sudo install -m 0600 /dev/null '/srv/academy-monitor/secrets/grafana-admin'
sudo nano '/srv/academy-monitor/secrets/grafana-admin'
sudo chown root:0 '/srv/academy-monitor/secrets/grafana-admin'
sudo chmod 0440 '/srv/academy-monitor/secrets/grafana-admin'
sudo test -s '/srv/academy-monitor/secrets/grafana-admin'
از کجا بدانم درست انجام شد؟

فایل رمز خالی نیست و بدون نمایش رمز، محافظت شده است.

07

قدم بعدی

فایل Compose را باز کنید

فایل تازه را باز کنید و پنل کامل بعدی را در آن بگذارید. فایل‌های bind باید پیش از اجرا واقعاً موجود باشند؛ نبودن فایل را با ساخت خودکار یک پوشه جایگزین نکنید.

Bash

سرور اختصاصی لینوکس؛ پوستهٔ Bash

sudo nano '/srv/academy-monitor/compose.yaml'
از کجا بدانم درست انجام شد؟

ویرایشگر برای فایل کامل YAML آماده است.

Compose؛ هویت، ذخیره‌سازی و جداسازی

فایل را کامل ذخیره کنید. شبکهٔ internal خروجی عادی اینترنت را می‌بندد؛ دریافت پلاگین، دیتاسورس خارجی، ایمیل و OAuth در این تمرین نداریم. این محدودیت، root میزبان یا همسایهٔ شبکه را حذف نمی‌کند. bind mount مسیر بکاپ همان میزبان را روشن می‌کند؛ volume نام‌دار هم راه رسمی است، اما بازیابی متناسب با خودش را لازم دارد. سقف منابع رزرو ظرفیت نیست. سرویس‌ها مستقل شروع می‌شوند و readiness را در بخش بعد جداگانه ثابت می‌کنیم. restart policy برای فرایند خارج‌شده است و به‌تنهایی سرویس هنگ‌کرده را تشخیص نمی‌دهد.

YAML · /srv/academy-monitor/compose.yaml
name: academy-monitor
services:
  prometheus:
    image: prom/prometheus:v3.15.0@sha256:efd719c99d83b060d9daefdcf00360461adf279f45ef5391f8d111892118753e
    user: "65534:65534"
    restart: unless-stopped
    read_only: true
    cap_drop: [ALL]
    security_opt: [no-new-privileges:true]
    mem_limit: 1536m
    cpus: 1.0
    pids_limit: 128
    tmpfs: [/tmp:size=64m,mode=1777]
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
      - --storage.tsdb.retention.time=15d
      - --storage.tsdb.retention.size=5GB
      - --web.listen-address=0.0.0.0:9090
    ports: ["127.0.0.1:19090:9090"]
    volumes:
      - type: bind
        source: /srv/academy-monitor/config/prometheus.yml
        target: /etc/prometheus/prometheus.yml
        read_only: true
        bind: {create_host_path: false}
      - type: bind
        source: /srv/academy-monitor/config/targets
        target: /etc/prometheus/targets
        read_only: true
        bind: {create_host_path: false}
      - type: bind
        source: /srv/academy-monitor/prometheus-data
        target: /prometheus
        bind: {create_host_path: false}
    networks: [monitor]
    logging:
      driver: json-file
      options: {max-size: "10m", max-file: "3"}
  grafana:
    image: grafana/grafana:13.2.4@sha256:dbbc38ea21103cefb50396340cd88afec779c7e070b0a7bf5a75b4ce46651d3f
    user: "472:0"
    restart: unless-stopped
    read_only: true
    cap_drop: [ALL]
    security_opt: [no-new-privileges:true]
    mem_limit: 768m
    cpus: 1.0
    pids_limit: 256
    tmpfs: [/tmp:size=64m,mode=1777]
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana_admin
      GF_AUTH_ANONYMOUS_ENABLED: "false"
      GF_USERS_ALLOW_SIGN_UP: "false"
      GF_METRICS_ENABLED: "true"
      GF_ANALYTICS_REPORTING_ENABLED: "false"
      GF_ANALYTICS_CHECK_FOR_UPDATES: "false"
      GF_ANALYTICS_CHECK_FOR_PLUGIN_UPDATES: "false"
      GF_PLUGINS_PREINSTALL_DISABLED: "true"
    ports: ["127.0.0.1:13000:3000"]
    secrets: [grafana_admin]
    volumes:
      - type: bind
        source: /srv/academy-monitor/grafana-data
        target: /var/lib/grafana
        bind: {create_host_path: false}
      - type: bind
        source: /srv/academy-monitor/config/datasources
        target: /etc/grafana/provisioning/datasources
        read_only: true
        bind: {create_host_path: false}
      - type: bind
        source: /srv/academy-monitor/config/dashboards
        target: /etc/grafana/provisioning/dashboards
        read_only: true
        bind: {create_host_path: false}
      - type: bind
        source: /srv/academy-monitor/dashboards
        target: /var/lib/grafana/dashboards
        read_only: true
        bind: {create_host_path: false}
    networks: [monitor]
    logging:
      driver: json-file
      options: {max-size: "10m", max-file: "3"}
networks:
  monitor:
    internal: true
    ipam:
      config: [{subnet: "172.30.71.0/24"}]
secrets:
  grafana_admin:
    file: /srv/academy-monitor/secrets/grafana-admin
همهٔ آموزش‌های آکادمی ↗