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

· 10 min read

Phần 1, chúng ta đã tạo VPC, subnets, và security groups hoàn toàn qua Console. Giờ hãy khởi chạy server và chạy Laravel trên đó.

Lưu ý: Việc khởi chạy EC2 thao tác qua Console, nhưng sau khi SSH vào server, các lệnh cài đặt phần mềm (Nginx, PHP, Composer...) bắt buộc phải chạy trong terminal. Đây là bản chất của việc quản lý server — không có giao diện Console cho nó.

Bước 1: Khởi Chạy EC2 Instance

1a. Mở EC2 Console

  1. Thanh tìm kiếm → gõ "EC2" → click EC2
  2. Kiểm tra region ap-northeast-1 (Tokyo) ở góc phải trên
  3. Click "Launch instance" (nút cam)

1b. Đặt Tên

  • Name and tags → Name: laravel-web-01

1c. Chọn AMI (Hệ Điều Hành)

  1. Phần Application and OS Images (Amazon Machine Image)
  2. Tab Quick Start → chọn Amazon Linux
  3. Trong dropdown AMI, chọn Amazon Linux 2023 AMI (Free tier eligible)
  4. Architecture: 64-bit (x86)

1d. Chọn Instance Type

  1. Phần Instance type
  2. t3.small vào ô tìm kiếm và chọn
Instance vCPU RAM Chi phí/tháng (Tokyo)
t3.micro 2 1GB ~$9 (Free tier)
t3.small 2 2GB ~$19
t3.medium 2 4GB ~$38

Gợi ý: t3.small (2GB RAM) phù hợp cho hầu hết Laravel apps. t3.micro (1GB) có thể thiếu RAM khi chạy cả Nginx + PHP-FPM + Supervisor.

1e. Key Pair

  1. Phần Key pair (login)
  2. Chọn laravel-production (đã tạo ở Phần 1)
  3. Nếu chưa tạo: click "Create new key pair" → tên laravel-production → RSA → .pemCreate

1f. Network Settings

Click "Edit" bên phải phần Network settings:

Thiết lập Giá trị
VPC laravel-production-vpc
Subnet laravel-production-subnet-public1-ap-northeast-1a
Auto-assign public IP Enable
Firewall (security groups) Select existing security group
Security groups laravel-ec2-sg

1g. Storage

  1. Phần Configure storage
  2. Thay đổi:
Thiết lập Giá trị
Size (GiB) 20
Volume type gp3
IOPS 3000 (mặc định)
Throughput 125 (mặc định)

gp3 nhanh hơn và rẻ hơn gp2 cùng mức hiệu năng.

1h. Advanced Details (IAM Role)

  1. Expand phần Advanced details
  2. Tìm IAM instance profile
  3. Chọn laravel-ec2-role (đã tạo ở Phần 1)
  4. Các thiết lập khác: giữ mặc định

1i. Review & Launch

  1. Phần Summary bên phải hiện tổng quan:
    • AMI: Amazon Linux 2023
    • Instance type: t3.small
    • Key pair: laravel-production
    • Network: laravel-production-vpc, public subnet
    • Security group: laravel-ec2-sg
    • Storage: 20 GB gp3
  2. Click "Launch instance"
  3. Đợi 30-60 giây

1j. Lấy Public IP

  1. Click "View all instances" hoặc vào EC2 → Instances
  2. Tìm laravel-web-01
  3. Đợi cột Instance state chuyển sang Running (icon xanh)
  4. Cột Public IPv4 address: ghi lại IP này (ví dụ 54.178.xxx.xxx)

Mẹo: Click instance ID để vào trang chi tiết, xem đầy đủ thông tin ở tab Details.

Bước 2: SSH Vào Server

Mở terminal trên máy local:

ssh -i ~/.ssh/laravel-production.pem ec2-user@54.178.xxx.xxx

Nếu thấy cảnh báo "Are you sure you want to continue connecting?" → gõ yes.

Lỗi "Permission denied"? Kiểm tra quyền file: chmod 400 ~/.ssh/laravel-production.pem

Lỗi "Connection timed out"? Kiểm tra:

  • Security group laravel-ec2-sg có rule SSH port 22 từ IP của bạn
  • Instance ở public subnet với public IP
  • IP của bạn có thể đã thay đổi (cập nhật security group rule)

