Docker

Sử dụng docker-compose để cài đặt laravel – nginx – mysql -php

How To Set Up Laravel, Nginx, and MySQL with Docker Compose

Giới thiệu

Trong những năm qua, Docker trở thành 1 giải pháp thường xuyên được sử dụng để triển khai nhanh các ứng dụng nhờ vào đơn giản hóa việc chạy và triển khai các ứng dụng trong container (thùng chứa). Khi chúng ta sử dụng LEMP, ví dụ, với PHP, Nginx, MysqlLaravel framework, Docker có thể đơn giản hóa quá trình thiết lập

Docker Compose đã đơn giản hóa hơn nữa quá trình phát triển bằng cách cho phép các nhà phát triển xác định cơ sở hạ tầng của họ, bao gồm các dịch vụ ứng dụng (application services), mạng (networks) và khối lượng (volums), trong một file duy nhất. Docker Compose cung cấp một giải pháp thay thế hiệu quả để chạy nhiều lệnh tạo vùng chứa docker và các lệnh chạy container của docker.

Trong hướng dẫn này, bạn sẽ xây dựng một ứng dụng web Laravel, với Nginx là máy chủ web và MySQL là cơ sở dữ liệu, tất cả bên trong các container Docker. Bạn sẽ xác định toàn bộ cấu hình  trong tệp soạn thảo docker, cùng với các tệp cấu hình cho PHP, MySQLNginx.

Nếu bạn chưa cài docker và docker-compose thì hãy xem qua bài này nhé

Cài đặt docker trên Ubuntu 18.04

Bước 1 — Tải Laravel và cài đặt các Dependencies

Ở bước này, chúng ta cài đặt Laravel, các bạn có thể vào doc của Laravel để xem lại cách cài tại đây 

Đầu tiên, các bạn vào thư mục làm việc của các bạn (ở đây tôi chọn /var/www) sau đó tiến hành clone code Laravel về với lệnh


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

Đi vào thư mục laravel-app vừa được tạo ra


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

Tiếp theo, sử dụng Docker composer image để mount (gắn kết) các thư mục mà bạn cần trong project và tránh việc phải cài Composer globally

Sử dụng -v và -rm với docker run tạo ra các container, các container này sẽ được kết nối với thư mục của bạn hiện tại trước khi bị xóa. Việc này sẽ copy thư mục laravel-app của bạn vào container và đảm bảo rằng thư mục vendor được tạo bên trong là bản copy của thư mục gốc của bạn

Cuối cùng, ta cấp quyền trên thư mục project với quyền non-root user


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

 

Bước 2 — Tạo Docker Compose File

Xây dựng các ứng dụng của bạn với Docker Compose sẽ giúp bạn đơn giản hóa việc phải thiết lập hạ tầng. Để thiết lập ứng dụng Laravel, chúng ta sẽ một file docker-compose để xác định web server, database và các service của ứng dụng.

Trong thư mục laravel-app, chúng ta tạo file docker-composer.yml với nội dung sau:

 


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

Giải thích file docker-compose.yml 1 chút, ở đây chúng ta xác định có 3 services là : app, webserver,database

  • app: định nghĩa này chứa ứng dụng Laravel và chạy 1 custom Docker image, digitalocean.com/php, cái này được chỉ ra tại Bước 4, nó thiết lập working_dir trong container tới thư mục /var/www
  • webserver: định nghĩa của dịch vụ này sẽ pull image nginx:alpine từ docker và  chạy trên cổng 80 và 443
  • db: định nghĩa của dịch vụ được pull về từ image mysql:5.7.22 từ Docker và đã xác định được 1 vài biến môi trường bao gồm cả database được thiết lập cho ứng dụng của bạn được đặt tên là laravel ( đây là name database), đồng thời kèm theo password root cho database, bạn có thể đặt tên khác cho database và đặt password mà bạn muốn. Service này sẽ map port 3306 trên host tới port 3306 trên container
  • container_name: để xác định ten của container, tương ứng với tên của dịch vụ, nếu bạn không chỉ định tên, Docker sẽ gán tên cho mỗi container đó
  • app-network: để tạo kết nối giữa các container, các dịch vụ sẽ được kết nối qua app-network
  • dbdata: là 1 volume tồn tại nội dung của folder /var/lib/mysql bên trong container. Điều này cho phép bạn dừng và khởi động service db mà không bị mất dữ liệu, ở cuối file docker-compose.yml ta cũng thấy có dbdata, với định nghĩa này, ta có thể sử dụng volumn này qua nhiều services
