Chúng ta đã tự build một server cho dự án laravel, bằng cách cài đặt các service trực tiếp trên server. Hôm nay chúng ta sẽ làm điều này sử dụng docker compose. Để sử dụng được docker compose thì việc đầu tiên cần làm là cài đặt docker và docker compose trên server. Sau đó cấu hình các dịch vụ sử dụng docker compose
Tạo file docker-compose.yml
để khai báo các service cần thiết cho dự án
version: "3.7"
networks:
backend:
services:
nginx:
build:
context: .
dockerfile: docker/Dockerfile.nginx
args:
PHP_FPM_SERVER: php
PHP_FPM_PORT: 9000
ports:
- ${DOCKER_NGINX_PORT}:80
- 443:443
depends_on:
- app
links:
- app
volumes:
- .:/var/www/html
- /etc/ssl:/etc/ssl
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
app:
build:
context: .
dockerfile: docker/Dockerfile
args:
XDEBUG: "true"
volumes:
- .:/var/www/html
- ./docker/php.ini:/usr/local/etc/php/conf.d/php.ini
links:
- db
networks:
- backend
db:
image: mysql:8.1
restart: unless-stopped
ports: []
expose:
- 3306
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: root
volumes:
- ./db_mysql:/var/lib/mysql/
etworks:
- backend
Chúng ta sẽ build 3 container: nginx, app và db để chạy ứng dụng laravel. Chú ý các dịch vụ app và db chúng ta không được mở post ra ngoài để bảo mật cho dự án, chỉ public post 80 và 443 của nginx. Nếu mở post ra ngoài sẽ rất dễ bị hack.
Tạo thư mục docker
cùng cấp với file docker-compose.yml
để định nghĩa dockerfile cho container nginx và app. Đọc bài viết tạo dockerfile cho cho dự án laravel để lấy dockerfile cho container app. Tạo dockerfile cho container nginx
FROM nginx:1.19.2-alpine
ARG PHP_FPM_SERVER=127.0.0.1
ARG PHP_FPM_PORT=9000
COPY docker/nginx.conf /tmp/nginx.conf
RUN envsubst '$PHP_FPM_SERVER $PHP_FPM_PORT' < /tmp/nginx.conf > /etc/nginx/conf.d/default.conf
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
Tạo file docker/nginx.conf
để cấu hình nginx local không sử dụng ssl
server {
listen 80;
server_name _;
root /var/www/html/public;
client_max_body_size 650M;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location / {
try_files $uri $uri/ /index.php$is_args$args;
if ($request_method = OPTIONS) {
return 204;
}
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Expose-Headers Content-Length;
add_header Access-Control-Allow-Headers *;
add_header Access-Control-Allow-Methods *;
autoindex off;
index index.php;
}
location ~ \.php$ {
set $path_info $fastcgi_path_info;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass $PHP_FPM_SERVER:$PHP_FPM_PORT;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param PHP_VALUE "upload_max_filesize=650M \n post_max_size=650M";
fastcgi_read_timeout 300s;
}
}
Tạo file docker/nginx.conf
để cấu hình nginx server sử dụng ssl
# HTTP -> HTTPS Redirect
server {
listen 80;
server_name demo.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
# HTTPS Configuration
server {
listen 443 ssl;
server_name demo.com;
root /var/www/html/public;
# SSL Certificate
ssl_certificate /etc/ssl/certificate.crt;
ssl_certificate_key /etc/ssl/private.key;
# SSL Options
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
client_max_body_size 650M;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location / {
try_files $uri $uri/ /index.php$is_args$args;
if ($request_method = OPTIONS) {
return 204;
}
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Expose-Headers Content-Length;
add_header Access-Control-Allow-Headers *;
add_header Access-Control-Allow-Methods *;
autoindex off;
index index.php;
}
location ~ \.php$ {
set $path_info $fastcgi_path_info;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param PHP_VALUE "upload_max_filesize=650M \n post_max_size=650M";
fastcgi_read_timeout 300s;
}
}
Để đăng kí ssl cho server chúng ta sẽ sử dụng let's encrypt certbot. Chúng ta sẽ đăng kí key ssl ở server trong thư mục /etc/ssl
sau đó mount key vào container nginx để web có thể chạy được ssl.
Thêm file docker/php.ini
cấu hình cho php
[PHP]
post_max_size = 650M
upload_max_filesize = 650M
variables_order = EGPCS
max_multipart_body_parts = 5000
max_input_vars = 5000
Để chạy các container trên server chúng ta chạy command sau
// Cd to workspace
// Build docker image
docker-composer build
// Run container
docker-compose up -d
// Run container with special file
docker-compose -f docker-compose.dev.yml up -d
// Stop special service
docker-compose stop [service_name]
// Start special service
docker-compose start [service_name]
// Check log
docker-compose logs -f [service_name]
// Access to container
docker-compose exec app bash
docker-compose -f docker-compose.dev.yml exec app bash
Làm sao để update thư viện, migration, seed khi code được update
// Khi code có update thư viện
docker-compose exec [service_name] composer install
// Migrate db
docker-compose exec [service_name] php artisan migrate
Thêm script deploy khi sử dụng jenkin khi deploy code to server
#!/bin/bash
# Execute commands remotely via SSH without TTY allocation
ssh demo-app << 'SSH_EOF'
# Commands to run on the remote server
cd ~/var/www/html/demo
git pull
docker-compose exec app sh -c 'composer install && php artisan migrate && php artisan db:seed && php artisan optimize:clear && php artisan cache:clear'
SSH_EOF
Như vậy là chúng ta đã thiết lập xong docker để chạy dự án laravel. Thiết lập thông qua docker sẽ giúp tiết kiệm thời gian hơn cài trực tiếp trên server. Nhưng cần chú ý đến việc mở post đúng cách. Rất nhiều người đã bị hack drop database khi mở post 3306 ra ngoài. Thanks for reading...