در سال‌های گذشته، ابزار Docker Compose تبدیل به راه‌حل غالب برای استفاده از اپلیکیشن‌ها شده است. این موضوع به دلیل سادگی اجرا و وارد کردن اپلیکیشن‌ها در کانتینرهای موقت است. در هنگام استفاده از بسته LEMP همراه با PHP، Nginx ،  MySQL و فریم‌ورک Laravel، ابزار Docker می‌تواند به میزان قابل‌توجهی فرآیند نصب را برای شما ساده‌سازی کند.

Docker Compose به توسعه‌دهندگان اجازه می‌دهد که ساختارشان شامل سرویس‌ها، شبکه‌ها و حجم‌ها را در یک فایل تعریف کنند. در نتیجه، به کمک این ابزار فرآیند توسعه وب بسیار ساده‌تر می‌شود.

در این آموزش قصد داریم که یک برنامه تحت وب با استفاده از فریم‌ورک Laravel همراه با Nginx به عنوان وب‌سرور و MySQL به عنوان پایگاه داده بسازیم. همگی این موارد درون کانتینر‌های Docker انجام می‌گیرند. شما تمام این بسته تنظیمات را درون یک فایل docker-compose تعریف می‌کنید و موارد لازم را برای php، MySQL و Nginx تنظیم می‌نمایید.

پیش‌نیازها

قبل از اینکه شروع به کار کنید، به موارد زیر نیاز خواهید داشت:

یک سرور اوبونتو 18.04 و یک کاربر غیر روت با دسترسی‌های sudo. همچنین نصب Docker و کمپوزر آن.

گام ۱) دریافت Laravel و نصب متعلقات

به عنوان گام اول، آخرین نسخه Laravel را دریافت کرده و معتلقات لازم را برای پروژه نصب کنید؛ از جمله Composer و مدیریت بسته در سطح اپلیکیشن برای php. ما این بخش‌ها را همراه با نصب Docker انجام می‌دهید تا نیاز به نصب سراسری Composer نداشته باشیم.

ابتدا بررسی کنید که که دایرکتوری خانگی هستید و سپس آخرین نسخه ارائه‌شده از Laravel را به مقصدی با نام laravel-app منتقل کنید.

cd ~
git clone https://github.com/laravel/laravel.git laravel-app

به دایرکتوری laravel-app منتقل شوید:

cd ~/laravel-app

سپس از کمپوزر تصویر Docker برای تعیین موقعیت دایرکتوری‌هایی که برای پروژه Laravel به آن نیاز دارید، استفاده کنید. در این حالت، از نصب کلی و سراسری Composer خودداری کنید.

docker run --rm -v $(pwd):/app composer install

استفاده از گزینه‌های –v و –rm با docker موجب ایجاد یک کانتینر موقت می‌شود. این کانتینر به صورت موقت در دایرکتوری کنونی ایجاد شده و سپس برداشته می‌شود. این فرمان باعث کپی‌شدن محتویات دایرکتوری ~/laravel-app به کانتینرمی‌گردد. همچنین حتماً فولدری را که Composer درون کانتینر ایجاد کرده، به داخل دایرکتوری کنونی شما کپی می‌کند.

به عنوان قدم نهایی، مجوزهای لازم را در دایرکتوری پروژه ایجاد نمایید. این دایرکتوری تحت مالکیت کاربر غیر روت شما خواهد بود.

sudo chown -R $USER:$USER ~/laravel-app

این موضوع زمانی که شما یک فایل موسوم به Dockerfile برای اپلیکیشن خود در گام چهارم می‌نویسید، اهمیت خواهد داشت. چنین چیزی به شما امکان می‌دهد که با کد اپلیکیشن خود کار کنید و فرآیندها را به عنوان یک کاربر غیر روت در کانتینر اجرا نمایید.

با قرار گرفتن کد اپلیکیشن در مکان مناسب، می‌توانید به سراغ تعریف خدماتتان با Docker Compose بروید.

گام ۲) ساخت فایل Docker Compose

ساخت اپلیکیشن با Docker Compose موجب ساده‌سازی فرآیند تنظیمات و نوسازی زیرساخت‌های شما می‌شود. برای تنظیم برنامه Laravel یک فایل docker-compose می‌نویسیم. در این فایل، وب‌سرور، پایگاه داده و سرویس‌های اپلیکیشن خود را تعریف می‌کنیم.

