|

Triển khai PHP Apache Httpd và MySQL bằng Docker

Trong môi trường phát triển web hiện đại, việc triển khai PHP Apache Httpd và MySQL bằng Docker Compose để là một giải pháp mạnh mẽ, giúp tối ưu hóa hiệu suất và khả năng mở rộng. PHP FPM cho phép xử lý các yêu cầu web nhanh chóng, trong khi Apache httpd đảm bảo phân phối nội dung PHP trên web một cách hiệu quả. Khi kết hợp với MySQL và phpMyAdmin, bạn có một hệ thống hoàn chỉnh để phát triển và quản lý ứng dụng web động.

Bài viết này sẽ hướng dẫn bạn từng bước triển khai ứng dụng PHP FPM với Apache httpd và MySQL bằng Docker Compose. Bạn sẽ học cách:

  • Xây dựng image PHP FPM tùy chỉnh với các tiện ích mở rộng như mysqli, pdo_mysql, và xdebug.
  • Cấu hình Apache httpd để xử lý các tệp PHP thông qua FPM.
  • Tích hợp MySQL và phpMyAdmin để quản lý cơ sở dữ liệu.
  • Tối ưu hóa cấu hình Docker Compose để đảm bảo hiệu suất và bảo mật.

Ngoài ra, tôi sẽ chia sẻ các lưu ý cá nhân, góp ý cải tiến và mẹo thực tế dựa trên kinh nghiệm DevOps để giúp bạn triển khai hệ thống này một cách hiệu quả và an toàn.


PHP FPM, Apache httpd và Docker Compose là gì?

  • PHP FPM: Là một trình quản lý quy trình FastCGI, tối ưu hóa việc xử lý các yêu cầu PHP, giúp ứng dụng web đạt hiệu suất cao và khả năng mở rộng tốt.
  • Apache httpd: Máy chủ web phổ biến, được sử dụng để phục vụ nội dung PHP trên web thông qua tích hợp với PHP FPM.
  • Docker Compose: Công cụ quản lý nhiều container, giúp định nghĩa và chạy các dịch vụ như PHP FPM, Apache httpd, MySQL, và phpMyAdmin trong một cấu hình duy nhất.

Sự kết hợp này tạo ra một môi trường phát triển mạnh mẽ, dễ dàng triển khai và bảo trì.


Điều kiện tiên quyết

Trước khi bắt đầu, hãy đảm bảo bạn có:

  • DockerDocker Compose được cài đặt trên máy tính (Hướng dẫn cài đặt Docker).
  • Kiến thức cơ bản về PHP, MySQL, và cách viết Dockerfile.
  • Cấu trúc thư mục dự án như sau:
apache-php-fpm-app/
├── Dockerfile
├── docker-compose.yml
├── apache/
   ├── apache.vhost.conf
   └── Dockerfile
└── app/
    └── index.php
  • Dockerfile: Cấu hình image PHP FPM với các tiện ích mở rộng cần thiết.
  • docker-compose.yml: Định nghĩa các dịch vụ (PHP FPM, Apache httpd, MySQL, phpMyAdmin).
  • apache/apache.vhost.conf: Cấu hình Virtual Host cho Apache.
  • apache/Dockerfile: Cấu hình image Apache httpd.
  • app/index.php: Mã nguồn ứng dụng PHP.

Tạo image PHP FPM bằng Dockerfile

File Dockerfile định nghĩa cách xây dựng image PHP FPM tùy chỉnh. Dưới đây là cấu hình được tối ưu hóa, bao gồm các tiện ích mở rộng như mysqli, pdo_mysql, bcmath, xdebug, và hỗ trợ Composer:

# Sử dụng image PHP FPM chính thức
FROM php:8.2-fpm

# Cài đặt các gói phụ thuộc và tiện ích mở rộng
RUN apt-get update && apt-get install -y \
    git \
    libicu-dev \
    && docker-php-ext-configure bcmath \
    && docker-php-ext-install -j$(nproc) \
        mysqli \
        pdo \
        pdo_mysql \
        bcmath \
        intl

# Cài đặt Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer

# Enable Apache modules
RUN a2enmod rewrite

# Cài đặt Xdebug (tùy chọn, dùng để debug)
COPY xdebug-2.5.4.tgz /usr/src/php/ext/xdebug.tgz
RUN tar -xf /usr/src/php/ext/xdebug.tgz -C /usr/src/php/ext/ && \
    rm /usr/src/php/ext/xdebug.tgz && \
    docker-php-ext-install xdebug-2.5.4
COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini

# Hỗ trợ ionCube (tùy chọn, bỏ comment nếu cần)
# COPY ioncube/ioncube_loader_lin_5.6.so /usr/lib/php5/20131226/ioncube_loader_lin_5.6.so
# COPY ioncube.ini /usr/local/etc/php/php.ini

# Dọn dẹp để giảm kích thước image
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