Dùng để mount ~/laravel-app/mysql/my.cnf trên thư mục project tới /etc/mysql/my.cnf trên container
Đầu tiên là để mount code từ thư mục project  ~/laravel-app vào thư mục /var/www nằm trên container, tiếp theo là các file config sẽ được add từ ~/laravel-app/nginx/conf.d/ vào thư mục cấu hình nginx /etc/nginx/conf.d/ trên container, việc này cho phép bạn sửa đổi config trên thư mục khi cần
app service sẽ mount thư mục ~/laravel-app, nơi chứa code ứng dụng, tới thư mục /var/www trên container, và bạn có thể map file cấu hình của PHP từ ~/laravel-app/php/local.ini tới /usr/local/etc/php/conf.d/local.ini trên container

Bước 3 — Tạo Dockerfile

các bạn tạo 1 file là Dockerfile và được lưu tại ~/laravel-app, nội dung của file như sau


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 \
    default-mysql-client \
    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"]

 

Giải thích file Dockerfile 1 chút

Đầu tiên Dockerfile tạo 1 image trên cùng của 1 Docker image là php:7.2-fpm, image này đã được cài sẵn php-fpm

RUN để thực hiện việc update, install và cấu hình bên trong 1 container, bao gồm cả việc chỉ ra user và group www

WORKDIR chỉ ra thư mục làm việc dành cho ứng dụng trên container.

Tạo một người dùng và nhóm chuyên dụng với các quyền hạn chế sẽ giảm thiểu lỗ hổng vốn có khi chạy các container Docker, vì mặc định là root. Thay vì chạy container này với quyền root, chúng tôi đã tạo user www, người có quyền truy cập đọc / ghi vào thư mục /var/www thông qua lệnh COPY và kèm theo –chown để sao chép quyền của thư mục ứng dụng .

Cuối cùng, lệnh EXPOSE hiển thị một cổng trong container, 9000, cho máy chủ php-fpm. CMD chỉ định lệnh sẽ chạy khi container được tạo. Ở đây, CMD chỉ định “php-fpm”, sẽ khởi động máy chủ.

Bước 4 — Cấu hình PHP

Bây giờ bạn xác định cơ sở hạ tầng thông qua docker-compose.yml, bạn có thể cấu hình dịch vụ PHP để hoạt động xử lý các yêu cầu đến từ Nginx

Để cấu hình PHP, bạn sẽ tạo tệp local.ini bên trong thư mục ~/laravel-app/php. Đây là tệp mà bạn đã gắn kết với /usr/local/etc/php/conf.d/local.ini bên trong vùng chứa trong Bước 2. Tạo tệp này sẽ cho phép bạn ghi đè tệp php.ini mặc định mà PHP đọc khi nó bắt đầu khởi động

Các chỉ thị upload_max_filesizepost_max_size đặt kích thước tối đa được phép cho các tệp đã tải lên và trình bày cách bạn có thể đặt cấu hình php.ini từ tệp local.ini của mình. Bạn có thể đặt bất kỳ cấu hình dành riêng cho PHP nào mà bạn muốn ghi đè vào tệp local.ini.

Step 5 — Cấu hình Nginx

Để cấu hình cho nginx, bạn tạo 1 file app.conf bên trong thư mục ~/laravel-app/nginx/conf.d/, với nội dung


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;
    }
}

Bước 6 — Cấu hình MySQL

Tạo file my.cnf bên trong thư mục ~/laravel-app/mysql với nội dung


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

Bước 7 — Chạy các container và sửa cấu hình môi trường

Bây giờ bạn đã xác định tất cả các dịch vụ của mình trong docker-compose và tạo các tệp cấu hình cho các dịch vụ này, bạn có thể khởi động các container. Tuy nhiên, là bước cuối cùng, chúng ta sẽ tạo file .env từ .env.example để xác định môi trường trong ứng dụng Laravel

cp .env.example .env

chúng ta sẽ cấu hình cụ thể khi chúng ta bắt đầu chạy container

Với tất cả các dịch vụ được xác định trong tệp docker-compose, bạn chỉ cần đưa ra một lệnh duy nhất để bắt đầu tất cả các vùng chứa, tạo khối lượng và thiết lập và kết nối các mạng:


docker-compose up -d

Khi bạn chạy docker-compose lần đầu tiên, nó sẽ tải xuống tất cả các hình ảnh Docker cần thiết. Khi hình ảnh được tải xuống và lưu trữ trong máy cục bộ của bạn, Compose sẽ tạo các thùng chứa của bạn. Cờ -d để nói rằng, việc chạy các container là chạy ngầm.

Bạn có thể sửa đổi cấu hình .env trong container bằng lệnh docker-compose exec ví dụ để mở file .env ta dùng

docker-compose exec app nano .env

ngoài ra các bạn chạy thêm

docker-compose exec app php artisan key:generate

docker-compose exec app php artisan config:cache

Kết quả các bạn sẽ thấy như sau:

 

 

Chúc các bạn thành công

Nguồn:

https://www.digitalocean.com/community/tutorials/how-to-set-up-laravel-nginx-and-mysql-with-docker-compose

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Close