Hướng dẫn docker-compose php mysql - docker-soạn php mysql

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 emMì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! `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à

      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    5 và
      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    6, để 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
      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    7

  • 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
      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    8. Ở 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 để

      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    9 dữ liệu

      docker 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

    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
0 thành
    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
1 trong
    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
2

  • 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**

    
    Options Indexes FollowSymLinks
    AllowOverride ALL
    Require all granted
    
  • 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!

    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
3

  • 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

        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
    
    4 /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!khắc phục được vấn đề này là cũng
        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
    
    4 /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 run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    0
  • 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

        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
    
    4 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.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.

      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    1
  • Với laravel 5.3 mình không thể chạy

        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
    
    6 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 =]]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]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

    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
7 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 composeDocker 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. 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

        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
    
    8

  • Khai báo mysql server và web server trong compose file này

      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    2
  • 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
      •   docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
        
        3
      • 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ó

      docker run -tid -p 9000:80 -v ~/www/sites/FrProject/Github/selfproject:/var/www/html --name selfproject-server --link mysqlserver:mysql  tutum/apache-php
    
    4
  • 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

Bài Viết Liên Quan

Chủ Đề