فایل را به این صورت باز می‌کنیم.

nano ~/laravel-app/docker-compose.yml

در فایل docker-compose، شما سه نوع خدمات را تعریف می‌کنید؛ اپ، وب‌سرور و دی‌بی (پایگاه داده). برای این منظور، کد زیر را به فایل اضافه کنید. حتماً دقت کنید که کلمه عبور روت را با عبارت MYSQL_ROOT_PASSWORD جایگزین کنید. این عبارت به عنوان یک متغیر محیطی در سرویس db تعریف شده است.

~/laravel-app/docker-compose.yml

version: '3'

services:

#PHP Service

app:

build:

context: .

dockerfile: Dockerfile

image: digitalocean.com/php

container_name: app

restart: unless-stopped

tty: true

environment:

SERVICE_NAME: app

SERVICE_TAGS: dev

working_dir: /var/www

networks:

- app-network

#Nginx Service

webserver:

image: nginx:alpine

container_name: webserver

restart: unless-stopped

tty: true

ports:

- "80:80"

- "443:443"

networks:

- app-network

#MySQL Service

db:

image: mysql:5.7.22

container_name: db

restart: unless-stopped

tty: true

ports:

- "3306:3306"

environment:

MYSQL_DATABASE: laravel

MYSQL_ROOT_PASSWORD: your_mysql_root_password

SERVICE_TAGS: dev

SERVICE_NAME: mysql

networks:

- app-network

#Docker Networks

networks:

app-network:

driver: bridge

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

app: این سرویس شامل اپلیکیشن Laravel بوده و یک تصویر سفارشی از Docker اجرا می‌کند. این همان چیزی است که شما در گام چهارم تعریف می‌کنید. همچنین این آیتم مقدار working_dir را به /var/www تنظیم می‌کند.

webserver: این سرویس تصویر nginx:alpine را استخراج کرده و پورت‌های ۸۰ و ۴۴۳ را در اختیار قرار می‌دهد.

db: این سرویس تصویر mysql:5.7.22 را از Docker استخراج کرده و برخی متغیرهای محیطی مانند پایگاه داده‌ای با عنوان laravel تعریف می‌کند. این همان پایگاه داده‌ای است که برای اپلیکیشن شما مورد استفاده قرار می‌گیرد. همچنین پسورد روت از جمله متغیرهای محیطی دیگری است که در این سرویس تعریف می‌شود. عنوان پایگاه داده کاملاً انتخابی است. ضمن اینکه شما باید عبارت your_mysql_root_password با پسورد مناسب خودتان جایگزین کنید. این سرویس همچنین پورت 3306 هاست را با پورت  3306 کانتینر مرتبط می‌کند.

هر مشخصه container_name یک نام برای کانتینر تعریف می‌کند؛ عنوانی که مطابق با نام سرویس خواهد بود. اگر این مشخصه را تعریف نکنید، Docker یک نام با ترکیبی از اسم مشاهیر و یک کلمه تصادفی برای شما انتخاب می‌کند.

برای تسهیل ارتباط بین کانتینرها، سرویس‌ها به یک شبکه بریج با عنوان app-network مرتبط می‌شوند. یک شبکه بریج از یک نرم‌افزار بریج برای ارتباط کانتینرها با یکدیگر استفاده می‌کند. درایور بریج به صورت خودکار تنظیمات را در سیستم هاست نصب می‌کند. در نتیجه، کانتینرهای شبکه‌های بریج مختلف نمی‌توانند با یکدیگر به صورت مستقیم در ارتباط باشند. این موضوع سطح بالایی برای امنیت اپلیکشن‌ها ایجاد می‌کند. تنها سرویس‌های مرتبط با یکدیگر می‌تواندد با یکدیگر ارتباط داشته باشند. همچنین این بدان معناست که شما می‌توانید شبکه‌ها و سرویس‌های چندگانه تعریف کنید و به عملکردهای مشخص آنها را مرتبط نمایید.

حالا ببینیم که چگونه باید حجم اضافه کنیم و چگونه مقادیر را برای ثبات داده‌های اپلیکیشن وارد کنیم.

