PHP and Application Deployment
Overview
- What you’ll learn: How to install PHP and PHP-FPM on Ubuntu, integrate PHP processing with Apache and Nginx, configure PHP settings, connect to MySQL/MariaDB databases, and deploy a complete PHP application.
- Prerequisites: Lesson 22 — Apache2 Web Server, Lesson 23 — Nginx Web Server, Lesson 24 — TLS Certificates and HTTPS
- Estimated reading time: 20 minutes
Introduction
PHP is the most widely used server-side scripting language on the web, powering platforms such as WordPress, Laravel, Drupal, and Magento. While web servers like Apache and Nginx handle static files directly, they need a PHP processor to execute PHP scripts and generate dynamic content.
On modern Ubuntu systems, PHP-FPM (FastCGI Process Manager) is the standard way to run PHP. PHP-FPM manages a pool of PHP worker processes that receive requests from the web server via the FastCGI protocol, execute the PHP code, and return the output. This architecture provides better performance, resource management, and isolation compared to the older mod_php approach.
In this lesson, you will install PHP and PHP-FPM, configure integration with both Apache and Nginx, tune PHP settings for production use, set up database connectivity, and deploy a real PHP application step by step.
Installing PHP and PHP-FPM
# Install PHP-FPM and common extensions
$ sudo apt update
$ sudo apt install php-fpm php-cli php-common php-mysql php-xml
php-mbstring php-curl php-zip php-gd php-intl php-bcmath
# Check PHP version
$ php -v
PHP 8.1.2-1ubuntu2 (cli)
# Check PHP-FPM service status
$ sudo systemctl status php8.1-fpm
● php8.1-fpm.service - The PHP 8.1 FastCGI Process Manager
Active: active (running)
# List installed PHP modules
$ php -m
The PHP-FPM service name includes the version number (e.g., php8.1-fpm). Adjust commands according to your installed version.
PHP-FPM Pool Configuration
PHP-FPM manages worker processes through pool configurations. The default pool is defined in /etc/php/8.1/fpm/pool.d/www.conf:
# /etc/php/8.1/fpm/pool.d/www.conf — key settings
[www]
user = www-data
group = www-data
; Listen on a Unix socket (faster than TCP)
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
; Process manager: static, dynamic, or ondemand
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
Process manager modes:
- static: A fixed number of worker processes. Best for dedicated servers with predictable load.
- dynamic: Workers are spawned and killed based on demand, within configured limits. Good default for most servers.
- ondemand: Workers are spawned only when requests arrive and killed after idle timeout. Best for low-traffic sites sharing resources.
# Create a separate pool for a specific application
$ sudo cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/myapp.conf
# /etc/php/8.1/fpm/pool.d/myapp.conf
[myapp]
user = myapp
group = myapp
listen = /run/php/myapp.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 20
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 10
; Per-pool PHP settings
php_admin_value[error_log] = /var/log/php/myapp-error.log
php_admin_flag[log_errors] = on
php_value[memory_limit] = 256M
php_value[upload_max_filesize] = 50M
php_value[post_max_size] = 50M
# Restart PHP-FPM to apply changes
$ sudo systemctl restart php8.1-fpm
Integrating PHP-FPM with Apache
Apache connects to PHP-FPM using the proxy_fcgi module:
# Enable required modules
$ sudo a2enmod proxy_fcgi setenvif
$ sudo a2enconf php8.1-fpm
# Or configure manually in a virtual host:
<VirtualHost *:80>
ServerName myapp.example.com
DocumentRoot /var/www/myapp/public
<Directory /var/www/myapp/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch .php$>
SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/myapp-error.log
CustomLog ${APACHE_LOG_DIR}/myapp-access.log combined
</VirtualHost>
$ sudo apache2ctl configtest
$ sudo systemctl reload apache2
Integrating PHP-FPM with Nginx
Nginx passes PHP requests to PHP-FPM using the fastcgi_pass directive:
# /etc/nginx/sites-available/myapp
server {
listen 80;
server_name myapp.example.com;
root /var/www/myapp/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Deny access to hidden files
location ~ /.ht {
deny all;
}
# Deny access to sensitive files
location ~ /.(env|git) {
deny all;
}
}
$ sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl reload nginx
PHP Configuration Tuning
PHP’s main configuration file is php.ini. There are separate files for CLI and FPM:
# FPM php.ini location
$ php --ini # CLI config
$ php-fpm8.1 -i | grep "Loaded Configuration" # FPM config
# Typically: /etc/php/8.1/fpm/php.ini
# Key production settings
$ sudo nano /etc/php/8.1/fpm/php.ini
; Production-recommended settings
memory_limit = 256M
max_execution_time = 30
max_input_time = 60
upload_max_filesize = 50M
post_max_size = 50M
; Error handling — never display errors in production
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/error.log
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
; Session configuration
session.save_handler = files
session.save_path = "/var/lib/php/sessions"
session.gc_maxlifetime = 1440
; OPcache — critical for production performance
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0
# Create log directory
$ sudo mkdir -p /var/log/php
$ sudo chown www-data:www-data /var/log/php
# Restart PHP-FPM after configuration changes
$ sudo systemctl restart php8.1-fpm
Database Connectivity
Most PHP applications require a database. Here is how to set up MySQL/MariaDB connectivity:
# Install MariaDB server
$ sudo apt install mariadb-server
$ sudo mysql_secure_installation
# Create a database and user for the application
$ sudo mysql -u root
MariaDB> CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
MariaDB> CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
MariaDB> GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
MariaDB> FLUSH PRIVILEGES;
MariaDB> EXIT;
# Test PHP database connectivity
$ cat > /tmp/dbtest.php <<'EOF'
<?php
$pdo = new PDO('mysql:host=localhost;dbname=myapp_db', 'myapp_user', 'StrongPassword123!');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Database connection successful!n";
EOF
$ php /tmp/dbtest.php
Database connection successful!
$ rm /tmp/dbtest.php
Deploying a PHP Application
Here is a step-by-step example deploying a Laravel application:
# Install Composer (PHP dependency manager)
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
# Clone the application
$ cd /var/www
$ sudo git clone https://github.com/example/myapp.git
$ cd myapp
# Install dependencies
$ sudo composer install --no-dev --optimize-autoloader
# Set permissions
$ sudo chown -R www-data:www-data /var/www/myapp
$ sudo chmod -R 755 /var/www/myapp
$ sudo chmod -R 775 /var/www/myapp/storage
$ sudo chmod -R 775 /var/www/myapp/bootstrap/cache
# Configure environment
$ sudo cp .env.example .env
$ sudo nano .env # Set DB credentials, APP_URL, etc.
$ php artisan key:generate
$ php artisan migrate --force
# Optimize for production
$ php artisan config:cache
$ php artisan route:cache
$ php artisan view:cache
Key Takeaways
- PHP-FPM is the standard way to run PHP on modern Ubuntu servers, providing better performance and isolation than mod_php.
- PHP-FPM pools allow separate worker configurations per application with different users, memory limits, and log files.
- Apache uses
proxy_fcgito connect to PHP-FPM; Nginx usesfastcgi_pass. - Always disable
display_errorsin production and enable OPcache for significant performance improvements. - Use Composer for dependency management and follow the application’s deployment documentation for environment setup.
- Set proper file ownership (
www-data) and permissions, especially for writable directories like storage and cache.
What’s Next
In Lesson 26, you will learn how to configure Nginx and Apache as reverse proxies and load balancers, distributing traffic across multiple backend application servers for high availability and scalability.
繁體中文
概述
- 您將學到: 如何在 Ubuntu 上安裝 PHP 和 PHP-FPM、將 PHP 處理整合到 Apache 和 Nginx、設定 PHP 參數、連接 MySQL/MariaDB 資料庫,以及部署完整的 PHP 應用程式。
- 先決條件: 第 22 課 — Apache2 網頁伺服器、第 23 課 — Nginx 網頁伺服器、第 24 課 — TLS 憑證和 HTTPS
- 預估閱讀時間: 20 分鐘
簡介
PHP 是網頁上使用最廣泛的伺服器端腳本語言,驅動著 WordPress、Laravel、Drupal 和 Magento 等平台。在現代 Ubuntu 系統上,PHP-FPM(FastCGI 程序管理器)是執行 PHP 的標準方式。
PHP-FPM 管理一個 PHP 工作程序池,透過 FastCGI 協定從網頁伺服器接收請求、執行 PHP 程式碼並返回輸出。這種架構比舊式 mod_php 方法提供更好的效能和資源管理。
安裝 PHP 和 PHP-FPM
$ sudo apt update
$ sudo apt install php-fpm php-cli php-common php-mysql php-xml
php-mbstring php-curl php-zip php-gd php-intl
$ php -v
$ sudo systemctl status php8.1-fpm
PHP-FPM 池設定
PHP-FPM 透過池設定管理工作程序。預設池定義在 /etc/php/8.1/fpm/pool.d/www.conf:
- static: 固定數量的工作程序,適合專用伺服器。
- dynamic: 根據需求動態產生和終止工作程序。
- ondemand: 僅在請求到達時產生工作程序,適合低流量網站。
將 PHP-FPM 整合到 Apache
$ sudo a2enmod proxy_fcgi setenvif
$ sudo a2enconf php8.1-fpm
$ sudo systemctl reload apache2
將 PHP-FPM 整合到 Nginx
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
PHP 設定調整
; 生產環境建議設定
memory_limit = 256M
display_errors = Off
log_errors = On
opcache.enable = 1
opcache.memory_consumption = 128
資料庫連接
$ sudo apt install mariadb-server
$ sudo mysql_secure_installation
$ sudo mysql -u root
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
部署 PHP 應用程式
# 安裝 Composer
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
# 安裝相依套件
$ composer install --no-dev --optimize-autoloader
# 設定權限
$ sudo chown -R www-data:www-data /var/www/myapp
$ sudo chmod -R 775 /var/www/myapp/storage
重點整理
- PHP-FPM 是在現代 Ubuntu 伺服器上執行 PHP 的標準方式。
- PHP-FPM 池允許為每個應用程式單獨設定工作程序。
- Apache 使用
proxy_fcgi連接 PHP-FPM;Nginx 使用fastcgi_pass。 - 在生產環境中始終停用
display_errors並啟用 OPcache。 - 設定正確的檔案所有權和權限,特別是可寫目錄。
下一步
在第 26 課中,您將學習如何設定 Nginx 和 Apache 作為反向代理和負載均衡器。
日本語
概要
- 学習内容: Ubuntu での PHP と PHP-FPM のインストール、Apache/Nginx との PHP 処理の統合、PHP 設定、MySQL/MariaDB データベース接続、完全な PHP アプリケーションのデプロイ。
- 前提条件: レッスン 22 — Apache2 ウェブサーバー、レッスン 23 — Nginx ウェブサーバー、レッスン 24 — TLS 証明書と HTTPS
- 推定読了時間: 20 分
はじめに
PHP はウェブで最も広く使用されているサーバーサイドスクリプト言語で、WordPress、Laravel、Drupal、Magento などのプラットフォームを駆動しています。現代の Ubuntu システムでは、PHP-FPM(FastCGI Process Manager)が PHP を実行する標準的な方法です。
PHP-FPM は PHP ワーカープロセスのプールを管理し、FastCGI プロトコルを介してウェブサーバーからリクエストを受信し、PHP コードを実行して出力を返します。
PHP と PHP-FPM のインストール
$ sudo apt update
$ sudo apt install php-fpm php-cli php-common php-mysql php-xml
php-mbstring php-curl php-zip php-gd php-intl
$ php -v
$ sudo systemctl status php8.1-fpm
PHP-FPM プール設定
PHP-FPM はプール設定でワーカープロセスを管理します:
- static: 固定数のワーカープロセス。専用サーバーに最適。
- dynamic: 需要に応じてワーカーを生成・終了。大半のサーバーに適切なデフォルト。
- ondemand: リクエスト到着時のみワーカーを生成。低トラフィックサイトに最適。
Apache との PHP-FPM 統合
$ sudo a2enmod proxy_fcgi setenvif
$ sudo a2enconf php8.1-fpm
$ sudo systemctl reload apache2
Nginx との PHP-FPM 統合
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
PHP 設定チューニング
; 本番環境推奨設定
memory_limit = 256M
display_errors = Off
log_errors = On
opcache.enable = 1
opcache.memory_consumption = 128
データベース接続
$ sudo apt install mariadb-server
$ sudo mysql_secure_installation
$ sudo mysql -u root
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
PHP アプリケーションのデプロイ
# Composer をインストール
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
# 依存パッケージをインストール
$ composer install --no-dev --optimize-autoloader
# パーミッションを設定
$ sudo chown -R www-data:www-data /var/www/myapp
$ sudo chmod -R 775 /var/www/myapp/storage
重要ポイント
- PHP-FPM は現代の Ubuntu サーバーで PHP を実行する標準的な方法。
- PHP-FPM プールによりアプリケーションごとに個別のワーカー設定が可能。
- Apache は
proxy_fcgiで PHP-FPM に接続、Nginx はfastcgi_passを使用。 - 本番環境では常に
display_errorsを無効にし、OPcache を有効にする。 - 適切なファイル所有権とパーミッションを設定する(特に書き込み可能なディレクトリ)。
次のステップ
レッスン 26 では、Nginx と Apache をリバースプロキシおよびロードバランサーとして設定する方法を学びます。