Giải thích:

  • Image cơ sở: Sử dụng php:8.2-fpm từ Docker Hub. Bạn có thể thay đổi phiên bản PHP (5.3, 5.6, 7.0, 7.4, 8.0, 8.1, 8.2, v.v.) tùy theo yêu cầu.
  • Tiện ích mở rộng: Cài đặt mysqli, pdo_mysql để kết nối MySQL, bcmath cho tính toán chính xác, và intl cho xử lý quốc tế hóa.
  • Composer: Công cụ quản lý phụ thuộc PHP, cần thiết cho các dự án hiện đại.
  • Xdebug: Hỗ trợ debug ứng dụng PHP (tùy chọn, chỉ nên bật trong môi trường phát triển).
  • ionCube: Hỗ trợ mã hóa PHP (bỏ comment nếu cần).
  • Dọn dẹp: Xóa cache apt để giảm kích thước image.

Cấu hình Apache httpd bằng Virtual Host và Dockerfile

1. Cấu hình Virtual Host (apache/apache.vhost.conf)

File apache.vhost.conf định nghĩa cách Apache xử lý các tệp PHP thông qua PHP FPM:

ServerName localhost

<VirtualHost *:80>
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php-fpm:9000/var/www/html/$1
    DocumentRoot /var/www/html/
    
    <Directory /var/www/html/>
        DirectoryIndex index.php
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    CustomLog /proc/self/fd/1 common
    ErrorLog /proc/self/fd/2
</VirtualHost>

Giải thích:

  • ProxyPassMatch: Chuyển tiếp các yêu cầu PHP đến container PHP FPM (được đặt tên là php-fpm trong docker-compose.yml) qua cổng 9000.
  • DocumentRoot: Thư mục /var/www/html/ chứa mã nguồn PHP.
  • DirectoryIndex: Đặt index.php làm tệp mặc định.
  • CustomLog/ErrorLog: Ghi log để hỗ trợ debug.

2. Tạo image Apache httpd (apache/Dockerfile)

# Sử dụng image Apache httpd chính thức
FROM httpd:2.4

# Sao chép cấu hình Virtual Host
COPY ./apache/apache.vhost.conf /usr/local/apache2/conf/extra/apache.vhost.conf

# Kích hoạt các module cần thiết
RUN sed -i \
    -e '/#LoadModule deflate_module/s/^#//g' \
    -e '/#LoadModule proxy_module/s/^#//g' \
    -e '/#LoadModule proxy_fcgi_module/s/^#//g' \
    /usr/local/apache2/conf/httpd.conf

# Thêm cấu hình Virtual Host vào file chính
RUN echo "Include /usr/local/apache2/conf/extra/apache.vhost.conf" >> /usr/local/apache2/conf/httpd.conf

Giải thích:

  • Image cơ sở: Sử dụng httpd:2.4 từ Docker Hub.
  • Module: Kích hoạt deflate (nén dữ liệu), proxy, và proxy_fcgi để hỗ trợ PHP FPM.
  • Virtual Host: Tích hợp file apache.vhost.conf vào cấu hình Apache.

Tạo và chạy ứng dụng PHP với Docker Compose

1. Tạo tệp PHP thử nghiệm (app/index.php)

Tạo tệp index.php để kiểm tra ứng dụng:

<?php
echo "Hello, Docker! PHP is Now Up and Running. PHP version: " . phpversion();
phpinfo();
?>

Tệp này hiển thị phiên bản PHP và thông tin hệ thống khi truy cập.

2. Cấu hình docker-compose.yml

File docker-compose.yml định nghĩa các dịch vụ PHP FPM, Apache httpd, MySQL, và phpMyAdmin:

services:
  php-fpm:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./app:/var/www/html
    depends_on:
      - mysql-db

  apache-httpd:
    build:
      context: .
      dockerfile: ./apache/Dockerfile
    volumes:
      - ./app:/var/www/html
    ports:
      - "8080:80"
    depends_on:
      - php-fpm
      - mysql-db

  mysql-db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: test_database
      MYSQL_USER: db_user
      MYSQL_PASSWORD: password
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: mysql-db
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "8081:80"
    depends_on:
      - mysql-db

volumes:
  mysql-data:

Giải thích:

  • php-fpm: Xây dựng image từ Dockerfile, ánh xạ thư mục ./app vào /var/www/html.
  • apache-httpd: Xây dựng image từ apache/Dockerfile, mở cổng 8080 để truy cập web.
  • mysql-db: Sử dụng image mysql:8.0, tạo cơ sở dữ liệu test_database với người dùng db_user.
  • phpmyadmin: Cung cấp giao diện quản lý MySQL, truy cập qua cổng 8081.
  • Volumes: Sử dụng volume mysql-data để lưu trữ dữ liệu MySQL, đảm bảo dữ liệu không bị mất khi container dừng.