گام ۳) ثبات داده‌ها

Docker داری ویژگی‌هایی قدرتمند برای ثبات داده‌هاست. در اپلیکیشنی که در اینجا داریم، میخواهیم از حجم‌ها و اضافه‌کردن مقادیر برای ثبات داده‌ها، اپلیکیشن و فایل‌های تنظیمات استفاده کنیم. حجم‌ها انعطاف‌پذیری لازم را برای پشتیبان‌گیری ایجاد می‌کنند و فراتر از چرخه عمر کانتینر، یک نوع ثبات به‌وجود می‌آورند. این در حالی که مقادیر موسوم به bind mounts روند تغییرات کدنویسی را در مراحل توسعه و همچنین اصلاح در فایل‌های هاست یا دایرکتوری‌های موجود در کانتینرها را تسهیل می‌کنند. در اینجا از هر دو گزینه استفاده خواهیم کرد.

هشدار: با استفاده از bind mount ها، شما امکان تغییر فایل‌های سیستمی هاست را  از طریق فرآیندهای کانتینر فراهم می‌کنید؛ از جمله ساخت، اصلاح و یا حذف فایل‌ها یا دایرکتوری‌های مهم سیستمی. این قابلیت بسیار قدرتمندی در ارتباط با کاربردهای امنیتی است و می‌تواند فرآیندهای خارج Docker را در سیستم هاست تحت‌تأثیر قرار دهد.

در فایل docker-compose، حجمی را با نام dbdata را تحت سرویس db تعریف کنید. این کار برای پشتیبانی از پایگاه داده MySQL صورت می‌گیرد.

...

#MySQL Service

db:

...

volumes:

- dbdata:/var/lib/mysql

networks:

- app-network
<pre>  ...

حجم dbdata از محتوای فولدر /var/lib/mysql پشتیبانی می‌کند. این فولدر درون کانتینر واقع شده است. در نتیجه شما می‌توانید بدون آن که داده‌ای از دست بدهید، سرویس db را متوقف و دوباره راه‌اندازی کنید.

در انتهای فایل، تعریف حجم dbdata را به صورت زیر اضافه کنید.

...

#Volumes

volumes:

dbdata:

driver: local

حالا می‌توانید از حجم در تمام سرویس‌ها استفاده کنید.

سپس نوبت به اضافه کردن یک مقدار bind mount به سرویس db می‌رسد. این کار برای فایل‌ تنظیمات MySQL صورت می‌گیرد که در گام هفتم طریق کار با آن را مشاهده خواهید کرد.

...

#MySQL Service

db:

...

volumes:

- dbdata:/var/lib/mysql

- ./mysql/my.cnf:/etc/mysql/my.cnf

...

این bind mount فایل ~/laravel-app/mysql/my.cnf را به فایل /etc/mysql/my.cnf در کانتینر مرتبط می‌کند.

در مرحله بعد باید bind mount ها را به سرویس وب‌سرور اضافه کنیم؛ یکی برای کد اپلیکیشن و دیگر برای تنظیمات Nginx. تنظیمات Nginx را در گام هفتم ایجاد خواهیم کرد.

</pre>
#Nginx Service

webserver:

...

volumes:

- ./:/var/www

- ./nginx/conf.d/:/etc/nginx/conf.d/

networks:
<pre>- app-network

اولین bind mount کد اپلیکیشن موجود در دایرکتوری ~/laravel-app را به دایرکتوری /var/www در کانتینر متصل می‌کند. همچنین فایل تنظیماتی نیز که در ~/laravel-app/nginx/conf.d/ اضافه خواهید کرد، به /etc/nginx/conf.d/ در کانتینر مرتبط خواهد شد. در نتیجه، این امکان برای شما فراهم می‌شود که محتوای دایرکتوری تنظیمات را اضافه یا اصلاح کنید.

نهایتاً bind mount های زیر را برای کد اپلیکیشن و فایل‌های تنظیمات، به سرویس app اضافه کنید.

#PHP Service
app:
...
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network 