Cấu Hình SSH Shortcut (Tùy chọn)

Thêm vào ~/.ssh/config trên máy local:

Host laravel-prod
    HostName 54.178.xxx.xxx
    User ec2-user
    IdentityFile ~/.ssh/laravel-production.pem

Từ giờ chỉ cần: ssh laravel-prod

Bước 3: Thiết Lập Hệ Thống

Sau khi SSH thành công, bạn đang ở trong Amazon Linux 2023.

# Cập nhật toàn bộ hệ thống
sudo dnf update -y

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

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

Bước 4: Cài Đặt Nginx

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

Kiểm tra: mở trình duyệt → http://54.178.xxx.xxx → thấy trang mặc định Nginx.

Không thấy trang? Security group laravel-ec2-sg chỉ cho phép HTTP từ ALB (laravel-alb-sg), không phải từ internet. Để test tạm, thêm rule HTTP port 80 từ My IP → nhớ xóa sau khi test xong.

Bước 5: Cài Đặt PHP 8.4

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

Nếu PHP 8.4 không có sẵn, 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

Thay đổi các giá trị sau:

; 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

sudo vim /etc/php.ini
; Hiệu năng và giới hạn
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 (rất quan trọng cho hiệu năng)
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0

Quan trọng: opcache.validate_timestamps = 0 tắt kiểm tra file thay đổi → tăng hiệu năng lớn nhưng cần restart PHP-FPM sau mỗi lần deploy. Script deploy ở Phần 5 tự xử lý.

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

Bước 6: Cài Composer & Node.js

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

# Kiểm tra
composer --version

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

# Kiểm tra
node --version
npm --version

Bước 7: Cấu Hình Nginx Cho Laravel

Xóa config mặc định và tạo config Laravel:

sudo rm -f /etc/nginx/conf.d/default.conf
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;
    }

    # Chặn dotfiles (trừ .well-known)
    location ~ /\.(?!well-known).* {
        deny all;
    }
}
# Test cấu hình
sudo nginx -t

# Reload
sudo systemctl reload nginx

Bước 8: Tạo Cấu Trúc Thư Mục 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

Cấu trúc kết quả:

/var/www/laravel/
├── current → releases/20260403_120000/   (symlink đến bản mới nhất)
├── releases/
│   ├── 20260403_120000/                  (release hiện tại)
│   └── ...
└── shared/
    ├── .env                              (persistent — giữ qua các release)
    └── storage/                          (persistent — logs, uploads, cache)

Bước 9: 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 file .env (chỉ lần đầu)
cp .env.example /var/www/laravel/shared/.env
vim /var/www/laravel/shared/.env
# → Điền database, cache, queue... (sẽ cấu hình ở Phần 3)

# 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 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

Bước 10: Cài Supervisor (Cho Queue Workers)

sudo dnf install -y supervisor
sudo systemctl enable supervisord
sudo systemctl start supervisord

Tạo config cho Laravel worker:

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
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

Bước 11: Cài Laravel Scheduler (Cron)

crontab -e

Thêm dòng:

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

Xác Nhận Qua Console

Quay lại AWS Console để xác nhận EC2 đang chạy tốt:

Kiểm Tra Instance Status

  1. EC2 → Instances → click laravel-web-01
  2. Tab Status checks:
    • System status check: ✅ passed
    • Instance status check: ✅ passed

Xem Monitoring

  1. Tab Monitoring → xem CPU, Network, Disk I/O
  2. Nếu CPU liên tục > 80%, nên nâng cấp instance type

Xem System Log (Nếu cần debug)

  1. Click Actions → Monitor and troubleshoot → Get system log
  2. Xem boot log để phát hiện lỗi khởi động

Checklist Sau Phần 2

  • EC2 instance laravel-web-01 đang Running
  • SSH vào server thành công
  • Nginx cài và chạy
  • PHP 8.4 FPM cài và chạy
  • Composer và Node.js cài xong
  • Nginx config cho Laravel đã tạo
  • Cấu trúc thư mục /var/www/laravel/ đã sẵn sàng
  • Deploy thủ công lần đầu thành công (hoặc sẵn sàng sau Phần 3)
  • Supervisor đang chạy queue workers
  • Cron job cho scheduler đã thêm

Server đã sẵn sàng. Tiếp theo: kết nối database, storage, và cache.


Điều hướng Series:

Bình luận