Build code lên ec2

Build code lên ec2

May 17, 20267 min read

# Deploy Laravel 13 + Filament v4 lên AWS EC2 (Ubuntu 24.04)

## Yêu cầu

- EC2 instance Ubuntu 22.04/24.04

- SSH key .pem

- Domain trỏ về IP EC2

- PHP 8.3, PostgreSQL 16, Nginx

---

## 1. Kết nối EC2

```bash

chmod 400 ~/aws-vps-key.pem

ssh -i ~/aws-vps-key.pem ubuntu@YOUR_EC2_IP

```

---

## 2. Cài đặt dependencies

```bash

sudo apt update && sudo apt upgrade -y

# Nginx

sudo apt install -y nginx

# PHP 8.3

sudo add-apt-repository ppa:ondrej/php -y

sudo apt update

sudo apt install -y php8.3 php8.3-fpm php8.3-cli php8.3-common \

php8.3-pgsql php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip \

php8.3-bcmath php8.3-intl php8.3-tokenizer php8.3-gd

# PostgreSQL 16

sudo apt install -y postgresql postgresql-contrib

# Composer & Git

curl -sS https://getcomposer.org/installer | php

sudo mv composer.phar /usr/local/bin/composer

sudo apt install -y git unzip

```

---

## 3. Cấu hình PostgreSQL

```bash

sudo -u postgres psql

```

```sql

CREATE USER blog_user WITH PASSWORD 'your_strong_password';

CREATE DATABASE blog_cms OWNER blog_user;

GRANT ALL PRIVILEGES ON DATABASE blog_cms TO blog_user;

\q

```

---

## 4. Deploy code

```bash

sudo mkdir -p /var/www/blog-cms

sudo chown ubuntu:ubuntu /var/www/blog-cms

cd /var/www/blog-cms

git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git .

```

Hoặc rsync từ máy local:

```bash

rsync -avz --exclude='.env' --exclude='vendor' \

-e "ssh -i ~/aws-vps-key.pem" \

/path/to/local/project/ \

ubuntu@YOUR_EC2_IP:/var/www/blog-cms/

```

---

## 5. Cấu hình Laravel

```bash

cd /var/www/blog-cms

composer install --no-dev --optimize-autoloader

cp .env.example .env

nano .env

```

Các giá trị cần thay:

```env

APP_ENV=production

APP_DEBUG=false

APP_URL=https://your-domain.com

DB_CONNECTION=pgsql

DB_HOST=127.0.0.1

DB_PORT=5432

DB_DATABASE=blog_cms

DB_USERNAME=blog_user

DB_PASSWORD=your_strong_password

FILESYSTEM_DISK=public

```

```bash

php artisan key:generate

php artisan storage:link

php artisan migrate --force

php artisan config:cache

php artisan route:cache

php artisan view:cache

```

---

## 6. Permissions (quan trọng)

Cấu trúc ownership chuẩn — không chown toàn bộ về www-data để tránh conflict với git:

```bash

# Toàn bộ code: ubuntu sở hữu (git pull, composer, artisan hoạt động)

sudo chown -R ubuntu:ubuntu /var/www/blog-cms

# Chỉ 2 thư mục PHP cần ghi: www-data

sudo chown -R www-data:www-data /var/www/blog-cms/storage

sudo chown -R www-data:www-data /var/www/blog-cms/bootstrap/cache

sudo chmod -R 775 /var/www/blog-cms/storage

sudo chmod -R 775 /var/www/blog-cms/bootstrap/cache

# Livewire file upload

sudo mkdir -p /var/www/blog-cms/storage/app/livewire-tmp

sudo chown -R www-data:www-data /var/www/blog-cms/storage/app

```

---

## 7. Nginx config

```bash

sudo nano /etc/nginx/sites-available/blog-cms

```

```nginx

server {

listen 80;

server_name your-domain.com;

root /var/www/blog-cms/public;

index index.php;

add_header X-Frame-Options "SAMEORIGIN";

add_header X-Content-Type-Options "nosniff";

client_max_body_size 128M;

location / {

try_files $uri $uri/ /index.php?$query_string;

}

location ~ \.php$ {

fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

include fastcgi_params;

}

location ~ /\.(?!well-known).* {

deny all;

}

}

```

```bash

sudo ln -s /etc/nginx/sites-available/blog-cms /etc/nginx/sites-enabled/

sudo rm -f /etc/nginx/sites-enabled/default

sudo nginx -t && sudo systemctl restart nginx

sudo systemctl enable nginx php8.3-fpm

```

---

## 8. PHP-FPM upload limits

```bash

sudo nano /etc/php/8.3/fpm/php.ini

```

```ini

upload_max_filesize = 64M

post_max_size = 128M

```

```bash

sudo systemctl restart php8.3-fpm

```

---

## 9. SSL với Certbot

```bash

sudo apt install -y certbot python3-certbot-nginx

sudo certbot --nginx -d your-domain.com

```

Certbot hỏi lần lượt: email → agree terms → chọn Redirect (2). Tự động cập nhật Nginx sang HTTPS.

```bash

# Cập nhật APP_URL

nano .env # APP_URL=https://your-domain.com

php artisan config:cache

```

---

## 10. Tạo admin user

```bash

php artisan tinker --execute="

App\Models\User::create([

'name' => 'Admin',

'email' => 'admin@yourdomain.com',

'password' => bcrypt('your_password'),

'role' => 'admin',

]);

echo 'Done.';

"

```

---

## 11. Publish Filament assets

```bash

php artisan filament:assets

```

---

## Các lỗi thường gặp

### git pull bị Permission denied

```bash

# Nguyên nhân: chown www-data làm mất quyền git

sudo chown -R ubuntu:ubuntu /var/www/blog-cms/.git

git pull

# Sau đó trả lại permissions đúng (mục 6)

```

### storage/logs/laravel.log Permission denied

```bash

sudo chown -R www-data:www-data /var/www/blog-cms/storage

sudo chmod -R 775 /var/www/blog-cms/storage

```

### Livewire upload thất bại

```bash

sudo mkdir -p /var/www/blog-cms/storage/app/livewire-tmp

sudo chown -R www-data:www-data /var/www/blog-cms/storage/app

sudo chmod -R 775 /var/www/blog-cms/storage/app

```

### tempnam(): file created in system's temporary directory

```bash

# storage/app không ghi được → PHP fallback sang /tmp

sudo chown -R www-data:www-data /var/www/blog-cms/storage

php artisan storage:link

```

### Migrations lỗi relation "posts" does not exist

Pivot table post_category) có timestamp trùng với posts và chạy trước do alphabetical sort. Fix: đổi timestamp của pivot table thành số lớn hơn.

```

# Sai: 2026_05_17_064952_create_post_category_table.php

# Đúng: 2026_05_17_064954_create_post_category_table.php (sau posts)

```

### Login page không có nút Submit

CSS quá broad ẩn mất form actions. Kiểm tra AdminPanelProvider.php:

```css

/* Sai — ẩn cả nút login */

.fi-sc-actions .fi-ac { display: none !important; }

/* Đúng — chỉ ẩn trong admin panel */

.fi-main .fi-sc-actions .fi-ac { display: none !important; }

```

Share: Twitter