در اینجا فولدر ~/laravel-app از سرویس app که حاوی کد اپلیکیشن است به فولدر /var/www در کانتینر مرتبط می‌شود. این موضوع موجب سرعت‌بخشیدن به روند توسعه می‌شود. به این دلیل که هر گونه تغییری که در دایرکتوری محلی اپلیکیشن خود انجام می‌دهید، به صورت لحظه‌ای در کانتینر انعکاس پیدا می‌کند. شما همچنین فایل تنظیمات php یا ~/laravel-app/php/local.ini را به /usr/local/etc/php/conf.d/local.ini در کانتینر متصل می‌کنید. در گام پنجم، فایل تنظیمات محلی php را ایجاد خواهید کرد.

فایل docker-compose شما به شکل زیر خواهد بود.

version: '3'
services:
#PHP Service
app:
build:
context: .
dockerfile: Dockerfile
image: digitalocean.com/php
container_name: app
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
#Nginx Service
webserver:
image: nginx:alpine
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#MySQL Service
db:
image: mysql:5.7.22
container_name: db
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: your_mysql_root_password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- dbdata:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local

اکنون که تغییرات را انجام داده‌اید، فایل را ذخیره کرده و ویرایشگر خود را ببندید. حالا نوبت به ساخت تصویر سفارشی اپلیکیشن شماست.

گام ۴) ساخت Dockerfile

Docker به شما این امکان را می‌دهد که با استفاده از Dockerfile یک محیط اختصاصی درون کانتینرها ایجاد کنید. شما با استفاده از یک Dockerfile می‌‌توانید تصاویر سفارشی موردنیاز برای نصب اپلیکیشن خودتان را بسازید و تنظیمات را مطابق نیازهایتان انجام دهید. می‌توانید تصاویر سفارشی خود را به Docker Hub یا هر رجیستری اختصاصی دیگری منتقل کنید.

Dockerfile ما درون دایرکتوری ~/laravel-app واقع خواهد شد.  برای ساخت این فایل داریم:

nano ~/laravel-app/Dockerfile

این Dockerfile تصویر پایه را ایجاد می‌کند و برای مشخص کردن دستورات و راهنماهای ضرور برای تصویر اپلیکیشن Laravel مورد استفاده قرار می‌گیرد. برای این منظور، کد زیر را به فایل اضافه کنید:

FROM php:7.2-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Dockerfile ابتدا یک تصویر در بالای تصویر php:7.2-fpm Docker ایجاد می‌کند. این یک تصویر بر پایه دبیان است که از قابلیت‌های PHP FastCGI بهره می‌گیرد. این فایل همچنین بسته‌های موردنیاز برای Laravel را نصب می‌کند. این بسته‌ها عبارتند از: mcrypt، pdo_mysql، mbstring و imagick.

مشخصه RUN دستورات مرتبط با ارتقا، نصب و تنظیمات درون کانتینر را تعیین می‌کند. ساخت کاربر و گروه اختصاصی با عنوان www نیز در این زیرمجموعه قرار می‌گیرد. دستورالعمل WORKDIR مشخص می‌کند که دایرکتوری /var/www محل انجام کارهای مربوط به اپلیکیشن خواهد بود.

ساخت یک کاربر و گروه اختصاصی با مجوزهای محدود برای مقابله با آسیب‌پذیری کانتینرهای Docker صورت می‌گیرد. این در حالی است که این کانتینرها به طور پیش‌فرض، به صورت روت اجرا می‌شوند. به جای اجرای کانتینر به صورت روت، ما کاربری به نام www ایجاد می‌کنیم که اجازه دسترسی نوشتن و خواندن را به فولدر /var/www دارد. این موضوع در دستورالعمل COPY تعریف شده است.

نهایتاً فرمان EXPOSE پورت 9000 را در دسترس سرور php-fpm قرار می‌دهد. CMD نیز فرمانی را مشخص می‌کند که پس از ساخت کانتینر، حتماً می‌بایست یک بار اجرا شود. CMD با مشخصه “php-fpm”، سرور را راه‌اندازی خواهد کرد.

پس از انجام تغییرات، فایل را ذخیره کرده و ببندید.

حالا می‌توانید به سراغ تنظیمات php بروید.

گام ۵) تنظیمات PHP

