Docker Compose: Xây dựng môi trường phát triển ứng dụng web - PHP, MySql
Bài đăng này đã không được cập nhật trong 3 năm
Chào mọi người!
Hôm nay sẽ tiếp tục loạt bài "Mình biết thì mình chia sẻ" của mình mong tiếp tục nhận được sự ủng hộ từ anh em
Rất xin lỗi vì sau bài viết trước Docker với lập trình viên web của mình thì mình lại ngắt quãng không thể đi luôn vào phần tìm hiểu tiếp tục kết nối với cơ sở dữ liệu. Hôm nay chúng ta sẽ cùng đi giải quyết vấn đề đó.
Bài toán
-
Mình có một project php tên là selfproject xây dựng dựa trên laravel framework. Project này làm việc với hệ quản trị CSDL là MySql.
-
Vấn đề là bây giờ mình muốn chạy nó với docker! `
Giải quyết
Cách 1
-
Theo như bài tìm hiểu lần trước mình sẽ sử dụng các images đã được chia sẻ bởi các lập trình viên khác trên dockerhub.
-
Mình sẽ sử dụng 2 images đó là tutum/apache-php cho service apache-php và mysql cho mysql server.
-
Đầu tiên mình cần tạo MySQL container trước
docker run -p 3307:3306 --name mysqlserver -e MYSQL_ROOT_PASSWORD=root -d mysql
-
Sau đó tạo web server container
docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql tutum/apache-php
-
Ở đây mình cần mở rộng hơn trong bài tìm hiểu lần trước, đó là mình có 2 container là
mysqlserver
vàselfproject-server
, để chúng có thể giao tiếp với nhau cần link web server với mysql thông qua tùy chọn--link <container name or ID>:<alias>
-
Bây giờ mở trình duyệt và thử kết quả
Lý do?
Mình quên config lại trong file .env
DB_CONNECTION=mysql
# host bên ngoài local
# DB_HOST=127.0.0.1
# Sửa trong container nên sẽ config lại
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=selfproject
DB_USERNAME=root
DB_PASSWORD=root
- Kết nối tới database trong container tạo db có tên
selfproject
. Ở command tạo MYSQL container mình cần expose port ra bên ngoài container là 3307. Do ở máy mình cổng 3306 đã được sử dụng cho ứng dụng khác.
-
Ở đây mình sử dụng công cụ trực quan mysql-workbench để thao tác với mysql, các bạn có thể dụng công cụ khác như php-myadmin...
-
Giờ vào vào trong container để
migrate
dữ liệudocker exec -it containerName/containerId bash # Với mình docker exec -it selfproject-server bash
-
Và giờ là kết quả
- Nhưng khi muốn vào đăng ký mình gặp phải
Vấn đề: không thể truy cập được url nào khác ngoài public. Khắc phục: trong container mình cần sửa lại file apache.conf đoạn
AllowOverride None
thànhAllowOverride ALL
trong<Directory /var/www/>
- Vào trong container
docker exec -it containerName/caintainerId bash
- Sử dụng vim để sửa lại file apache.conf (Do container mình đang dùng không có nano =)) )
vi /etc/apache2/apache2.conf
**Sửa như sau**
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride ALL
Require all granted
</Directory>
- Save lại và restart service apache bên trong container.
service apache2 restart
- Lúc này thì web server container này của mình sẽ bị terminate (ngắt kết nối) và mình cần start nó lại
Bên ngoài máy chủ của mình
docker start containerName/containerId
Với mình
docker start selfproject-server
Kết quả thu được
Ngon chạy rồi (hehe). Thử tương tác với db coi sao. Mình thử tạo một bài post và đây là kết quả
Các bạn thử stop cả mysqlserver với web server đi rối start lại xem còn chạy và dữ liệu ok không nhé. Với mình thì tuyệt vời!
Một số câu hỏi và vấn đề mà mình gặp khi mới bắt đầu
-
Vậy dữ liệu hắn lưu ở đâu?
Vào trong mysql container nhé và trong /var/lib/mysql/
-
Nên cẩn thận khi xóa container này nhé. Mình có thể khắc phục được vấn đề này là cũng
mount
/var/lib/mysql trong container ra một folder nào đó ngoài máy chủ của mình chẳng hạn "mysql-data" do mình tự tạo giống như mình mount folder project (nhớ nên để folder quyền user nhé, tránh để root) làm việc vào trong /var/www/html khi create web server container vậy! -
Stop tất cả các container đang chạy
docker stop $(docker ps -a -q)
-
Khi mình chỉnh sửa, làm việc với project thì sẽ gặp phải vấn đề permission do khi
mount
vào trong container thì nó sửa toàn bộ dữ liệu trong folder của mình về owner và group là www-data, chứ không còn là current user của mình hoặc root nữa. Vậy nên mình vào trong container và cấp quyền ghi cho project của mình với user là guest.# Vào trong container web server # Đi đến folder project mà bạn đã mount chmod 777 -R . # Quyền các bạn tùy chọn nói chung là dạng --7 để thằng user không phải owner có thể ghi
-
Với laravel 5.3 mình không thể chạy
php artisan
trong container mặc dù bên ngoài vẫn ok
- Lý do: laravel 5.3 yêu cầu version của php > 5.6 trong khi image mình đang dùng là tutum/apache-php với version php 5.5.9. Khá đau đầu với ông này mình mới nhìn ra được =))
- Khắc phục: Tự build image hoặc sử dụng image khác có sẵn mà phiên bản > 5.6. Với mình chọn sử dụng image được chia sẻ bởi cộng đồng docker-hub. Thay vì dùng tutum/apache-php thì dùng webdevops/php-apache (Ông này cũng có vấn đề với bản laravel 5.4 nên nếu có lỗi bạn có thể thử với nimmis/apache-php7 hoặc bất cứ ông nào mà bạn tìm thấy trên docker hub và cảm thấy phù hợp với project của mình)
Cách 2
Take it easy
với Docker compose
-
Chẳng lẽ mỗi lần code lại start từng con server một, nếu có 3 hay nhiều hơn nữa thì mệt quá, phải nhớ container name vì id là bất khả thi rồi =)). Rồi lại cần nhớ thứ tự start nữa.
- Như việc link Mysql với Apache thì cần start server MySql trước sau đó start Apache container
-
Điều đó dẫn đến việc mình bắt đầu thử sử dụng Docker compose
What is Docker composer
-
Docker compose là một công cụ cho việc định nghĩa và khởi chạy nhiều container với docker. Với compose mình sẽ khai báo nhiều container trong cùng một file và chỉ việc chạy một dòng lệnh là nó sẽ làm mọi việc start container cho mình.
-
Bạn có thể tham khảo tại đây
Sử dụng docker compose cho ứng dụng của mình
-
Cài đặt docker-compose thì các bạn cài đặt theo hướng dẫn tại trang chủ docker nhé.
-
Tạo docker compose file với tên
docker-compose.yml
-
Khai báo mysql server và web server trong compose file này
# docker-compose.yml version: "2" services: selfproject: image: tutum/apache-php links: - mysql ports: - "8888:80" networks: - back-tier volumes: - .:/var/www/html/selproject environment: - ALLOW_OVERRIDE=true hostname: selfproject cpu_shares: 512 # 0.5 CPU mem_limit: 536870912 # 512 MB RAM mysql: image: mysql ports: - "3307:3306" networks: - back-tier volumes: - ./mysql-data/:/var/lib/mysql/ environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=selfproject hostname: mysql cpu_shares: 512 # 0.5 CPU mem_limit: 536870912 # 512 MB RAM networks: back-tier:
-
Về các options trong compose file mình sẽ không nói nhiều vì nó được mô tả khá chi tiết tại Composefile reference trên trang chủ của docker
-
Giải thích chút về nội dung file compose của mình
- Trước tiên là về version sử dụng đối với docker file là version '2'. Bạn có thể tìm hiểu thêm trên trang chủ docker. Version '1' là 'legacy format', version hiện tại là '2.1' và '2' là version được khuyến khích sử dụng có một số thay đổi về options so với version '1'.
- Với service mysql:
- image sử dụng là mysql
- ports ở đây như mình đã nói với phần sử dụng command. 3306 là port được sử dụng bên trong container, 3307 được export ra bên ngoài để mình có thể xem và thao tác với dữ liệu.
- networks sử dụng là back-tier
- volumes ở đây chính là mount folder bên ngoài với bên trong container như phần sử dụng command. './mysql-data' là folder mình muốn lưu trữ dữ liệu ở bên ngoài, bạn có thể link bất kỳ tới đâu bạn muốn.
- hostname: mysql
- Với web service
- image mình sử dụ là tutum/apache-php. Lưu ý là với laravel 5.2 trở về trước nhé, hay là với project mình không yêu cầu version php > 5.6
- links tới mysql container
- networks: cũng phải sử dụng là back-tier cùng với mysql cho toàn bộ service trong compose file để các container có thể giao tiếp với nhau
- volumes: Do docker-compose.yml file này của mình đặt ngày trong folder selfproject của mình nên đường dẫn đến project bên ngoài máy chủ là "." thư mục hiện tại và mount vào "/var/www/html/selproject" trong container
-
environment: - ALLOW_OVERRIDE=true
- Như vấn đề với Override mà mình đã nói bên trên và đoạn config này giải quyết vấn đề đó.
-
OK việc cần làm là start nó
# Đi đến thư mục chứa compose file docker-compose up # Khi làm việc xong docker-compose down
-
Nhớ lưu ý tới việc quyền hạn và config nhá
Kết luận
-
Cảm ơn các bạn đã dành thời gian đọc bài viết của mình. Thời gian mình tìm hiểu về docker chưa được nhiều nên có thể có nhiều sai xót, rất mong nhận được sự góp ý từ mọi người để sửa đổi nội dung bài viết được tốt hơn.
-
Hiện tại trong tài liệu chính thức của docker compose không khuyến nghị sử dụng cho production, chỉ nên sử dụng ở môi trường development, staging, continous integration
All rights reserved