Mạng network bridge trong Docker kết nối các container với nhau

Cách tạo một network trong Docker, thực hành cài đặt Apache, PHP, MySQL và kết nối chúng vào mạng, cài đặt WordPress trên Docker

Network trong Docker, liên kết mạng các container

Docker cho phép bạn tạo ra một network (giao tiếp mạng), sau đó các container kết nối vào network. Khi các container cùng một network thì chúng có thể liên lạc với nhau nhanh chóng qua tên của container và cổng (port) được lắng nghe của container trên mạng đó.

Để liệt kê các network đang có:

docker network ls

Các network được tạo ra theo một driver nào đó như bridge, none, overlay, macvlan. Trong phần này sẽ sử dụng đến bridge network: nó cho phép các container cùng network này liên lạc với nhau, cho phép gửi gói tin ra ngoài. Tạo một bridge network với tên network là name-network.

docker network create --driver bridge name-network
Mạng network bridge trong Docker kết nối các container với nhau

Khi tạo một container, ấn định nó nối vào network có tên là name-network thì thêm vào tham số --network name-netowrk trong lệnh docker run. (Ở đây mình sẽ tạo container tên B1 ấn định vào network1 và được tạo bởi image busybox )

docker run -it --name B1 --network network1 busybox
Mạng network bridge trong Docker kết nối các container với nhau

Khi một container có tên name-container đã được tạo, để thiết lập nó nối vào network có tên name-network.

docker network connect name-network name-container

Ví dụ : Kết nối network1 với container B2.

docker network connect network1 B2

Để kiểm tra hiện network đang được liên kết với những container nào bạn dùng lệch sau :

docker network inspect network1

Cổng – Port

Các kết nối mạng thông qua các cộng, để thiết lập cấu hình các cổng của container chú ý: có cổng bên trong container, có cổng mở ra bên ngoài (public), có giao thức của cổng (tpc, udp). Khi chạy container (tạo) cần thiết lập cổng thì đưa vào lệnh docker run tham số dạng sau:

docker run -p public-port:target-port/protocol ... 

Ví dụ : Ở đây mình sẽ tạo container B3 và ánh xạ cổng port 9999 của máy host vào cổng 80 của container này

docker run -it --name B3 --network network1 -p 9999:80 busybox

Kiểm tra như sau :

Chuyển tới đường dẫn /var/www , chạy lệnh httpd .

Như vậy dịch vụ httpd sẽ nhận thư mục này , bây giờ tạo thử file index.html để kiểm tra .

echo "webserver is running" > index.html

Mở trình duyệt máy tính của bạn truy cập tới IP máy host, nếu bạn lab bài này ở môi trường localhost thì truy cập 127.0.0.1:9999 nhé .

Cài LAMP với Docker

Sau đây sẽ thực hành tạo ra 3 container, chạy 3 dịch vụ khác nhau là httpd, php-fpm, mysql. Tạo một mạng bridge để liên kết những container này với nhau (giao tiếp với nhau qua cổng nội bộ httpd:80, php-fpm:9000, mysql:443). Trong đó thiết lập thêm httpd mở cổng public 8080 để ánh xạ vào 80 của nó.

Cài đặt PHP trên Docker

Chọn cài đặt php:7.4-fpm (các phiên bản khác tương tự) đây là PHP 7.4 cài đặt sẵn PHP-FPM, mặc định cho phép apache gọi đến PHP thông qua proxy với cổng 9000.

Tạo một container chạy PHP từ image php:7.4-fpm, đặt tên container này là c-php

docker run -d --name c-php -h php -v "/home/tobi/php74":/home/phpcode php:7.4-fpm