اکنون که بستر لازم را در فایل docker-compose فراهم کرده‌اید، نوبت به تنظیمات سرویس php می‌رسد. شما در این مرحله تنظیم می‌کنید که سرویس php به عنوان یک پردازنده php برای درخواست‌های ورودی از Nginx عمل کنذد.

برای تنظیم php شما یک فایل local.ini درون فولدر php ایجاد می‌کنید. این همان فایلی است که در گام دوم، بین آن و فایل /usr/local/etc/php/conf.d/local.ini در کانتینر ارتباط برقرار کرده‌ بودید. ساخت این فایل به شما اجازه می‌دهد که بتوانید از کنار فایل پیش‌فرض php.ini به‌راحتی عبور کنید.

ساخت دایرکتوری php

mkdir ~/laravel-app/php

سپس فایل local.ini را باز می‌کنید.

nano ~/laravel-app/php/local.ini

برای نشان‌دادن نحوه تنظیم php در اینجا، کد زیر را برای ایجاد محدود حجم فایل آپلود شده اضافه می‌کنیم.

</pre>
upload_max_filesize=40M

post_max_size=40M

پارامترهای  upload_max_filesize و post_max_size مقادیر ماکزیمم حجم فایل آپلودی را مشخص می‌کنند. در اینجا شما می‌تواند هر گونه تنظیمات خاص php را که می‌خواهید خارج از فایل local.ini داشته باشید، انجام دهید.

حالا می‌توانید فایل را ذخیره و برنامه ویرایشگر را ببندید.

بعد از تنظیم فایل PHP local.ini، می‌توانید به سراغ تنظیمات Nginx بروید.

گام ۶) تنظیمات Nginx

پس از تنظیم سرویس php، می‌توانید سرویس Nginx را به گونه‌ای تعریف کنید که از PHP-FPM به عنوان سرور FastCGI برای ارائه محتوای دینامیک استفاده کند. سرور FastCGI بر اساس یک پروتکل باینری برای ارائه رابط کاربری برنامه‌های هوشمند  و همراه با یک وب‌سرور است.

برای تنظیم Nginx، شما یک فایل app.conf همراه با تنظیمات سرویس خواهید ساخت که در فولدر ~/laravel-app/nginx/conf.d/ قرار می‌گیرد.

ابتدا دایرکتوری nginx/conf.d/ را ایجاد کنید.

mkdir -p ~/laravel-app/nginx/conf.d

سپس فایل تنظیمات app.conf را بسازید.

nano ~/laravel-app/nginx/conf.d/app.conf

برای ایجاد تنظیمات خاص Nginx، کد زیر را به فایل اضافه کنید.

server {
listen 80;
index index.php index.html;
error_log  /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}

بلوک بالا تنظیمات وب‌سرور Nginx را با پارامترهای زیر انجام می‌دهد.

listen: این پارامتر پورتی را تعریف می‌کند که سرور از طریق آن درخواست‌ها را دریافت خواهد کرد.

error_log و access_log: پارامترهای تعریف‌کننده فایل‌ها برای ثبت تاریخچه عملکرد وب‌سرور

root: مشخص‌کننده مسیر فولدر روت، مسیر کامل هر گونه فایل درخواست‌شده در سیستم محلی.

در بلوک موقعیت php، پارامتر fastcgi_pass مشخص می‌کند که سرویس app متصل به سوکت TCP در پورت 9000 خواهد بود. این موضوع موجب می‌شود که سرور PHP-FPM فراتر از یک سوکت یونیکس، کل شبکه را تحت‌نظر داشته باشد. البته این موضوع را باید درنظر داشت که یک سوکت یونیکس سرعت نسبتاً بیشتری نسبت به یک سوکت TCP دارد. با این وجود، این نوع سوکت از یک پروتکل شبکه برخوردار نیست و برنامه بسته شبکه را نادیده می‌گیرد. زمانی که هاست‌ها در یک سیستم قرار داشته باشند، استفاده از سوکت یونیکس توجیه‌پذیر خواهد بود. امّا زمانی که سرویس‌هایتان در هاست‌های مختلف اجرا می‌شوند، استفاده از یک سوکت TCP مزیت ارتباط با سرویس‌های گسترده را در اختیار شما قرار می‌دهد. به دلیل اینکه کانتینر app ما بر روی هاست دیگری به جز هاست کانتینر وب‌سرور اجرا می‌شود، سوکت TCP در اینجا برای ما چاره‌ساز خواهد بود.

