Nếu như bạn đã từng code trên nhiều môi trường hệ điều hành, nhiều máy khác nhau thì chắc hẳn bạn đã từng gặp phải trường hợp conflict version cài đặt ở máy local: php, node,...
hay không tương thích giữa các hệ điều hành: ubuntu, macos, window,...
Vậy làm thế nào để giải quyết vấn đề này ?
Tại sao chúng ta không tạo nên 1 môi trường chung (hệ điều hành, phiên bản cho các ngôn ngữ sử dụng, ...)
==> Docker sẽ giúp chúng ta giải quyết vấn đề này
Trong bài này chúng ta chỉ tập chung vào vấn đề setup Docker để có được môi trường code Laravel
Một số yêu cầu cần có
- Ứng dụng laravel đã từng code: Tham khảo document larvavel
- Docker: Hướng dẫn cài đặt docker
- Docker-compose: Hướng dẫn cài đặt docker-compose
- Một số khái niệm cơ bản trong docker
Bắt đầu setup nào
Tạo docker-compose
file
docker-compose
là gì ?
Đây là file chứa tất cả các docker container cần dùng và các docker container này có thể tạo bằng một câu lệnh tương đối đơn giản kiểu như:
docker-compose -f docker-compose.prod.yml up --build
- Tạo file có tên:
docker-compose.yml
ở thư mục gốc
Chúng ta sẽ định nghĩa các container sử dụng trong file này, có 3 phần chính- nginx
- mysql
- Ứng dụng của mình
Container của laravel app được định nghĩa như sau:
Giải thích một chút về đoạn code trênversion: '2' services: # The Application app: container_name: laravel_app build: context: ./ dockerfile: development/app.dockerfile volumes: - ./storage:/var/www/storage env_file: '.env.prod' environment: - "DB_HOST=database" - "REDIS_HOST=cache"
version
: tùy theo lựa chọn của mìnhcontainer_name
: Sử dụng tên này để sau này tham chiếu đến container - có thể tùy ý lựa chọnbuild
: Sử dụng để build 1image
từdockerfile
Một số tùy chọn bổ sung:context
: Giống như đường dẫn vào bên trong thư mục sourcecode của laravel app
Ở đây, dùng./
vì hiện tại filedocker-compose
đang đặt ở thư mục gốc của laravel appdockerfile
: docker image được build từDockerfile
, thường là thêm các lệnh bổ sung sẽ được chạy trong container
Ở đây,development/app.dockerfile
nghĩa làdocker file
được để trongdevelopment
của thư mục laravel gốc
volumes
: Định nghĩa nơi lưu trữ chia sẻ giữa ứng dụng và docker container đang chạyenv_file
: nơi định nghĩa file.env
của laravelenvironment
: Khai báo các biến môi trường
NGINX Container
# The Web Server web: container_name: nginx_server build: context: ./ dockerfile: development/web.dockerfile volumes: - ./storage/logs/:/var/log/nginx ports: - 8990:80
volumes
: Ở đây ta chia sẻ folder log của laravel với log của nginxport
: Hiểu đơn giản thì chúng ta sẽ định nghĩa port mà docker container sẽ lắng nghe
Bên trái port của máy chủ, bên phải là port của docker container
MYSQL container
# The Database database: container_name: mysql_database image: mysql:5.7 volumes: - dbdata:/var/lib/mysql environment: - "MYSQL_DATABASE=Baly" - "MYSQL_USER=phpmyadmin" - "MYSQL_PASSWORD=phpmyadmin" - "MYSQL_ROOT_PASSWORD=root" ports: - 8991:3306
image
: Ở đây ta dùng luôn từ 1 image sẵn là mysql:5.7 chứ không tự định nghĩa docker file nữaports
: Ở đây mysql container sẽ lắng nghe từ cổng 8991 trên máy chủ và 3306 trên mạng của container
Tạo Dockerfiles
Ở bước này, chúng ta định nghĩa các dockerfile cho các mục vừa khai báo ở docker-compose
file vừa xong
Tạo app.dockerfile
Tạo tệp development/app.dockerfile
bên trong thư mục gốc sourcecode laravel app
FROM php:7.2-fpm
COPY composer.lock composer.json /var/www/
COPY database /var/www/database
WORKDIR /var/www
RUN apt-get update && apt-get -y install git && apt-get -y install zip
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
&& php composer-setup.php
&& php -r "unlink('composer-setup.php');"
&& php composer.phar install --no-dev --no-scripts
&& rm composer.phar
COPY . /var/www
RUN chown -R www-data:www-data
/var/www/storage
/var/www/bootstrap/cache
RUN php artisan cache:clear
RUN php artisan optimize
RUN apt-get install -y libmcrypt-dev
libmagickwand-dev --no-install-recommends
&& pecl install mcrypt-1.0.2
&& docker-php-ext-install pdo_mysql
&& docker-php-ext-enable mcrypt
RUN mv .env.prod .env
RUN php artisan optimize
From php:7.2-fpm
: Build container từ image:php:7.2-fpm
COPY
: thực thi command copy các folder tương ứng từ máy chủ vào docker containerWORKDIR
: set không gian làm việc docker container vào thẳng /var/www, sau này chạy các command ở bash thì không cầncd
vào đóRUN
: cài đặt các trình phục thuộc mà laravel cần (tương tự composer install ở máy chủ và 1 số phần khác)
Hãy lưu ý dòngif(hash_file('SHA384'...
vì mỗi lần cập nhật thì giá trị băm sẽ thay đổi, cho nên cần Get Hash ValueCOPY . /var/www
: copy toàn bộ source code vào foler làm việc
Tạo web.dockerfile
FROM nginx:1.10-alpine
ADD development/vhost.conf /etc/nginx/conf.d/default.conf
COPY public /var/www/public
Ở đây chúng ta build container từ iamge: nginx:1.10-alpine
và thay thế default.conf của nginx bằng vhost.conf
Vì vậy ta cần tạo file vhost.conf
cùng thư mục với web.dockerfile (development)
# vhost.conf
server {
listen 80;
index index.php index.html;
root /var/www/public;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
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;
}
}
Kiểm tra lại, chúng ta cần có các tệp sau:
- Root folder - docker-compose.yml và .env.prod
- development folder:
- .dockerignore
- app.dockerfile
- web.dockerfile
- vhost.conf
docker-compose up --build
Lệnh trên giúp ta tiến hành build ra các container và start chúng
Nếu mọi thứ chạy bình thường thì laravel app của chúng ta sẽ được khởi chạy trong container tại: 0.0.0.0:8990
Tổng kết
Cảm ơn các bạn đã theo dõi, mong rằng một số thông tin trên sẽ giúp các bạn có thể tự mình build 1 laravel app sử dụng Docker để có thể tránh các trường hợp conflict không mong muốn
Các thông số trong dockerfile, docker-conpose có thể còn khá khó hiểu, nhưng theo ý kiến cá nhân đối với người mới bắt đầu, ta chỉ cần hiểu mục đích nó làm gì chứ không nhất thiết phải biết cách build ra các file như vậy ngay