Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Cài đặt môi trường Docker cho Laravel 2019
Xin chào mọi người. Hôm nay mình xin chia sẻ về cách thiết lập môi trường Docker cho project sử dụng Laravel của cá nhân mình. Hi vọng sẽ có ích với mọi người.
Trước đây mình cũng đã có một bài chia sẻ tương tự ở đây
https://kipalog.com/posts/Thu-cai-dat-moi-truong-docker-cho-laravel
tuy nhiên hiện tại version laravel cũng hơi cũ rồi nên mình cập nhật lại ở bài viết này, cộng thêm thay đổi về cấu trúc project cho dễ cài đặt và coding hơn.
Ngoài ra thì với những bạn lần đầu cấu trúc môi trường thì các bạn có tham khảo một framework có sẵn laravel và docker là Laradock, đây là một repository khá hot về cài đặt môi trường cho project sử dụng PHP với Docker, sử dụng luôn laradock có thể tiết kiệm nhiều thời gian và công sức hơn rất nhiều. Bài viết của mình là tự xây dựng từ đầu sẽ mất công hơn 1 chút.
Thông tin về môi trường Host
Host tức là môi trường máy mà mình thao tác, thực hiện command trên đó. Môi trường khác nhau ví dụ như Windows/Linux cũng có gây 1 chút ảnh hưởng nên mình ghi lại để các bạn đối chiếu.
OS
MacOS High Sierra 10.13.6
Docker
$docker -v
Docker version 19.03.5, build 633a0ea
Docker Compose
$docker-compose -v
docker-compose version 1.24.1, build 4667896b
Môi trường dự định cài đặt
Webserver
Nginx 1.0
Database
mysql 8.0
PHP
PHP:7.4-FPM
Cấu trúc
Sau khi cài đặt xong, proẹct sẽ có cấu trúc như sau, các bạn có thể xác nhận trước để dễ hình dung.
|-- app # Docker image cho Laravel, chứa source code về Laravel
|-- composer # Docker image cho composer
|-- db # Docker image cho db
|-- docker-compose.yml
|-- web # Docker image cho web server
Bạn có thể hình dung sau khi cài đặt môi trường sẽ như sau :
Browser tương tác với hệ thống qua thành phần đầu tiên là webserver Nginx, từ đây Nginx sẽ điều hướng đến App. Phía app xử lý và trao đổi dữ liệu với database nếu cần thiết, cuối cùng là trả về response về lại Nginx và trả về browser.
Cài đặt
1. Tạo project Laravel
1.1. Tạo một directory trống
Mình đặt tên là docker_laravel_2019, bạn có thể đặt với tên tuỳ thích
$ mkdir docker_laravel_2019
$ cd docker_laravel_2019
1.2. Tạo project Laravel mới
Ta sẽ tạo một project laravel mới bằng composer.
Thông thường thì ta sẽ cần cài composer trên máy host và dùng composer để tải về project laravel mới như hướng dẫn trên offical https://laravel.com/docs/6.x/installation#installing-laravel . Tuy nhiên với mình thì so với việc dùng docker thì việc cài đặt composer nói riêng và quản lý version php hay composer trên máy host nói chung cũng hơi mất công một chút, nên mình tạo một docker container riêng cho việc này, chứa composer và install với cấu hình theo ý mình.
1.2.1. Tạo dir composer
Theo đó, mình tạo một directory mới và build một docker image về composer mới.
$ mkdir composer
Đến đây mình tạo dockerfile về composer docker image tại composer/composer.dockerfile
1.2.2. Tạo docker image composer (php)
https://github.com/mytv1/docker_laravel_2019/blob/master/composer/composer.dockerfile
composer/composer.dockerfile
FROM php:7.4-fpm
RUN apt-get update && apt-get install -y libzip-dev
# Extension zip for laravel
RUN docker-php-ext-install zip
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer global require laravel/installer
Mình dùng base image là php:7-4-fpm là bản mới nhất của php thay vì image của composer có sẵn.
Ngoài tải bản thân composer thì mình cũng require sẵn laravel/installer
, laravel installer cần thêm libzip-dev
và zip
nên mình install thêm vào ở trên. Laravel installer
này mình sẽ dùng để tải về fresh project laravel về.
1.2.3. Build composer docker image
$ docker build -t localcomposer -f ./composer/composer.dockerfile ./composer
1.2.4. Dùng docker container composer này tạo fresh laravel directory
Build thành công, ta dùng image này để tạo project laravel mới tương tự như laravel new blog
Linux :
$ docker run -it -v $(pwd):/var/www/html localcomposer:latest /root/.composer/vendor/bin/laravel new app
Window :
$ docker run -it -v ${pwd}:/var/www/html localcomposer:latest /root/.composer/vendor/bin/laravel new app
Tạo thành công, ta sẽ thấy cấu trúc directory hiện tại như sau
|-- app
|-- composer
|-- composer.dockerfile
1.3. Cấu trúc docker container Nginx
1.3.1. Tạo directory mới
$ mkdir web
1.3.2. Tạo file cấu hình nginx
Tạo web/vhost.conf
https://github.com/mytv1/docker_laravel_2019/blob/master/web/vhost.conf
server {
listen 80;
index index.php index.html;
root /var/www/public;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
proxy_set_header HTTP_AUTHORIZATION $http_authorization;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
sendfile off;
}
}
Trong đó có 1 số config cần chú ý như sau:
-
listen 80
: Webserver lắng nghe ở port 80 -
fastcgi_pass app:9000
: Cấu hình địa chỉ FastCGI server với host làapp
(mình define trong docker-composer.yml sau này), và port là9000
(default export port của docker container) -
root /var/www/public;
: Những request đến file ngoài .php như css hay js trỏ thẳng đếnpublic
, đây là directory sau này sẽ mount từ./app/public
với config trongdocker-composer.yml
Cấu trúc docker iamge nginx
Tạo web/web.dockerfile
https://github.com/mytv1/docker_laravel_2019/blob/master/web/web.dockerfile
FROM nginx:1.10
ADD vhost.conf /etc/nginx/conf.d/default.conf
Base image là nginx:1.10, khi tạo image ta copy vhost.conf vào địa chỉ cấu hình của nginx với lệnh ADD
Đến đây ta có cấu trúc directory như sau
|-- app
|-- composer
|-- web
|-- vhost.conf
|-- web.dockerfile
1.4. Tạo cấu hình Mysql
1.4.1. Tạo directory mới
$ mkdir db
1.4.2. Thiết lập cho database
Tạo ./db/my.cnf
https://github.com/mytv1/docker_laravel_2019/blob/master/db/my.cnf
[mysqld]
default-authentication-plugin = mysql_native_password
Mình dùng mysql:8.0
, ở phiên bản này thì default authentication-plugin không phải là mysql_native_password
mà là caching_sha2_password
, nói cách khác nếu ta đơn thuần access từ laravel bởi user-password có thể sẽ có báo lỗi không support authentication-plugin này.
Do đó mình thêm config này để laravel vẫn có thể access thường bằng user-password như trước.
Mình sẽ dùng image có sẵn của docker về mysql, và mount file config này vào đó.
Đến đây ta có cấu trúc directory như sau
|-- app
|-- composer
|-- web
|-- db
|-- my.conf
1.5. Cấu trúc docker container Laravel
1.5.1. Tạo dockerfile ./app/app.dockerfile
https://github.com/mytv1/docker_laravel_2019/blob/master/app/app.dockerfile
FROM php:7.4-fpm
RUN apt-get update && apt-get install -y libzip-dev
# Extension mysql driver for mysql
RUN docker-php-ext-install pdo_mysql mysqli
Base image tương tự với composer, mình chọn là php:7.4-fpm
1.5.2. Install vendor
docker run -v $(pwd)/app:/var/www/html localcomposer:latest composer install
Ta dùng composer build trên local vừa nãy để install vendor cho laravel với câu lệnh trên
1.5.3. Sửa lại thông tin biến môi trường
Ta sửa lại thông tin trong ./app/.env
2 biến sau
DB_HOST=127.0.0.1
DB_PASSWORD=
↓
DB_HOST=database
DB_PASSWORD=secret
- DB_HOST : database là tên host database mà laravel sẽ trỏ đến mà ta sẽ define trong
docker-composer.yml
sau này, thông thường là localhost nhưng lần này ta dùng docker nên sẽ cần chỉ định tên host khác. - DB_PASSWORD : password dùng để access đến database, tương tự ta sẽ chỉ định trong
docker-composer.yml
Đến đây ta có cấu trúc directory như sau
|-- app
|-- ....
|-- .env
|-- app.dockerfile
|-- ....
|-- composer
|-- web
|-- db
1.6. Tạo docker-compose.yml
docker-compose.yml là file cấu hình cho các docker-container của ta hoạt động.
Mình đề xuất nội dung như sau :
Tạo ./docker-compose.yml
https://github.com/mytv1/docker_laravel_2019/blob/master/docker-compose.yml
version: '3'
services:
# The Application
app:
build:
context: ./app/
dockerfile: app.dockerfile
working_dir: /var/www
volumes:
- ./app/:/var/www/
# The Web Server
web:
build:
context: ./web/
dockerfile: web.dockerfile
working_dir: /var/www
volumes:
- ./web/:/var/www/
- ./app/public:/var/www/public
ports:
- 8080:80
# The Database
database:
image: mysql:8.0
volumes:
- ./db/dbdata:/var/lib/mysql
- ./db/my.cnf:/etc/mysql/conf.d/my.cnf
command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci','--default-authentication-plugin=mysql_native_password']
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: secret
ports:
- "33061:3306"
volumes:
dbdata:
Như các bạn đã thực hiện ở trước đó nên chắc cũng đã biết, cấu trúc các docker container của mình như sau
-
app
: docker container chứa laravel, các xử lý về laravel thực hiện ở đây. Có một config cần chú ý là- ./app/:/var/www/
, ở đây mình đã mount app đến entry point của server là/var/www
-
web
: docker container chứa proxy server nginx, các request đến ban đầu sẽ được tiếp nhận ở đây và chuyển đến app -
database
: docker-container chứa database, cụ thể là mysql
Đến đây ta có cấu trúc directory như sau :
|-- app
|-- composer
|-- web
|-- db
|-- docker-compose.yml
2. Chạy project
Đến đây ta đã cấu trúc xong môi trường Docker cho Laravel! Chúng ta sẽ chạy lên thử với câu lệnh
$ docker-compose up
Hi vọng là các bạn có thể thấy ở http://0.0.0.0:8080 hiện ra như sau
Vậy là đến đây cài đặt môi trường đã hoàn thành! Ta có thể bắt đầu coding các tính năng khác cho project laravel.
(Option) Kiểm tra kết nối với cơ sở dữ liệu
Hiện được trang index laravel ở trên cũng chưa hẳn là kết nối đến database thành công. Ta sẽ kiểm tra lại bằng migrate
$docker-compose exec app php artisan migrate --seed
Câu lệnh yêu cầu laravel chạy migrate các bảng mặc định (về auth) kèm theo dữ liệu tạo sẵn (seeding) kiểu như master data
Kết quả khi mình chạy như sau
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.04 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.03 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.02 seconds)
Database seeding completed successfully.
Nếu chạy không có lỗi gì tức là kết nối đến database là bình thường!
3. Source code
Mình đã đưa source code lên https://github.com/mytv1/docker_laravel_2019, các bạn có thể tham khảo cụ thể trên đó.
Kết
Hi vọng bài viết của mình đã cung cấp được cho các bạn các kiến thức hữu ích về cấu trúc project Laravel bằng Docker. Cảm ơn và hẹn gặp lại các bạn ở các bài viết sau.




