راه اندازی Laravel و Nginx و PhpMyAmdin و MariaDB و Redis بر روی Docker

سلام . امیدوارم که حالتون خوب باشه . امروز میخواستم تجربه خودم رو در اختیارتون قرار بدم . توی این مطلب قصد دارم بهتون آموزش بدم که چطور میشه یک پروژه لاراول رو با داکر راه اندازی کرد . توی این مطلب قصد ندارم در مورد مبحث داکر توضیح بدم . در واقع شما باید با داکر کار کرده باشید و با دستورات داکر آشنایی داشته باشید و با container ها و image های داکر آشنا باشید .همچنین در مورد داکر فایل و داکر کامپوز هم اطلاعات داشته باشد . پس راه اندازی لاراول روی داکر موضوعی هست که میخوام در موردش توضیح بدم . خب اول از همه برای راه اندازی یه پروژه با فریمورک لاراول به چند تا تکنولوژی دیگه هم نیاز داریم . به یک دیتابیس نیاز داریم که من MariaDB رو انتخاب میکنم و همچنین از PhpMyAmdin هم برای مدیریت دیتابیس استفاده میکنیم. به یک وب سرور نیاز داریم که من Nginx رو انتخاب میکنم برای این آموزش . همچنین به Redis نیاز داریم که به عنوان cache driver و همچنین queue driver توی پروژه لاراولی ازش استفاده کنیم .برای شروع کار باید image تمام تکنولوژی هایی که میخواهیم رو از داکر هاب دانلود کنیم و از روی هر ایمیج یک کانتینر ایجاد کنیم و بعد کانتینر هارو به وسیله نتورک داکر به هم متصل کنیم . برای Redis و Nginx و PhpMyAdmin و MariaDB ایمیج های رسمی موجود هست . ولی چون خود پروژه لاراولی ما هم باید درون یک کانتینر اجرا شود باید ایمیج مخصوص به خودش را بسازیم تا بتونیم اون ایمیج رو اجرا کنیم . برای ساختن ایمیج دلخواه باید از Dockerfile استفاده کرد .ابتدا پروژه لاراول را در مسیر زیر ایجاد کنید . /var/www/exampleProject/یک فایل با نام Dockerfile در پوشه روت پروژه ایجاد کنید . بوسیله این فایل ما image مخصوص خودمون رو برای پروژه ایجاد میکنیم . خب میدونید که هر ایمیج داکر از یک ایمیج دیگر ساخته میشود . در واقع هر ایمیج داکر یک base image دارد . ما هم برای ساختن ایمیج خودمان از ایمیج رسمی php:7.4-fpm استفاده می کنیم . محتویات داخل Dockerfile به صورت زیر است . FROM php:7.4-fpm # فایل کامپوزر رو توی ورکینگ دایرکتوری قرار میدیم COPY composer.lock composer.json /var/www/ # توی این قسمت ورکینگ دایرکتوری خودمون رو مشخص میکنیم WORKDIR /var/www # هر دیپندنسی که لازم داریم رو نصب میکنیم RUN apt-get update --fix-missing && apt-get install -y \ build-essential \ libssl-dev \ zlib1g-dev \ libpng-dev \ libjpeg-dev \ libfreetype6-dev \ zlibc \ mariadb-client \ libpng-dev \ libjpeg62-turbo-dev \ libfreetype6-dev \ locales \ jpegoptim optipng pngquant gifsicle \ vim \ unzip \ git \ curl \ zip #از اوپکش استفاده میکنیم برای افزایش سرعت اجرای کد های پی اچ پی RUN docker-php-ext-install opcache && docker-php-ext-enable opcache # کش رو خالی میکنیم RUN apt-get clean && rm -rf /var/lib/apt/lists/* # اکستنشن های لازم برای لاراول و پی اچ پی رو نصب میکنیم RUN docker-php-ext-install pdo_mysql 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 bcmath # کامپوزر رو نصب میکنیم RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer # پورت 9000 رو اکسپوز میکنیم . در انتها سرور اف پی ام رو اجرا میکنیم EXPOSE 9000 CMD [&quotphp-fpm&quot]خب به وسیله این داکر فایل ما از بیس ایمیج رسمی php ورژن 7.4 استفاده میکنیم . و تمام مواردی که لازم داریم رو نصب میکنیم . مثل ویرایشگر vim . نکته مهم اینه که پروژه رو در مسیر /var/www/ داخل این ایمیج کپی میکنیم . در واقع ورکینگ دایرکتوری ما داخل کانتینری که از این ایمیج بعدا ساخته میشه این مسیر میشه .خب کار ما با Dockerfile تمومه . حالا باید از docker compose استفاده کنیم تا کل پروژه و سرویس هارو مدیریت کنیم و کانتینر هارو ران کنیم . فایل docker-compose.yml رو کنار فایل Dockerfile ایجاد کنید و اطلاعات زیر رو داخلش کپی کنید . تک تک این سرویس هارو بعدا توضیح خواهم داد . version: '3' services: #PHP Service app: build: context: . dockerfile: Dockerfile image: sepisoltani/php:newVersionWithStartShFile container_name: app restart: unless-stopped tty: true environment: SERVICE_NAME: app SERVICE_TAGS: dev CONTAINER_ROLE: app working_dir: /var/www volumes: - ./:/var/www - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini networks: - app-network #mariadb Service db: image: mariadb container_name: db restart: unless-stopped tty: true ports: - &quot3306:3306&quot environment: MYSQL_DATABASE: laravel_db MYSQL_ROOT_PASSWORD: ِYOUR_MYSQL_ROOT_PASSWORD SERVICE_TAGS: dev SERVICE_NAME: mariadb volumes: - /dbdata:/var/lib/mysql/ - ./mysql/my.cnf:/etc/mysql/my.cnf networks: - app-network # Phpmyadmin Service phpmyadmin: depends_on: - db image: phpmyadmin/phpmyadmin container_name: phpmyadmin restart: always ports: - '8082:80' environment: PMA_HOST: db MYSQL_ROOT_PASSWORD: YOUR_MYSQL_ROOT_PASSWORD networks: - app-network # Redis Service redis: image: redis:latest container_name: redis environment: - REDIS_PASSWORD=YOUR_REDIS_PASSWORD ports: - &quot6379:6379&quot restart: unless-stopped command: [&quotredis-server&quot, &quot--requirepass&quot, &quotYOUR_REDIS_PASSWORD&quot] networks: - app-network #Docker Networks networks: app-network: #Volumes volumes: dbdata: driver: localخب هالا تک تک سرویس هارو توضیح میدم . اول بپردازیم به سرویس appapp: build: context: . dockerfile: Dockerfile image: sepisoltani/php:latest container_name: app restart: unless-stopped tty: true environment: SERVICE_NAME: app SERVICE_TAGS: dev CONTAINER_ROLE: app working_dir: /var/www volumes: - ./:/var/www - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini networks: - app-network خب این قسمت از فایل داکر کامپوز داره یک سرویس با نام app یا در واقع یک کانتینر با همین اسم رو از روی ایمیجی که با داکر فایل ساختیم اجرا میکنه و بعد اسم این ایمیج رو sepisoltani/php:latest قرار میده. شما میتونید هر اسمی خواستید بزارید . توی قسمت volumes هم کل پروژه لاراول که داخل ایمیج توی مسیر /var/www/ کپی کردیم رو در یک فضا بیرون از کانتینر نگهداری میکنیم . که باید /. باشه . یعنی مسیر فعلی فایل داکر کامپوز توی هاست OS خودمون.برای تنظیمات PHP هم فایل local.ini در مسیر زیر در داخل کانیتنر وجود دارد /usr/local/etc/php/conf.d/ که به مسیر زیر در داخل هاست OS خودمون بایند میکنیم /var/www/exampleProject/php/local.ini/ پس یک دایرکتوری در داخل پروژه لاراولی میسازیم و فایل local.ini رو ایجاد میکنیم . میتونیم هر تنظیمی خواستیم داخلش قرار بدیم . برای مثال :upload_max_filesize=40M post_max_size=40M در واقع اینطوری هر موقع کانتینر بمیره اطلاعات از بین نمیرن . یعنی این دو مسیر به هم bind هستند . در قمست networks هم یک شبکه با نام app-network به این کانتینر اختصاص میدیم . که باید آخر همین فایل هم تعریف شده باشه .قسمت بعدی مربوط به سرویس دیتابیس هست db: image: mariadb container_name: db restart: unless-stopped tty: true ports: - &quot3306:3306&quot environment: MYSQL_DATABASE: laravel_db MYSQL_ROOT_PASSWORD: MYSQL_ROOT_PASSWORD SERVICE_TAGS: dev SERVICE_NAME: mariadb volumes: - /dbdata:/var/lib/mysql/ - ./mysql/my.cnf:/etc/mysql/my.cnf networks: - app-network توی این قسمت سرویس دیتابیس رو راه اندازی میکنیم . از ایمیج رسمی mariadb استفاده میکنیم سپس اسم کانتینر رو db قرار میدیم . پورت 3306 دیتابیس رو به 3306 هاست OS خودمون بایند میکنیم سپس در قسمت environment نام دیتابیس و یوزر دیبتابیس رو مشخص میکنیم . در قسمت volumes باید یک فضا برای اطلاعات درون دیتابیس روی هاست OS خودمون در نظر بگیریم و اطلاعات رو بهش بایند کنیم تا در صورت کشته شدن کانتینر اطلاعات دیتابیس مثل جدول ها و سطر ها از بین نرند . پس مسیر زیر در داخل کانتینر را /var/lib/mysql به مسیر زیر /dbdata/ در داخل هاست OS بایند میکنیم. سپس فایل تنظیمات دیتابیس را هم به بیرون بایند میکنیم . یعنی فایل تنظیمات در مسیر /etc/mysql/my.cnfرو به مسیر ./mysql/my.cnfبایند میکنیم و میتونیم هر کانفیگی خواستیم درون فایل my.cnf قرار بدیم . مثلا :[mysqld] general_log = 1 general_log_file = /var/lib/mysql/general.log قسمت بعدی سرویس phpmyadmin هست . # Phpmyadmin Service phpmyadmin: depends_on: - db image: phpmyadmin/phpmyadmin container_name: phpmyadmin restart: always ports: - '8082:80' environment: PMA_HOST: db MYSQL_ROOT_PASSWORD: MYSQL_ROOT_PASSWORD networks: - app-network توی این قسمت از ایمیج رسمی phpmyadmin استفاده میکنیم . و پورت 80 رو به یه پورت دلخواه مثلا 8082 بایند میکنیم . سپس در قسمت environment هاست دیتابیس رو db قرار میدیم . چون اسم کانتینر دیتابیس رو db گزاشته بودیم . پسورد دیتابیس هم قبلا در سرویس دیتابیس ست کردیم و همون رو قرار میدیم . قسمت بعدی سرویس ردیس هست که توضیح میدم . # Redis Service redis: image: redis:latest container_name: redis environment: - REDIS_PASSWORD=YOUR_PASSWORD ports: - &quot6379:6379&quot restart: unless-stopped command: [&quotredis-server&quot, &quot--requirepass&quot, &quotYOUR_PASSWORD&quot] networks: - app-network توی این سرویس از ایمیج رسمی redis:latest استفاده میکنیم. نام سرویس رو redis قرار میدیم و یه پسورد هم در نظر میگیریم . سپس پورت ردیس رو به بیرون بایند میکنیم . در قسمت command هم مشخص میکنیم که کانتینر با این دستور ران بشه.سرویس آخر که خیلی هم مهم است سرویس وب سرور یا همون Nginx است که باید تعریف بشه که به صورت زیر توضیح میدم .#Nginx Service webserver: image: nginx:alpine container_name: webserver restart: unless-stopped tty: true ports: - &quot80:80&quot volumes: - ./:/var/www - ./nginx/conf.d/:/etc/nginx/conf.d/ networks: - app-network از ایمیج رسمی nginx:alpine استفاده میکنیم . اسم سرویس رو webserver قرار میدیم . و پورت 80 رو به 80 هاست خودمون بایند میکنیم . سپس کل پروژه رو به مسیر /var/www/ داخل این کانتینر بایند میکنیم . همچنین فایل کانفیگ nginx رو که درون مسیر زیر در داخل کانتینر هست/etc/nginx/conf.d/رو به مسیری که دوست داریم بایند میکنیم . مثلا به مسیر زیر :./nginx/conf.d/سپس هر کانفیگی برای nginx داشتیم درون مسیر زیر در داخل هاست os خودمون قرار میدیم ../nginx/conf.d/app.confمثلا فایل 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; access_log off; root /var/www/public; client_max_body_size 40m; 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; } }در قسمت زیر مسیر کانتینر app که سرویس fpm داخلش ران شده را مشخص کردیم . البته این سرویس روی پورت 9000 هست که قبلا اکسپوز کردیم . fastcgi_pass app:9000;در قسمت آخر فایل داکر کامپوز هم network و volume هارو مشخص میکنیم به این صورت .#Docker Networks networks: app-network: #Volumes volumes: dbdata: driver: localنتورک app-network و volume دیتابیس تعریف شده اند . خب . حالا کامپوز فایل ما آماده شده . میتونیم کل سرویس هارو با دستور زیر اجرا کنیم . docker-compose up -d وقتی کانتینر ها ران شدند میتونیم فایل env پروژه لاراول رو تغییر بدیم . مثلا برای اطلاعات دیتابیس مقادیر زیر رو در نظر میگیریم . DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=laravel_db DB_USERNAME=YOUR USER NAME DB_PASSWORD=YOUR PASSWORDدر واقع DB_HOST رو باید db قرار بدیم چون اسم سرویس دیتابیس رو db در نظر گرفته بودیم . چون تمام سرویس های داکر داخل یک نتورک هستند پس میتونیم تمام سرویس هارو با نام سرویسشون در دسترس داشته باشیم . برای اتصال لاراول به ردیس هم میتونیم این مقادیر رو قرار بدیم .REDIS_HOST=redis REDIS_PASSWORD=ِYOUR PASSWORD REDIS_PORT=6379بعد از این که تماس سرویس ها ران شدند میتونیم با رستور زیر لاگ هر کانتینر رو مشاهده کنیم. docker logs CONTAINER_NAME از دستور زیر هم میتونیم برای باز کردن bash هر کانتینر استفاده کنیم . مثلا برای کانتینر app میتونیم اینطوری وارد شیم . docker-compose exec app bashتوجه داشته باشید که تمام دستورات artisan را باید داخل bash کانتینر app اجرا کرد . خب امیدوارم این آموزش واستون مفید واقع شده باشه . ممنون از وقتی که برای این آموزش گذاشتید .