Các tham số tạo, chạy container như đã biết trong phần trước, ở đây cụ thể là:

  • -d : container sau khi tạo chạy luôn ở chế độ nền.
  • --name c-php : container tạo ra và đặt luôn cho nó tên là c-php (Tương tác với container dễ đọc hơn khi sử dụng tên thay vì phải sử dụng mã hash id, nếu không đặt tên thì docker sinh ra tên ngẫu nhiên).
  • -h php đặt tên HOSTNAME của container là php
  • -v "/home/tobi/php74":/home/phpcode thư mục trên máy host /home/tobi/php74 (với Windows đường dẫn theo OS này như "c:\path\home\tobi\php74\") được gắn vào container ở đường dẫn /home/phpcode.
  • php:7.4-fpm là image khởi tạo ra container, nếu image này chưa có nó tự động tải về.

Sau lệnh này, một container đã tạo container có tên đặt là c-php từ image php:7.4-fpm. Hãy kiểm tra tình hình các container xem sao với lệnh: docker ps -a

Như hình trên, một container có tên c-php được tạo ra, chạy với lệnh script mặc định docker-php-entrypoint, dịch vụ PHP-FPM chạy và lắng nghe ở cổng 9000. Script mặc định này mô tả trong một file Dockerfile, loại file này sẽ tìm hiểu sau. Ở đây bạn có thể xem thông tin file này kèm trong image bằng lệnh.

docker inspect php:7.4-fpm

Giờ nếu muốn nhảy vào tương tác với container này (container phải đang chạy), thì gọi lệnh bash của nó bằng cách:

docker exec -it c-php bash

Đang trong container, hãy gõ lệnh kiểm tra php version:

php -v

Kết quả hiện thị thông tin phiên bản PHP, vậy bạn đã có một container PHP rồi!. Thử tạo một script PHP có tên test.php và chạy nó từ dòng lệnh của container này.

Mở rộng: có sẵn một script có tên là docker-php-ext-configuredocker-php-ext-install để bạn cấu hình, cài các Extension cho PHP, ví dụ nếu muốn có thêm OpCache thì gõ:

docker-php-ext-configure opcache --enable-opcache && docker-php-ext-install opcache

Cài thêm mysqli – extension để kết nối PHP đến MySQL

docker-php-ext-install mysqli

Cài thêm pdo_mysql – extension để kết nối PHP đến MySQL với thư viện PDO

docker-php-ext-install pdo_mysql

File php.ini mà PHP nạp nằm ở /usr/local/etc/php, để có file ini này gõ lệnh:

cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini

Để có trình soạn thảo text vim gõ lệnh:

apt-get update && apt-get install vim

Nếu cần chỉnh sửa thiết lập nào đó, vào ini chỉnh sủa, gõ lệnh:

vi /usr/local/etc/php/php.ini

Khi cài đặt extension, thay đổi thiết lập để hiệu lực hãy khởi động lại container này bằng lệnh:

docker restart c-php

Kiểm tra các phần mở rộng đã có trong PHP bằng lệnh php -m, cái nào cần dùng còn thiếu thì cài vào theo cách như trên.

Cài đặt APACHE HTTPD trên Docker

Apache là máy chủ HTTPD rất phổ biến, nhất là các server Linux. Tải về httpd bản mới nhất:

docker pull httpd

Tạo một container httpd đặt tên là c-httpd

docker run -di -p 8080:80 -p 443:443 --name c-httpd -h httpd -v "/home/tobi/php74":/home/phpcode httpd

Trong lệnh trên, có tham số -p 8080:80 để thiết lập cổng cho container, nếu không thiết lập thì mặc định một container không mở cổng nào cả, với thiết lập trên – khi truy cập cổng 8080 trên HOST, sẽ ánh xạ vào cổng 80 của container, cổng mà máy chủ httpd đang lắng nghe.

Giờ từ trình duyệt, vào địa chỉ httpd://localhost:8080 thấy có kết quả

Vậy đã có một container – httpd đang chạy!

Muốn chỉnh sửa file config httpd.conf

  • File config tại: /usr/local/apache2/conf/httpd.conf
  • Nếu muốn cài trình soạn thảo nano gõ lệnh apt-get update && apt-get install vim

Vậy để soạn thảo config bạn gõ (nếu chưa có nano thì cài vào như ở trên) vi /usr/local/apache2/conf/httpd.conf

Thiết lập PHP Handler

Ứng dụng PHP nằm ở container có tên là c-php, Vì vậy, thêm vào httpd.conf dòng cấu hình sau để khi truy vấn đến file .php thì nó sẽ chạy PHP từ Proxy:

AddHandler "proxy:fcgi://c-php:9000" .php

Do Handler này gọi PHP thông qua proxy, nên Apache phải kích hoạt module liên quan đến proxy, mở file httpd.conf và bỏ commnet trên các dòng:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

Tiếp theo sửa doucument root để upload dữ liệu website của bạn ( ở đây đường dẫn /home/phpcode/ lúc mình tạo container nó sẽ được ánh xạ tới thư mục /home/tobi/php74 ở máy host )

Sửa xong khởi động lại apache:

apachectl -k restart

Liên kết Apache và PHP-FPM

Để hai container c-phpc-httpd liên lạc được với nhau (ví dụ từ httpd với proxy:fcgi://c-php:9000), thì ta thiết lập chúng cùng một mạng. Trước tiên, kiểm tra xem có những mạng nào!

docker network ls

Giờ ta sẽ tạo ra một mạng với Driver là bridge đặt tên là www-net (cùng cấu hình mạng Host)

docker network create --driver bridge www-net

Danh sách mạng của Docker đã có mạng www-net vừa tạo ra. Giờ ta thiết lập container c-phpc-httpd nối vào mạng này.

docker network connect www-net c-php
docker network connect www-net c-httpd

Kiểm tra thông tin mạng www-net

docker network inspect www-net

Thấy có đoạn thông tin

Như vậy 2 container trên đã cùng một network với địa chỉ IP cho từng container. Hai container này đã có thể liên lạc với nhau qua giao tiếp mạng, bạn có thể kiểm tra bằng cách vào container này và dùng lệnh ping đến IP của container kia.

Chú ý để có lệnh ping cần cài đặt :

apt-get update && apt-get install iputils-ping -y

Hãy tạo file /home/phpcode/www/info.php

vi /home/phpcode/info.php

Nhập vào nội dung:

<?php

phpinfo();

?>

Lưu lại, và từ máy Host vào trình duyệt với địa chỉ, http://localhost:8080/info.php, thấy nội dung sau:


Như vậy đã hoàn thành thiết lập Apache – PHP trên 2 container khác nhau, chia sẻ dữ liệu và cùng một mạng

Cài đặt MySQL

Trong phần này sẽ tạo và cài đặt mysql trên một container để cuối cùng có bộ ba container Apache HTTP – PHP 7.4 – MySQL 8, như vậy có một webserver hoàn chỉnh để cài đặt, phát triển các ứng dụng web

Đây là mysql 8, mặc định không sử dụng plugin mysql_native_password, để các ứng dụng thông dụng kết nối dễ dàng tương thích bạn có thể chỉnh file cấu hình để sử dụng loại plugin này.

Đầu tiên mình sẽ tạo container mysql và cp file `/etc/my.cnf` từ container mysql ra máy host ( ở đây mình dùng –rm để container sẽ được xoá ngay xong khi tạo )

docker run --rm -v /home/tobi/:/home/mycode mysql cp  /etc/my.cnf /home/mycode

Lúc này ở máy host tại đường dẫn /home/tobi/ sẽ có file my.cnf được copy từ container mysql ra

Các bạn mở file này và thêm dòng sau vào cuối file rồi lưu lại nhé :

default-authentication-plugin=mysql_native_password

Tạo, chạy container từ image mysql (image này nếu chưa có ở local, nó sẽ tự tải về), đặt tên là c-mysql

docker run -it -d --network www-net --name c-mysql -v /home/tobi/my.cnf:/etc/my.cnf -v /home/tobi/db:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=abc123 mysql

Các tham số của lệnh trên:

  • --network www-net container sẽ kết nối với mạng có tên www-net (cùng mạng với c-php, c-httpd)
  • -e MYSQL_ROOT_PASSWORD=abc123 đặt password cho user root, quản trị mysql là abc123
  • -v /home/tobi/db:/var/lib/mysql nơi lưu trữ các database là ở thư mục /home/tobi/db của máy Host, làm điểu này để có không mất db khi cần xóa container, hoặc khi cần sử dụng lại các db cũ.
  • -v /home/tobi/my.cnf:/etc/my.cnf là sử dụng file my.cnf đã điều chỉnh để tạo container

Sau khi tạo xong các bạn có thể vào container với lệnh :

docker exec -it c-mysql bash

Truy cập vào môi trường của mysql với cú pháp và nhập password đã gán ở trên là abc123 nhé.

mysql -u root -p

Thử thực hành vào container này và quản trị tạo một user, tạo một db

#Từ dấu nhắc MySQL, Tạo một user tên testuser với password là testpass
CREATE USER 'testuser'@'%' IDENTIFIED BY 'testpass';
#Tạo db có tên db_testdb
create database db_testdb;
#Cấp quyền cho user testuser trên db - db_testdb
GRANT ALL PRIVILEGES ON db_testdb.* TO 'testuser'@'%';
flush privileges;
#Xem các database đang có, kết quả có db bạn vừa tạo
show database;
#Ra khỏi MySQL Server
exit;

Đến đây đã hoàn hàm xây dựng xong các Container với 3 thành phần: APACHE HTTPDMYSQLPHP để phát triển và chạy các ứng dụng Web. Sau đây sẽ là ví dụ cài đặt WordPress

Cài đặt WordPress trên Docker

Ta sẽ cấu hình để chạy một tên miền ảo, ví dụ này chọn quyenlt.com, trước tiên vào chỉnh file host của máy tại /etc/host (trên Windows tại C:\Windows\System32\drivers\etc\hosts), nếu ở môi trường internet tức máy host là VPS , bạn có thể dùng domain trỏ về IP VPS luôn nhé :

Tải WordPress (Download WordPress) về, giải nén vào thư mục máy host /mycode/php/quyenlt.com (Tương ứng chính là thư mục /home/phpcode/quyenlt.com trong container). Tiếp theo vào container c-httpd, tạo một VirtualHost cho tên miền này, cấu hình để thư mục làm việc là /home/phpcode/quyenlt.com/:

Mở httpd.conf thêm vào cuối

<VirtualHost *:80>
    ServerName quyenlt.com
    ServerAdmin [email protected]
    DocumentRoot /home/phpcode/quyenlt.com/
    CustomLog /dev/null combined
    #LogLevel Debug
    ErrorLog /home/phpcode/quyenlt.com/error.log
    <Directory /home/phpcode/quyenlt.com/>
        Options -Indexes -ExecCGI +FollowSymLinks -SymLinksIfOwnerMatch
        DirectoryIndex index.php
        Require all granted
        AllowOverride None
    </Directory>
</VirtualHost>

Lưu lại và khởi động lại c-httpd (apache).

apachectl -k restart

Tới đây mọi người tải wordpress mặc định về thì sẽ có giao diện để config database, ở đây chỉ cần lưu ý

/** MySQL hostname: tên của container chứa MySQL Server hoặc IP của container c-mysql cũng được nhé*/
define( 'DB_HOST', 'c-mysql' );

Còn với trường hợp các bạn đã có mã nguồn, và muốn import database .

Đầu tiên copy file .sql từ máy host vào trong container này :

docker cp /home/tobi/php74/quyenlt.com/tobic_demo-2024-04-05-ff0c557.sql c-mysql:/home/tobic_demo-2024-04-05-ff0c557.sql

Truy cập vào container c-mysql và chạy lệnh sau để import .

mysql -u testuser -p db_testdb < /home/tobic_demo-2024-04-05-ff0c557.sql

Vậy là một trang WordPess đã hoạt động thành công, điều đó chứng tỏ 3 container độc lập ở trên đã kết nối lại với nhau chạy ứng dụng. Mặc dùng có thể dùng đến file Dockerfile, quá trình tạo các container như trên nhanh và đơn giản hơn, nhưng ở thời điểm đang tìm hiểu hãy thực hiện thủ công như vậy sẽ nắm rõ cách thức hoạt động hơn.

< Bài trước. Bài sau.>

Picture of Tobi

Tobi

Chào mọi người, mình là Quyền - hiện đang công tác tại Phòng Kỹ thuật AZDIGI. Trong quá trình làm việc mình có cơ hội được tiếp xúc với khá nhiều các vấn đề liên quan đến Website/Hosting/VPS/Server, do đó mình viết lại các hướng dẫn này nhằm chia sẻ kiến thức, cũng như tạo một môi trường để chúng ta giao lưu và học hỏi lẫn nhau, trau dồi thêm nhiều kiến thức bổ ích hơn nữa.