Triển Khai Laravel Lên AWS (Phần 2): EC2 với Amazon Linux 2023 — Nginx + PHP-FPM Từ Đầu

· 6 min read

Phần 1, chúng ta đã thiết lập VPC, subnets, và security groups. Giờ hãy khởi chạy server thực và chạy Laravel trên đó.

Khởi Chạy EC2 Instance

Qua AWS Console

  1. Vào EC2 → Launch Instance
  2. Cấu hình:
Thiết lập Giá trị
Name laravel-web-01
AMI Amazon Linux 2023
Instance type t3.small (2 vCPU, 2GB RAM)
Key pair laravel-production
VPC laravel-production
Subnet laravel-public-a
Auto-assign public IP Enable
Security group laravel-ec2-sg
IAM instance profile laravel-ec2-profile
Storage 20 GB gp3

Qua AWS CLI

aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t3.small \
  --key-name laravel-production \
  --subnet-id subnet-public-a \
  --security-group-ids sg-ec2 \
  --iam-instance-profile Name=laravel-ec2-profile \
  --block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=laravel-web-01}]' \
  --associate-public-ip-address

SSH Vào Server

ssh -i laravel-production.pem ec2-user@<PUBLIC_IP>

Mẹo: Thêm vào ~/.ssh/config:

Host laravel-prod
    HostName <PUBLIC_IP>
    User ec2-user
    IdentityFile ~/.ssh/laravel-production.pem

Rồi chỉ cần: ssh laravel-prod

Thiết Lập Hệ Thống

# Cập nhật hệ thống
sudo dnf update -y

# Đặt múi giờ
sudo timedatectl set-timezone Asia/Tokyo

# Cài công cụ thiết yếu
sudo dnf install -y git vim htop unzip tar wget jq

Cài Đặt Nginx

sudo dnf install -y nginx
sudo systemctl enable nginx
sudo systemctl start nginx

Cài Đặt PHP 8.4

# Cài PHP 8.4 và các extensions cần thiết
sudo dnf install -y \
  php8.4-fpm \
  php8.4-cli \
  php8.4-common \
  php8.4-mbstring \
  php8.4-xml \
  php8.4-curl \
  php8.4-zip \
  php8.4-gd \
  php8.4-intl \
  php8.4-bcmath \
  php8.4-mysqlnd \
  php8.4-pdo \
  php8.4-opcache \
  php8.4-redis \
  php8.4-sodium

Lưu ý: Nếu PHP 8.4 không có trong repo mặc định, dùng Remi repository:

sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.4 -y
sudo dnf install -y php-fpm php-cli php-common php-mbstring php-xml \
  php-curl php-zip php-gd php-intl php-bcmath php-mysqlnd php-pdo \
  php-opcache php-redis php-sodium

Cấu Hình PHP-FPM

sudo vim /etc/php-fpm.d/www.conf
; Chạy với user nginx
user = nginx
group = nginx

; Dùng Unix socket (nhanh hơn TCP)
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

; Quản lý process
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 500

Cấu Hình php.ini Cho Production

; Cài đặt production
memory_limit = 256M
upload_max_filesize = 50M
post_max_size = 50M
max_execution_time = 60

; Bảo mật
expose_php = Off
display_errors = Off
log_errors = On

; OPcache (quan trọng cho hiệu năng)
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0     ; Tắt trong production!

Quan trọng: opcache.validate_timestamps = 0 nghĩa là PHP không kiểm tra file có thay đổi không. Tăng hiệu năng rất lớn nhưng cần restart PHP-FPM sau mỗi lần deploy. Script deploy ở Phần 5 tự động xử lý việc này.

sudo systemctl enable php-fpm
sudo systemctl start php-fpm

Cài Đặt Composer & Node.js

# Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Node.js 20 LTS
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf install -y nodejs

Cấu Hình Nginx Cho Laravel

sudo vim /etc/nginx/conf.d/laravel.conf
server {
    listen 80;
    server_name your-domain.com;
    root /var/www/laravel/current/public;

    index index.php index.html;
    charset utf-8;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript
               text/xml application/xml text/javascript image/svg+xml;

    # File tĩnh — serve trực tiếp, cache lâu
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Cấu Trúc Thư Mục Zero-Downtime Deploy

sudo mkdir -p /var/www/laravel/{releases,shared}
sudo mkdir -p /var/www/laravel/shared/{storage,node_modules}
sudo mkdir -p /var/www/laravel/shared/storage/{app,framework,logs}
sudo mkdir -p /var/www/laravel/shared/storage/framework/{cache,sessions,views}
sudo chown -R ec2-user:nginx /var/www/laravel
sudo chmod -R 775 /var/www/laravel/shared/storage
/var/www/laravel/
├── current → releases/20260327_120000/   (symlink đến bản mới nhất)
├── releases/
│   ├── 20260327_120000/                  (release hiện tại)
│   └── 20260326_150000/                  (release trước)
└── shared/
    ├── .env                              (persistent)
    └── storage/                          (persistent)

Deploy Thủ Công Lần Đầu

cd /var/www/laravel
RELEASE=$(date +%Y%m%d_%H%M%S)
git clone git@github.com:your/repo.git releases/$RELEASE
cd releases/$RELEASE

# Cài dependencies
composer install --no-dev --optimize-autoloader --no-interaction

# Tạo .env (chỉ lần đầu)
cp .env.example /var/www/laravel/shared/.env
vim /var/www/laravel/shared/.env

# Link shared resources
rm -rf storage
ln -s /var/www/laravel/shared/storage storage
ln -s /var/www/laravel/shared/.env .env

# Build frontend
npm ci && npm run build && rm -rf node_modules

# Tối ưu Laravel
php artisan key:generate
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Kích hoạt release
cd /var/www/laravel
ln -sfn releases/$RELEASE current
sudo systemctl reload php-fpm

Cài Đặt Supervisor (Cho Queue)

sudo dnf install -y supervisor
sudo systemctl enable supervisord
sudo systemctl start supervisord
sudo vim /etc/supervisord.d/laravel-worker.ini
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/laravel/current/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
user=ec2-user
numprocs=2
redirect_stderr=true
stdout_logfile=/var/log/supervisor/laravel-worker.log

Cài Đặt Laravel Scheduler (Cron)

crontab -e
* * * * * cd /var/www/laravel/current && php artisan schedule:run >> /dev/null 2>&1

Tiếp Theo

Phần 3, chúng ta sẽ thiết lập RDS MySQL trong private subnet, tạo S3 bucket cho lưu trữ file, cấu hình Laravel kết nối với cả hai, và thêm ElastiCache (Redis).


Điều hướng Series:

Bình luận