حالا پس از انجام تغییرات، فایل را ذخیره کنید و ویرایشگرتان را ببندید.

به لطف bind mount که در گام دوم ساخته‌اید، هر تغییری که درون فولدر nginx/conf.d/ انجام می‌دهید، درون کانتینر وب‌سرور نیز منعکس خواهد شد.

در مرحله بعد به تنظیمات MySQL خواهیم پرداخت.

گام ۷) تنظیم MySQL

پس از تنظیم php و Nginx می‌توانید MySQL را به گونه‌ای تنظیم کنید به عنوان پایگاه داده برای اپلیکیشن شما عمل کند.

برای تنظیم MySQL، باید فایل my.cnf را در فولدر mysql بسازید. این همان فایلی است که شما در گام دوم آن را به فایل /etc/mysql/my.cnf درون کانتینر مرتبط کرده‌اید.

برای نشان نحوه این کار، ما تنظیمات فعالسازی ثبت تاریخچه درخواست‌ها و فایل تاریخچه عملکرد را در my.cnf اضافه می‌کنیم. ابتدا دایرکتوری mysql را ایجاد می‌کنیم.

mkdir ~/laravel-app/mysql

سپس نوبت به فایل my.cnf می‌رسد.

nano ~/laravel-app/mysql/my.cnf

در این فایل، کد زیر را برای فعالسازی ثبت تاریخچه درخواست‌ها و فایل تاریخچه عملکرد وارد می‌‌کنیم.

</pre>
[mysqld]
general_log = 1
<pre>general_log_file = /var/lib/mysql/general.log

این فایل my.cnf ثبت تاریخچه را برای شما فعال می‌کند. با تنظیم general_log به مقدار ۱ اجازه ثبت تاریخچه کلی را می‌دهید. همچنین general_log_file نیز مشخص می‌کند که تاریخچه دقیقاً در کجا ذخیره خواهد شد.

حالا فایل را ذخیره کنید و از ویرایشگر خارج شوید. قدم بعدی ما، راه‌اندازی کانتینرها خواهد بود.

گام ۸) اصلاح تنظیمات محیطی و راه‌اندازی کانتینرها

پس از تعریف تمام سرویس‌ها در فایل docker-compose و ساخت فایل تنظیمات برای این سرویس‌ها، می‌توانید کانتینرها را اجرا کنید. به عنوان گام پایانی، باید یک نسخه کپی از فایل پیش‌فرض Laravel که با عنوان .env.example ایجاد کنید و نام آن را .env بگذارید. این همان فایلی است که Laravel برای تعریف محیطش نیاز دارد.

cp .env.example .env

حالا می‌توانید فایل .env را درون کانتینر اصلاح کنید و جزئیات موردنظرتان را به آن اضافه نمایید. برای این منظور، فایل را با nano یا هر ویرایشگر دیگری که ترجیح می‌دهید، باز کنید.

nano .env

بلوکی را که در آن پارامتر DB_CONNECTION مشخص شده پیدا کنید و آن را مطابق تنظیمات‌تان ویرایش نمایید. مقادیری که ویرایش خواهید کرد، عبارتند از:

DB_HOST پایگاه داده db کانتینر شما خواهد بود.

DB_DATABASE به عنوان پایگاه داده laravel عمل می‌کند.

DB_USERNAME کلمه کاربری مورد استفاده برای پایگاه داده شماست. در اینجا از کاربر laraveluser استفاده می‌کنیم.

DB_PASSWORD رمز عبوری است که می‌خواهید برای این حساب کاربری استفاده کنید.

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laraveluser
DB_PASSWORD=your_laravel_db_password

حالا تغییرات خود را ذخیره کنید و ویرایشگر خود را ببندید.

پس از تعریف تمام سرویس‌ها در فایل docker-compose، باید فرمانی را مشخص کنید که به ‌وسیله آن تمام کانتینرها اجرا شوند. همچنین باید حجم‌ها را بسازید و شبکه‌ها را متصل کنید.

docker-compose up –d