3. Chạy ứng dụng

Chạy lệnh sau để xây dựng và khởi động các container:

docker-compose up --build -d
  • Truy cập ứng dụng tại http://localhost:8080/ để xem kết quả từ index.php.
  • Truy cập phpMyAdmin tại http://localhost:8081/ với tài khoản root và mật khẩu password.

Kết nối PHP với MySQL

Cập nhật app/index.php để kiểm tra kết nối với MySQL:

<?php
$host = 'mysql-db';
$user = 'db_user';
$pass = 'password';
$db = 'test_database';

$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die("Kết nối thất bại: " . $conn->connect_error);
}

echo "Kết nối MySQL thành công";

$conn->close();
?>

Giải thích:

  • Host: Sử dụng tên dịch vụ mysql-db (không phải localhost) vì các container giao tiếp qua mạng Docker.
  • mysqli: Được cài đặt trong Dockerfile để hỗ trợ kết nối MySQL.

Chạy lại lệnh để cập nhật:

docker-compose up --build -d

Ý kiến cá nhân và lưu ý triển khai

1. Lưu ý về bảo mật

Mật khẩu MySQL yếu: Trong ví dụ, mật khẩu password dễ bị đoán. Trong môi trường sản xuất, sử dụng mật khẩu mạnh và lưu trữ trong file .env:

MYSQL_ROOT_PASSWORD=your_strong_password
MYSQL_USER_PASSWORD=another_strong_password

Tham chiếu trong docker-compose.yml:

environment:
  MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
  MYSQL_PASSWORD: ${MYSQL_USER_PASSWORD}

Xdebug: Chỉ nên bật trong môi trường phát triển vì nó làm giảm hiệu suất. Trong sản xuất, bỏ phần cài đặt Xdebug trong Dockerfile.

Cổng công khai: Cổng 3306 (MySQL) không nên mở công khai trong sản xuất. Xóa ports: – “3306:3306” và chỉ cho phép phpMyAdmin hoặc PHP FPM truy cập MySQL qua mạng nội bộ Docker.

2. Tối ưu hóa hiệu suất

Tăng số lượng worker PHP FPM: Trong môi trường tải cao, chỉnh sửa file /usr/local/etc/php-fpm.d/www.conf trong container PHP FPM để tăng số lượng worker:

pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20

Nén dữ liệu Apache: Module deflate đã được bật, nhưng bạn có thể tối ưu thêm bằng cách cấu hình nén cho các loại tệp cụ thể trong apache.vhost.conf:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
</IfModule>

3. Góp ý cải tiến

Tích hợp Redis: Để tăng tốc độ xử lý, thêm container Redis cho cache:

redis:
  image: redis:7.0
  ports:
    - "6379:6379"

Cài đặt tiện ích mở rộng redis trong Dockerfile:

RUN pecl install redis && docker-php-ext-enable redis

Sử dụng Watchtower: Như đã thảo luận trước đó, tích hợp Watchtower để tự động cập nhật container, đảm bảo bạn luôn sử dụng phiên bản mới nhất của PHP, Apache, và MySQL.

Giám sát và log: Tích hợp công cụ như Prometheus hoặc ELK Stack để giám sát hiệu suất và thu thập log từ Apache, PHP FPM, và MySQL.

4. Mẹo thực tế

Sao lưu dữ liệu: Định kỳ sao lưu volume mysql-data để tránh mất dữ liệu:

docker run --rm -v mysql-data:/data -v $(pwd):/backup busybox tar cvf /backup/mysql-backup.tar /data

Kiểm tra trước khi triển khai: Chạy hệ thống trong môi trường staging để kiểm tra tính tương thích giữa các phiên bản PHP, MySQL, và ứng dụng.

Tài liệu tham khảo: Xem thêm các hướng dẫn về PHP FPM với NGINX hoặc PHP với PostgreSQL để so sánh các cách triển khai.


Kết luận

Triển khai PHP FPM với Apache httpd và MySQL bằng Docker Compose là một giải pháp mạnh mẽ cho các ứng dụng web động. Với cấu hình được tối ưu hóa trong bài, bạn có thể dễ dàng xây dựng, chạy, và quản lý ứng dụng PHP trong môi trường container hóa. Bằng cách áp dụng các lưu ý bảo mật, tối ưu hóa hiệu suất, và tích hợp các công cụ như Redis hoặc Watchtower, bạn sẽ tạo ra một hệ thống đáng tin cậy và dễ bảo trì.

Hãy thử triển khai hệ thống này trong dự án của bạn và chia sẻ trải nghiệm! Nếu bạn cần hỗ trợ thêm về DevOps, Docker, hoặc các công cụ khác, hãy để lại câu hỏi trong phần bình luận.

Bài viết liên quan

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

For security, use of CloudFlare's Turnstile service is required which is subject to the CloudFlare Privacy Policy and Terms of Use.