توانایی ذخیره انباری از دادههای object و قابل دسترس کردن آنها از طریق APIهای HTTP، معروف به ذخیرهسازی object، در چشمانداز فناوری مدرن، بهویژه با راهحلهای پشتیبانگیری مبتنی بر ابر و شبکههای تحویل محتوا (CDN) با دسترسی بالا ضروری است.
MinIO، یک سرور ذخیره سازی object منبع باز است که با سرویس ذخیره سازی ابری آمازون S3 سازگار میباشد. برنامههای پیکربندی شده با رابط آمازون S3 میتوانند با رابط MinIO نیز پیکربندی شوند؛ به این معنی که میتوانید از MinIO به عنوان جایگزین مناسبی برای S3 به منظور کنترل بیشتر بر سرور ذخیره سازی objectهای خود استفاده کنید. این سرویس، دادههای بدون ساختار مانند عکسها، فیلمها، فایلهای گزارش، نسخههای پشتیبان و imageهای container و VM را ذخیره کرده و یک سرور ذخیرهسازی object واحد فراهم مینماید تا درایوهای متعددی را که در بسیاری از سرورها پخش شدهاند، جمعآوری کند.
MinIO به همراه یک کلاینت خط فرمان و یک رابط گرافیکی (کنسول MinIO) ارائه میشود، در حالی که از سرویس صف ساده برای پروتکل صف پیام پیشرفته (AMQP)، Elasticsearch ،Redis ،NATS و اهداف PostgreSQL پشتیبانی میکند. راهاندازی یک سرور MinIO میتواند طیف وسیعی از انعطاف پذیری و کاربرد را به پروژه شما اضافه کند.
MinIO را میتوان در حالت مستقل (standalone) روی یک سرور واحد یا در حالت توزیع شده در دو یا چند سرور (که در مجموع از حداقل چهار درایو یا volume ذخیره سازی تشکیل شدهاند) نصب کرد. استقرار مستقل MinIO فاقد برخی ویژگیهای پیشرفته؛ مانند نسخهسازی، مقیاسبندی، افزونگی و در دسترس بودن (که پیشفرض یک استقرار توزیع شده است) میباشد. استقرار مستقل میتواند به منظور ارزیابی و اهداف توسعه کوچک استفاده شود، در حالی که استقرار توزیع شده در جهت نیازهای توسعه قابل توجه یا تولید به شدت توصیه میشود.
این مطلب نیز ممکن است برای شما مفید باشد: گواهی SSL چیست؟
در این آموزش، شما یک استقرار مستقل MinIO را طی مراحل زیر انجام خواهید داد:
- نصب سرور MinIO برروی سروری که اوبونتو 20.04 را اجرا میکند.
- نصب کلاینت MinIO بر روی رایانه شخصی و پیکربندی آن برای برقراری ارتباط با سرور MinIO.
- تنظیم یک گواهی دیجیتال به منظور ایمنسازی ارتباط بین سرور و کلاینت، از جمله از طریق کنسول MinIO.
دقت کنید که قبل از دنبال کردن این آموزش، به یک سرور اوبونتو 20.04، شامل یک کاربر با دسترسیهای sudo غیر از root و یک فایروال نیاز دارید.
برای دسترسی به MinIO Console از طریق نام دامنه به جای (یا علاوهبر) دسترسی به آن از طریق آدرس IP سرور خود، به موارد زیر نیاز دارید:
- یک نام دامنه ثبت شده (در سراسر این آموزش از example.com استفاده شده است.)
- دو رکورد DNS زیر برای سرور خود (به منظور یادگیری جزئیات در مورد نحوه افزودن آنها، مقاله رکوردها و سوابق DNS را دنبال کنید.)
- یک رکورد A با example.com که به آدرس IP عمومی سرور شما اشاره میکند.
- یک رکورد A با www.example.com نیز که به آدرس IP عمومی سرور شما اشاره میکند.
مرحله 1- دانلود و نصب سرور MinIO
سرور MinIO را میتوان از یک فایل باینری یا یک بسته .deb نصب کرد. در این مرحله، با استفاده از بسته .deb آن را نصب خواهید کرد.
برای شروع، وارد سرور خود شوید:
ssh sammy@your-server-ip
پایگاه داده بسته را به روز نمایید:
sudo apt update
سپس سیستم را به روز کنید:
sudo apt upgrade
نصب را با y تایید نمایید.
در طول فرآیند ارتقا، ممکن است صفحهای مشابه زیر را در ترمینال خود مشاهده کنید که از شما درباره فایل پیکربندی سرور OpenSSH سؤال میکند. در صورتی که نمیخواهید تغییرات فایل پیکربندی بازنویسی شود، Enter را فشار دهید و گزینه پیش فرض با رنگ قرمز برجسته شده (keep the local version currently installed) را بپذیرید.
سپس، آخرین بسته .deb سرور MinIO را از صفحه دانلودهای MinIO دانلود نمایید:
wget https://dl.min.io/server/minio/release/linux-amd64/minio_20220523184511.0.0_amd64.deb
فایلی با نام minio_20220523184511.0.0_amd64.deb در پوشه کاری شما دانلود میشود. دستور dpkg به منظور مدیریت بستههای .deb استفاده میشود؛ بنابراین فایل دانلود شده را با استفاده از دستور زیر نصب کنید:
sudo dpkg -i minio_20220523184511.0.0_amd64.deb
گزینه -i بسته را نصب میکند.
این دستور، یک دستور minio و یک اسکریپت راه اندازی systemd را تنظیم میکند که هر دو میتوانند برای راه اندازی سرور MinIO استفاده شوند.
در این مرحله، شما بستهها را به روز کردید و سرویس MinIO را نصب نمودید. در مرحله بعد، objectهای سیستم فایل مورد نیاز برای اجرای سرور MinIO را ایجاد میکنید.
مرحله 2- ایجاد کاربر، گروه، دایرکتوری دادهها و فایل محیطی MinIO
در این مرحله، نیازمندیهای سرور MinIO را تنظیم خواهید کرد. دقت کنید که اگر تمام موارد این مرحله انجام نشود، سرور MinIO راه اندازی نمیگردد.
در ابتدای کار در سرور MinIO با اجرای دستور زیر یک گروه سیستمی ایجاد نمایید:
sudo groupadd -r minio-user
پرچم r- دستور میدهد که گروه را به یک system group تبدیل کند.
پس از آن، با دستور زیر، کاربری را در سرور MinIO ایجاد کنید:
sudo useradd -M -r -g minio-user minio-user
پرچم M- مانع ایجاد دایرکتوری home توسط دستور برای کاربر میشود و پرچم r- یک کاربر سیستم ایجاد میکند. پرچم g- کاربر را به گروه اصلی خود اختصاص میدهد. در این مورد، گروه همان گروه minio-user تازه ایجاد شده است.
در مرحله بعد، دایرکتوری دادهای را ایجاد کنید که در آن، MinIO همه فایلهای خود را با دستور زیر ذخیره میکند:
sudo mkdir /mnt/data
سپس، مالکیت دایرکتوری داده را به کاربر و گروه MinIO بدهید:
sudo chown minio-user:minio-user /mnt/data
در نهایت از دستور زیر، به منظور ایجاد و باز کردن فایل محیطی MinIO استفاده نمایید:
sudo nano /etc/default/minio
این فایل، متغیرهای مورد نیاز سرور و کنسول را نگهداری میکند.
کد زیر را به فایل اضافه کرده و sammy را با کاربر غیر root سرور خود به روز کنید:
/etc/default/minio
MINIO_VOLUMES="/mnt/data"
MINIO_OPTS="--certs-dir /home/sammy/.minio/certs --console-address :9001"
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
متغیر MINIO_VOLUMES، دایرکتوری داده MinIO را تعریف میکند؛ در حالی که متغیر MINIO_OPTS دایرکتوری گواهیهای دیجیتال، آدرس شنود کنسول MinIO و شماره پورت (همه رابطهای شبکه و پورت 9001) را تعریف میکند. دایرکتوری /home/sammy/.minio/certs هنوز وجود ندارد، اما آن را در مرحله 4 ایجاد خواهید کرد.
با متغیرهای MINIO_ROOT_USER و MINIO_ROOT_PASSWORD میتوانید نام کاربر و رمز عبور را برای MinIO Console تعریف کنید. هر دو در حال حاضر به صورت minioadmin تنظیم شدهاند؛ اما شما باید کاربر و رمز عبور را با اعتبارنامههای ورود امن بهروزرسانی نمایید.
در پایان، فایل را ذخیره کرده و آن را ببندید.
در این مرحله، کاربر MinIO و سایر موارد وابسته را تنظیم کردید. در مرحله بعد، فایروال را طوری پیکربندی خواهید کرد که به ترافیک MinIO اجازه عبور بدهد.
مرحله 3- تنظیم فایروال برای اجازه عبور ترافیک MinIO
در این مرحله، فایروال را به گونهای پیکربندی خواهید کرد که به پورتهایی که به سرور MinIO و MinIO Console دسترسی دارند، اجازه ورود ترافیک را بدهد. موارد زیر مربوط به MinIO هستند:
- 9000 پورت پیش فرضی است که سرور MinIO روی آن شنود میکند.
- 9001 پورت توصیه شده برای دسترسی به MinIO Console است.
دستور زیر، از طریق فایروال، مجوز عبور ترافیک به هر دو پورت را صادر میکند:
sudo ufw allow 9000:9001/tcp
با اجرای این دستور، خروجی زیر را خواهید دید:
output:
Rule added
Rule added (v6)
اکنون که پورتها آماده هستند، شما میتوانید یک گواهی امضا شده برای فعال کردن دسترسی امن به سرور MinIO ایجاد کنید.
مرحله 4- ایمن کردن دسترسی به سرور MinIO با یک گواهی خود امضا شده
در این مرحله، از certgen (یک برنامه Go از توسعه دهندگان MinIO) به منظور تولید گواهی امضا شده استفاده خواهید کرد.
آخرین نسخه آن را با دستور زیر دانلود نمایید:
wget https://github.com/minio/certgen/releases/download/v1.2.0/certgen_1.2.0_linux_amd64.deb
این دستور، فایلی به نام certgen_1.2.0_linux_amd64.deb را در دایرکتوری کاری شما قرار میدهد. با دستور زیر آن را نصب کنید:
sudo dpkg -i certgen_1.2.0_linux_amd64.deb
دستور certgen اکنون در سیستم در دسترس بوده و certgen -h اطلاعات مصرف آن را نمایش میدهد.
اگر میخواهید یک نام دامنه را برای سرور مشخص نمایید و میخواهید سرور MinIO را با نام دامنه و آدرس IP ارجاع دهید، با استفاده از دستور زیر یک گواهی برای سرور MinIO ایجاد کنید:
sudo certgen -host example.com,your-server-ip
چنانچه میخواهید تنها از طریق آدرس IP سرور خود به سرور MinIO دسترسی داشته باشید، با استفاده از دستور زیر یک گواهی برای آن ایجاد نمایید:
sudo certgen -host your-server-ip
اگر با موفقیت تولید شود، خروجی باید به شکل زیر باشد:
output:
Created a new certificate 'public.crt', 'private.key' valid for the following names
- "example.com"
- "your-server-ip"
اگر از دامنه استفاده نمیکنید، خروجی شما تنها IP سرور را لیست میکند.
فایلهای public.crt و private.key باید در دایرکتوری کاری شما باشند. این فایلها باید به دایرکتوری /home/sammy/.minio/certs منتقل شوند. از آنجایی که آن دایرکتوری هنوز وجود ندارد، آن را با دستور زیر ایجاد کرده و sammy را با کاربر غیر root سرور خود جایگزین نمایید:
sudo mkdir -p /home/sammy/.minio/certs
گزینه p- دایرکتوریهای والدی را که وجود ندارند، ایجاد میکند.
فایلها را با دستور زیر جابه جا کنید (در صورت نیاز sammy را جایگزین نمایید):
sudo mv private.key public.crt /home/sammy/.minio/certs
در نهایت، مالکیت هر دو فایل را به کاربر و گروه MinIO بدهید (در صورت نیاز Sammy را جایگزین کنید):
sudo chown minio-user:minio-user /home/sammy/.minio/certs/private.key
sudo chown minio-user:minio-user /home/sammy/.minio/certs/public.crt
در این مرحله یک گواهی خودامضا برای سرور و/یا دامنه خود ایجاد کردید. در ادامه، سرور MinIO را راهاندازی خواهید کرد.
مرحله 5- راهاندازی سرور MinIO
در این مرحله سرور MinIO را با سرویس systemd آن راهاندازی خواهید کرد.
سرور MinIO را میتوان با دستور minio یا با فراخوانی اسکریپت راهاندازی systemd راهاندازی کرد. با این حال، هنگامیکه سرور MinIO با دستور minio راهاندازی میشود، پس از reboot فعال نمیماند. علاوهبراین، راهاندازی سرور MinIO با دستور minio به طور خودکار پوشه .minio را در زیر دایرکتوری /root ایجاد میکند که با systemd کار نمیکند. بنابراین توصیه میشود که سرور MinIO را از طریق systemd راهاندازی نمایید.
سرور MinIO را با دستور زیر راهاندازی کنید:
sudo systemctl start minio
سپس وضعیت آن را با دستور زیر بررسی نمایید:
sudo systemctl status minio
خروجی باید مشابه زیر باشد:
output:
minio.service - MinIO
Loaded: loaded (/etc/systemd/system/minio.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2022-05-23 02:55:03 UTC; 2s ago
Docs: https://docs.min.io
Process: 21978 ExecStartPre=/bin/bash -c if [ -z "${MINIO_VOLUMES}" ]; then echo "Variable MINIO_VOLUMES not set in /etc/default>
Main PID: 21989 (minio)
Tasks: 7
Memory: 49.5M
CGroup: /system.slice/minio.service
└─21989 /usr/local/bin/minio server --certs-dir /home/finid/.minio/certs --console-address :9001 /mnt/data
May 23 02:55:03 minio-buntu systemd[1]: Starting MinIO...
May 23 02:55:03 minio-buntu systemd[1]: Started MinIO.
May 23 02:55:03 minio-buntu minio[21989]: WARNING: Detected default credentials 'minioadmin:minioadmin', we recommend that you chang>
May 23 02:55:03 minio-buntu minio[21989]: API: https://161.35.115.223:9000 https://10.10.0.6:9000 https://10.116.0.3:9000 https:/>
May 23 02:55:03 minio-buntu minio[21989]: Console: https://161.35.115.223:9001 https://10.10.0.6:9001 https://10.116.0.3:9001 https:>
May 23 02:55:03 minio-buntu minio[21989]: Documentation: https://docs.min.io
May 23 02:55:03 minio-buntu minio[21989]: Finished loading IAM sub-system (took 0.0s of 0.0s to load data).
اگر در خروجی بالا، API و کنسول با https شروع شده باشد، همه چیز به درستی انجام شده است. ولیکن، اگر API و کنسول به http اشاره کنند، مشکلی پیش آمده است؛ حتی اگر MinIO با موفقیت راهاندازی شود. در این صورت ممکن است لازم باشد با استفاده از مرحله 4 یک گواهی جدید ایجاد کنید تا به https هدایت شوید. سپس سرویس MinIO را مجددا راهاندازی نمایید. اگر فایلهای گواهی در دایرکتوری صحیح قرار نگیرند؛ یا اگر کاربر MinIO مالک آنها نباشد، منبع خطای دیگری ممکن است رخ دهد. MinIO همیشه در ژورنال systemd گزارش ثبت نمیکند؛ بنابراین اگر sudo journalctl -u minio اطلاعات دقیقی را هنگام عیبیابی MinIO نشان نمیدهد، به جای آن از دستور sudo grep minio /var/log/syslog استفاده کنید.
در این مرحله، سرور MinIO را راهاندازی کردید. در ادامه، به آن متصل خواهید شد.
مرحله 6- اتصال ایمن به سرور MinIO از طریق کنسول MinIO
کنسول MinIO رابط گرافیکی برای انجام وظایف مدیریتی مانند نظارت بر گزارش دسترسی و پیکربندی سرور است. در این مرحله از طریق این کنسول به سرور MinIO متصل خواهید شد.
بدین منظور در مرورگر خود مسیر https://your-server-ip:9001 را وارد نمایید.
توجه: از آنجایی که هیچ وب سروری در کار نیست، http://your-server-ip:9001 به https://your-server-ip:9001 هدایت نمیشود. بنابراین، همیشه از https://your-server-ip:9001 برای دسترسی به MinIO Console خود استفاده کنید.
به دلیل اینکه گواهینامه به صورت خودامضا است، مرورگر شما اعلانی مشابه تصویر زیر نمایش میدهد:
اگر از فایرفاکس استفاده میکنید، روی Advanced… سپس روی Accept the Risk و Continue کلیک نمایید. برای سایر مرورگرها نیز روند مشابه خواهد بود.
اکنون صفحه ورود MinIO Console بارگیری میشود:
با اعتبارنامههای پیکربندی شده در فایل محیطی MinIO (که در مرحله 2 ایجاد شد) وارد شوید.
در صورت ورود موفقیت آمیز، رابط اصلی به صورت زیر نمایش داده میشود:
شما میتوانید وظایف مدیریتی (مانند مشاهده گزارشها، ایجاد و مدیریت bucketها، کاربران و گروهها و سایر وظایف پیکربندی سرور) را از رابط کنسول انجام دهید.
اکنون از طریق رابط گرافیکی به سرور MinIO متصل شدهاید. در مرحله بعد کلاینت MinIO را بر روی کامپیوتر شخصی خود نصب کرده و از آن برای اتصال به سرور MinIO استفاده مینمایید.
مرحله 7 – نصب کلاینت MinIO و نحوه استفاده از آن در رایانه محلی شما
کلاینت MinIO عنصری از MinIO است که روی رایانه محلی خود نصب میکنید و از آن به منظور مدیریت سرور MinIO استفاده مینمایید. تمام دستورات در این مرحله در خط فرمان رایانه محلی شما تکمیل میشود. همانند سرور MinIO، کلاینت را میتوان از یک فایل باینری یا یک بسته .deb نصب کرد. در این مرحله با استفاده از بسته .deb آن را نصب خواهید کرد.
در یک نشست ترمینال جدید در دستگاه محلی خود، آخرین بسته .deb کلاینت MinIO را از صفحه دانلودهای MinIO دانلود کنید:
wget https://dl.min.io/client/mc/release/linux-amd64/mcli_20220509040826.0.0_amd64.deb
wget فایلی به نام mcli_20220509040826.0.0_amd64.deb را در دایرکتوری کاری شما قرار میدهد. آن را با استفاده از دستور زیر نصب نمایید:
sudo dpkg -i mcli_20220509040826.0.0_amd64.deb
این دستور، کلاینت MinIO را در رایانه شخصی شما در دسترس قرار میدهد که میتوانید با دستور mcli آن را فراخوانی کنید. به منظور پیکربندی اولیه کلاینت و فعال کردن تکمیل خودکار برای shell خود، که تایپ دستورات کلاینت را ساده میکند، دستور زیر را صادر نمایید:
mcli --autocompletion
با اجرای این دستور، خروجیای مانند زیر دریافت خواهید کرد:
output:
mcli: Configuration written to `/home/sammy/.mcli/config.json`. Please update your access credentials.
mcli: Successfully created `/home/sammy/.mcli/share`.
mcli: Initialized share uploads `/home/sammy/.mcli/share/uploads.json` file.
mcli: Initialized share downloads `/home/sammy/.mcli/share/downloads.json` file.
mcli: Your shell is set to 'bash', by env var 'SHELL'.
mcli: enabled autocompletion in your 'bash' rc file. Please restart your shell.
این خروجی، محل پوشه پیکربندی مخفی و سایر پوشهها و فایلهای پیکربندی داخل آن را به شما نشان میدهد.
به منظور فعال سازی تکمیل خودکار در shell فعلی خود بدون خاموش کردن و راهاندازی مجدد آن، دستور زیر را صادر کنید:
source .profile
خارج از box، فایل پیکربندی حاوی اعتبار دسترسی سرورهای MinIO است که شما میتوانید از کلاینت MinIO برای مدیریت استفاده نمایید. شما میتوانید فایل را در یک ویرایشگر ترمینال ویرایش کنید یا میتوانید با استفاده از mcli یک ورودی اضافه نمایید.
به منظور افزودن ورودی برای سرور MinIO خود در فایل پیکربندی با mcli، از دستور زیر با اعتباری که در مرحله 2 برای سرور تنظیم کردید، استفاده کنید:
mcli --insecure alias set myminio/ https://your-server-ip:9000 minioadmin minioadmin
نام بعد از دستور alias set را میتوان به صورت دلخواه تنظیم کرد. در اینجا برروی myminio/ تنظیم شده است.
دقت کنید که پرچم insecure-- ضروری است؛ زیرا از گواهی خود امضا شده استفاده میکنید. بدون آن، دستور با شکست مواجه میشود؛ زیرا کلاینت سعی میکند، تأیید کند که گواهی از یک مرجع گواهی معتبر است.
نکته: هنگام استفاده از کلاینت MinIO برای اتصال به سرور MinIO، همیشه دستور mcli را با پرچم insecure-- فراخوانی نمایید. این بدان معنا نیست که اتصال امن نیست؛ بلکه تنها به این معنی است که کلاینت سعی نخواهد کرد صحت گواهی را تأیید کند. بنابراین، دستور بدون آن پرچم شکست خواهد خورد؛ با این حال، تنها در هنگام استفاده از گواهی امضا شده از آن استفاده کنید.
برای مشاهده داخل فایل ~/.mcli/config.json از دستور زیر استفاده نمایید:
sudo nano ~/.mcli/config.json
میزبان myminio را که به تازگی اضافه کردهاید، در خروجی خواهید دید:
output:
~/.mcli/config.json
{
"version": "10",
"aliases": {
"gcs": {
"url": "https://storage.googleapis.com",
"accessKey": "YOUR-ACCESS-KEY-HERE",
"secretKey": "YOUR-SECRET-KEY-HERE",
"api": "S3v2",
"path": "dns"
},
"local": {
"url": "http://localhost:9000",
"accessKey": "",
"secretKey": "",
"api": "S3v4",
"path": "auto"
},
"myminio": {
"url": "https://your_server_ip:9000",
"accessKey": "minioadmin",
"secretKey": "minioadmin",
"api": "S3v4",
"path": "auto"
},
"play": {
"url": "https://play.min.io",
"accessKey": "ACCESS-KEY",
"secretKey": "SECRET-KEY",
"api": "S3v4",
"path": "auto"
},
"s3": {
"url": "https://s3.amazonaws.com",
"accessKey": "YOUR-ACCESS-KEY-HERE",
"secretKey": "YOUR-SECRET-KEY-HERE",
"api": "S3v4",
"path": "dns"
}
}
اکنون آماده یادگیری گزینههایی هستید که به همراه دستور mcli ارائه میشود. آن را با پرچم h- اجرا کنید تا صفحه راهنما چاپ شود:
mcli -h
خروجی باید مشابه زیر باشد:
output:
COMMANDS:
alias manage server credentials in configuration file
ls list buckets and objects
mb make a bucket
rb remove a bucket
cp copy objects
mv move objects
rm remove object(s)
mirror synchronize object(s) to a remote site
cat display object contents
head display first 'n' lines of an object
...
...
GLOBAL FLAGS:
--autocompletion install auto-completion for your shell
--config-dir value, -C value path to configuration folder (default: "/home/finid/.mcli")
--quiet, -q disable progress bar display
--no-color disable color theme
--json enable JSON lines formatted output
--debug enable debug output
--insecure disable SSL certificate verification
--help, -h show help
--version, -v print the version
...
به منظور راهنمایی در مورد نحوه استفاده از هر دستوری، آن را با گزینه h- فراخوانی کنید. به عنوان مثال:
mcli alias -h
برای جمع آوری اطلاعات در مورد سرور MinIO، دستور زیر را تایپ کنید:
mcli --insecure admin info myminio
خروجی مشابه زیر خواهد بود:
● your-server-ip:9000
Uptime: 8 hours
Version: 2022-05-19T18:20:59Z
زمانی که سرور MinIO در حال اجرا است، شما میتوانید آن را با استفاده از دستور زیر retart نمایید:
mcli --insecure admin service restart myminio
شما نمیتوانید یک سرور MinIO متوقف شده را از کلاینت راهاندازی کنید. اگر سرور MinIO متوقف شده است، باید وارد سرور شده و آن را با دستور systemctl از مرحله 5 راهاندازی کنید. شما میتوانید سرور را با استفاده از دستور زیر متوقف نمایید:
mcli --insecure admin service stop myminio
در این مرحله توانستید با استفاده از دستور mcli به همراه پرچم insecure-- از کامپیوتر محلی به سرور MinIO خود متصل شوید.
منبع:
digitalocean
0 دیدگاه
نوشتن دیدگاه