وقتی برای اولین بار docker-compose را اجرا می‌کنید، شروع به دریافت تمام تصاویر لازم Docker خواهد کرد. این موضوع ممکن است مدت زمانی به طول بیانجامد. بعد از این زمان است که کانتینرهای شما ایجاد می‌شوند. گزینه –d موجب می‌شوند که کانیترهایتان در پس‌زمینه اجرا گردند.

پس از تکمیل این فرآیند، با استفاده از فرمان زیر می‌توانید لیست تمام کانتینرهای در حال اجرا را مشاهده کنید.

docker ps

نمونه خروجی

CONTAINER ID        NAMES               IMAGE                             STATUS              PORTS
c31b7b3251e0        db                  mysql:5.7.22                      Up 2 seconds        0.0.0.0:3306->3306/tcp
ed5a69704580        app                 digitalocean.com/php              Up 2 seconds        9000/tcp
5ce4ee31d7c0        webserver           nginx:alpine                      Up 2 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp

پارامتر CONTAINER ID در این خروجی یک شناسه منحصر به فرد برای هر کدام از کانتینرها خواهد بود. این در حالی است که ستون NAMES نام سرویس هر کدام از آنها را مشخص می‌کند. شما می‌توانید از هر دوی این شناسه‌ها برای دسترسی به کانتینرها استفاده کنید. IMAGE نام تصویر هر کدام از کانتینرهاست و STATUS اطلاعاتی در مورد وضعیت هر کدام از کانتینرها ارائه می‌دهد. پارامتر STATUS نشان می‌دهد که کدام کانتینر در حال اجرا، بازیابی یا توقف است.

حالا از ابزار docker-compose برای تنظیم کلید اپلیکیشن Laravel استفاده می‌کنیم. راه‌اندازی docker-compose به شما اجازه می‌دهد که برخی فرمان‌های خاص را در کانتینرها اجرا نمایید.

فرمانی که در زیر می‌بینید، کلیدی تولید می‌کند که باید آن را در فایل .env کپی کنید. این کار برای امنیت بیشتر داده‌های شما صورت می‌گیرد.

docker-compose exec app php artisan key:generate

اکنون تنظیمات محیطی موردنیاز برای اپلیکیشن شما نیز انجام شده است. برای دسترسی به این تنظیمات از طریق یک فایل که باعث سرعت هر چه بیشتر اپلیکیشن خواهد شد، داریم:

docker-compose exec app php artisan config:cache

تنظیمات شما در /var/www/bootstrap/cache/config.php درون کانتینر بارگذاری خواهند شد.

به عنوان گام نهایی، از آدرس http://your_server_ip در مرورگرتان بازدید کنید. در نتیجه، با صفحه خاگی برنامه Laravel مواجه خواهید شد.

صفحه خانگی Laravel

صفحه خانگی Laravel

گام ۹) ساخت یک کاربر برای MySQL

نصب پیش‌فرض MySQL تنها حساب کاربری روت مدیریتی را ایجاد می‌کند. باید توجه داشت که این حساب‌ کاربری دارای دسترسی‌های نامحدودی در سرور پایگاه داده است. در حالت کلی، بهتر است از یک کاربر غیر روت برای کار با پایگاه داده استفاده شود. بر این اساس، می‌خواهیم یک کاربر اختصاصی برای اپلیکیشن پایگاه داده Laravel ایجاد کنیم.

برای ساخت یک کاربر جدید یک bash shell هوشمند بر روی کانتینر db اجرا می‌کنیم. این در کنار اجرای docker-compose انجام می‌گیرد.

docker-compose exec db bash

درون کانتینر، وارد حساب کاربری روت MySQL شوید.

root@c31b7b3251e0:/# mysql -u root -p

حالا با پیغامی مبنی بر وارد کردن پسورد حساب کاربری MySQL root مواجه می‌شوید. این پسورد را قبلاً در طول مراحل نصب در فایل docker-compose وارد کرده بودید.

کار خود را با بررسی پایگاه داده‌ای با عنوان laravel آغاز کنید. این پایگاه داده قبلاً در فایل docker-compose تعریف شده است. با اجرای فرمان show databases، پایگاه‌های داده موجود را بررسی نمایید.

mysql> show databases;

پایگاه داده laravel را در لیست خروجی مشاهده خواهید کرد.

+--------------------+
| Database           |
+--------------------+
| information_schema |
| laravel            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

سپس حساب کاربری‌ای باید بسازید که اجازه دسترسی به این پایگاه داده را داشته باشد. شما می‌توانید به دلخواه هر کلمه کاربری دیگری انتخاب کنید، ولی کلمه کاربری ما در اینجا laraveluser خواهد بود. فقط باید توجه داشته باشید که جزئیات کلمه کاربری و رمز عبورتان همان چیزی باشد که در گام قبلی در فایل .env تعریف کرده‌اید.

mysql> GRANT ALL ON laravel.* TO 'laraveluser'@'%' IDENTIFIED BY 'your_laravel_db_password';

فرمان Flush privileges را برای آگاه‌کردن سرور MySQL از تغییرات اجرا کنید.

mysql> FLUSH PRIVILEGES;

از MySQL خارج شوید.

mysql> EXIT;

نهایتاً از کانتینر نیز خارج شوید.

root@c31b7b3251e0:/#     exit

اکنون حساب کاربری برای پایگاه داده اپلیکیشن Laravel تنظیم شده و آماده است تا داده‌های خود را منتقل کرده و با کنسول Tinker کار کنید.

گام ۱۰) انتقال داده‌ها و کار با کنسول Tinker

با اجرای اپلیکیشن، امکان انتقال داده و استفاده از فرمان tinker برای شما فراهم می‌شود. در نتیجه، یک کنسول PsySH برایتان پایه‌گذاری می‌شود که از قبل Laravel را اجرا خواهد کرد. PsySH یک کنسول توسعه‌دهنده runtime و یک عیب‌یاب هوشمند برای php است. همچنین Tinker یک REPL مخصوص Laravel است. فرمان tinker به شما اجازه می‌دهد که از طریق یک خط فرمان shell با اپلیکیشن Laravel در ارتباط باشید.

ابتدا با استفاده از فرمان artisan migrate در Laravel باید وضعیت ارتباط با MySQL را بررسی کنید. در نتیجه، یک میز انتقال پایگاه داده درون کانتینر در اختیار خواهید داشت.

docker-compose exec app php artisan migrate

این فرمان باعث جابجایی جداول پیش‌فرض Laravel خواهد شد. خروجی تأیید انتقال، چیزی شبیه به این خواهد بود:

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

پس از پایان جابجایی یا migration می‌توانید برای بررسی ارتباط مناسب با پایگاه داده، با استفاده از فرمان tinker یک درخواست اجرا نمایید.

docker-compose exec app php artisan tinker

بررسی ارتباط MySQL با دریافت داده‌هایی که به‌تازگی منتقل کرده‌اید.

\DB::table('migrations')->get();

نمونه خروجی

=> Illuminate\Support\Collection {#2856
all: [
{#2862
+"id": 1,
+"migration": "2014_10_12_000000_create_users_table",
+"batch": 1,
},
{#2865
+"id": 2,
+"migration": "2014_10_12_100000_create_password_resets_table",
+"batch": 1,
},
],
}

می‌توانید از فرمان tinker برای تعامل با پایگاه‌های داده و کار با سرویس‌ها و مدل‌ها استفاده کنید.

پس تکمیل و تنظیم اپلیکیشن Laravel، شما برای توسعه و کار بیشتر آماده خواهید بود.

جمع‌بندی

اگر مراحل بالا را که در این مطلب نسبتاً طولانی داشتیم، به‌درستی انجام داده باشید، در حال حاضر یک اپلیکیشن بسته LEMP در سرورتان در اختیار دارید. احتمالاً بررسی‌های لازم را با دسترسی به صفحه خوشامدگویی Laravel  و انتقال پایگاه داده MySQL انجام داده‌اید.

کلید نصب ساده این ابزار، Docker Compose است که به شما اجازه ساخت گروهی از کانتینرهای Docker را در یک فایل و با یک فرمان جداگانه می‌دهد. مسلماً‌ کار مداوم با این ابزار، تجربه‌ها و مهارت‌های بیشتری در اختیار شما قرار می‌دهد.