1. Chọn VPS

Để build strapi cần một vps 2GB ram trở lên, TH nếu ko sẽ bị lỗi. Thường thì dẽ chọn ubuntu 20.04 để cài đặt cho dễ quản lý

sudo apt-get update # Update

2. Cài đặt swap cho ubuntu

Tiến hành cài đặt swap để khi trường hợp không đủ ram để sử dụng có thể swap vào ổ cứng, hiện tại đều sử dụng SSD nên tốc độ sẽ khá tốt, nên chọn VPS Nvme.

Xem thêm: https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04

Đối với EC2, dùng một volume mới như một vùng swap

# Chạy lsblk để xem danh sách ổ đĩa, trong đó có /dev/xvdf
lsblk

#Tạo swap cho ổ cứng vừa mount vào
sudo mkswap /dev/xvdf

# Enable swap
sudo swapon /dev/xvdf

# Thêm cấu hình vào file /etc/fstab để chạy swap khi khởi động
sudo vi /etc/fstab
#Thêm dòng bên dưới
/dev/xvdf none swap sw 0 0

# Check swap
sudo swapon --show

Đối với EC2 mount volumes sang một folder và tạo swap

https://aws.amazon.com/premiumsupport/knowledge-center/ec2-memory-partition-hard-drive/

Trong đó https://www.cyberciti.biz/faq/debian-ubuntu-reload-partition-table/

https://dev.to/hardiksondagar/how-to-use-aws-ebs-volume-as-a-swap-memory-5d15

https://www.bogotobogo.com/DevOps/AWS/aws_adding_swap_space_to_attached_volume_via_mkswap_and_swapon.php

3. Cài đặt vsftpd

Để cài đặt vsftp cần làm theo link bên dưới

https://www.digitalocean.com/community/tutorials/how-to-set-up-vsftpd-for-a-user-s-directory-on-ubuntu-20-04

Chú ý các bước sau:

Mở port cho vsftp

sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 40000:50000/tcp --> port này là dải port mở để truyền dữ liệu, phải đăng kí trong config vsftpd
sudo ufw status

Sau khi tạo thành công user thì thêm vào file để cho phép user sử dụng ftp

echo "sammy" | sudo tee -a /etc/vsftpd.userlist

Config cho vsftp chuẩn /etc/vsftpd.conf

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
force_dot_files=YES
pasv_min_port=40000
pasv_max_port=50000

#user_sub_token=$USER
#local_root=/home/$USER/public_html
allow_writeable_chroot=YES

ssl_enable=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH

port_enable=YES
pasv_enable=YES
pasv_address=3.1.142.167
pasv_addr_resolve=YES
check_shell=NO
passwd_chroot_enable=YES

4. Cài đặt nginx

Tiến hành cài đặt nginx theo link:

https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04

Trong đó chú ý /etc/nginx/sites-enable và /etc/nginx/config.d là 2 nơi để chứa config cho nginx

Cấu hình nginx mẫu: domain.conf

server {
    # Listen HTTP
    listen 80;
    server_name domain.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    # Listen HTTPS
    listen 443 ssl;
    server_name domain.com;

    # SSL config
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot

    ## Gzip config
    gzip on;
    client_max_body_size          512M;

    # .Netcore
    location / {
        proxy_pass https://frontend;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
    }

    # Strapi API
    location /api/ {
        rewrite ^/api/?(.*)$ /$1 break;
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
    }

    # Strapi Dashboard
    location /admin {
        proxy_pass http://backend/admin;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
    }

}

upstream.conf

upstream frontend {
    server 127.0.0.1:6300;
}

upstream backend {
    server 127.0.0.1:1337;
}

5.Cài đặt .netcore

Cài đặt .netcore để chạy và build frontend theo link:

https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu

Thường thì sẽ cài theo source 3.1 hay 5.0.

6. Cài đặt node và npm

Tiến hành cài đặt node và npm, hãy xem requiredment của strapi mà cài đặt đúng version, sai khác sẽ gây ra lỗi.

https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04

7. Cài đặt pm2

Thông thường các .netcore hay strapi chạy sẽ là chạy trực tiếp, điều này sẽ gây ra một số vấn đề. Vì vậy cần đưa nó chạy dưới nền, để không ảnh hưởng tới các process khác. Trước kia sử dụng dùng các tool khác, hiện nay có thể sử dụng pm2, khá đơn giản.

Cài đặt pm2 ở đây

https://pm2.keymetrics.io/docs/usage/quick-start/

Với các câu lệnh thông dụng:

# Sẽ tạo ra file ecosystem.conf dùng để lưu cấu hình
pm2 init

# Lưu cấu hình pm2 lại
pm2 save

# Dùng để tạo ra câu command để bạn chạy nó để cho app chạy nền được gọi khi khởi động
pm2 startup

# Khơi chạy config
pm2 start ecosystem.conf.js / pm2 start {tên config}

# Dừng config
pm2 stop {tên config}

# Xem tất cả config của user
pm2 status

# Xem chi tiết logs một config
pm2 logs {tên config}

#pm2 del {tên config}/ {Số thứ tự config}

8. Cài đặt ssl dùng Let’s Encrypt

Cài đặt theo hướng dẫn, lưu ý backup config của nginx default.conf trước khi chạy cerbot.

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04

9. Cấu hình Strapi

Cấu hình s3 bucket

Tạo user để dùng đó làm clientid + secrect key kết nối s3

https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment/hosting-guides/amazon-aws.html#amazon-aws-install-requirements-and-creating-an-iam-non-root-user

Tạo s3 bucket

https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment/hosting-guides/amazon-aws.html#configure-s3-for-image-hosting

Đừng quên cấu hình Object Ownership trong Permission và cấu hình ACL enabled chọn Object write

Cấu hình config cho strapi

Theo như đường dẫn:

https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment/hosting-guides/amazon-aws.html#_3-install-the-strapi-aws-s3-upload-provider

Với config/plugins.js

module.exports = ({ env }) => ({
    upload: {
      provider: 'aws-s3',
      providerOptions: {
        accessKeyId: env('AWS_ACCESS_KEY_ID'),
        secretAccessKey: env('AWS_ACCESS_SECRET'),
        region: env('AWS_REGION'),
        params: {
          Bucket: env('AWS_BUCKET_NAME'),
        },
        cdn: env('AWS_CLOUDFRONT'), // CDN Url
        localServer: {
          maxage: 300000
        }
      },
      breakpoints: {
        xlarge: 1920,
        large: 1000,
        small: 500
      }
    }
  });

Sử dụng thư viện:

https://www.npmjs.com/package/strapi-provider-upload-aws-s3-plus-cdn

Với config/plugins.js

module.exports = ({ env }) => ({
  // ...
  upload: {
    provider: 'aws-s3-plus-cdn',
    providerOptions: {
      accessKeyId: env('AWS_ACCESS_KEY_ID'),
      secretAccessKey: env('AWS_ACCESS_SECRET'),
      region: env('AWS_REGION'),
      params: {
        Bucket: env('AWS_BUCKET'),
      },
      cdnUrl: env("CDN_URL"), // Optional CDN URL - include protofol and trailing forward slash, e.g. 'https://assets.example.com/'
    },
  },
  // ...
});

Cấu hình redis cache

Cài đặt strapi-middleware-cache trong npm và cấu hình config/midleware.js

module.exports = ({ env }) => ({
    settings: {
      cache: {
        enabled: true,
        type: 'redis',
        maxAge: 2600000,
        max: 400,
        cacheTimeout: 400,
        enableEtagSupport: true,
        logs: true,
        populateContext: false,
        models: ['blos'], // Models want to have cache
        redisConfig: {
          sentinels: [
            { host: '192.168.10.41', port: 26379 },
            { host: '192.168.10.42', port: 26379 },
            { host: '192.168.10.43', port: 26379 },
          ],
          name: 'redis-primary',
        }
      //or you can connect to redis lab with the command below.
       redisConfig: {
          host: 'localhost',
          port: 6379,
          password: 'secret_password',
        },
      }
    }
  });

Xem thêm:

https://strapi.io/blog/caching-in-strapi-strapi-middleware-cache

Cấu hình backend strapi

File config/sever.js

module.exports = ({ env }) => ({
  host: env('HOST'),
  port: env.int('PORT'),
  url: env('APP_URL'),
  admin: {
    url: env('APP_ADMIN_URL'),
    auth: {
      secret: env('ADMIN_JWT_SECRET'),
    },
  },
  cron: { enabled: env('CRON_JOB', false) },
});

File .env

Thường thì tạo config cho mỗi môi trường sẽ có config/env/{production}config/env/{stagging}config/env/{development}

Chép các file config và chỉnh sửa cho phù hợp.

File pm2 config

Thông thường file pm2 config cho strapi sẽ có thông tin sau:

module.exports = {
  apps: [
    {
      name: 'strapi',
      cwd: '/home/strapi/public_html',
      script: 'npm',
      args: 'start',
      env: {
        NODE_ENV: 'production',
        DATABASE_HOST: 'database url',
        DATABASE_PORT: '3306',
        DATABASE_NAME: 'strapi',
        DATABASE_USERNAME: 'admin',
        DATABASE_PASSWORD: 'ciadmin123',
        'DATABASE_SSL': 'true',
        AWS_ACCESS_KEY_ID: 'AKIAVL4SNFVVKZUU3IEX',
        AWS_ACCESS_SECRET: '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', // Find it in Amazon S3 Dashboard
        AWS_REGION: 'ap-southeast-1',
        AWS_BUCKET_NAME: 'ci-strapi-s3',
      },
    },
  ],
};

// Các thông tin .env sẽ đè .env trong config

Qui trình build strapi

Thông thường sẽ là:

# Đăng nhập user
su strapi
# Về thư mục home/user vào backend
cd ~ && cd backend
# Dừng ứng dụng đang chạy
pm2 stop {config}
# Tải code về
git pull
# Cài package
npm install
# Build với môi trường production
NODE_ENV=production npm run build
# Khởi chạy ứng dụng
pm2 start {config}
#Xem logs hoạt động
pm2 logs {config}

10. Cấu hình .netcore

Cấu hình để có thể build trên linux

Nguồn từ bài viết:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0

Trong file SmartCsmNetCore.Site.csproj thêm <RuntimeIdentifiers>win10-x64;linux-x64</RuntimeIdentifiers> để thêm cấu hình build cho linux.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AssemblyName>SmartCsmNetCore.Site</AssemblyName>
    <RootNamespace>SmartCsmNetCore.Site</RootNamespace>
    <UserSecretsId>bb4bb8e8-7f9b-41cb-b4a9-2141b7337bea</UserSecretsId>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>
  <PropertyGroup>
    <RuntimeIdentifiers>win10-x64;linux-x64</RuntimeIdentifiers>
  </PropertyGroup>

  <ItemGroup>
    <Content Remove="package.json" />
  </ItemGroup>

File appsetting.json

{
  "Logging": {
    "LogFilePath": "logs/ci-mvc/ci-mvc.txt",
    "LogFilePathError": "logs/ci-mvc-errors/ci-mvc.txt"
  },
  "AllowedHosts": "*",  
  "Tokens": {
    "Key": "6J1MNCBkG3yc7zj04c",
    "Issuer": "localhost",
    "TokenExpired": 15
  },
  "Urls": [
    "https://localhost:6300"
  ],
  "Website": "http://localhost:6234",
  "CorsSettings": {
    "AllowOrigin": "*",
    "AllowMethod": "*",
    "AllowHeader": "*"
  },
  "AppSettings": {
    "Item1": "Item1 value",
    "SampleSettings": {
      "SampleString": "SampleString value"
    }
  },
  "WebAPI": "https://api",
  "TokenAPI": {
    "Key": "123",
    "Issuer": "localhost",
    "TokenExpired": 15
  }
}

# Trong source cần cấu hình để tiếp nhận proxy header, cấu hình bảo mật + cấu hình để bắt chạy https mặc định.

Qui trình chạy

# Đăng nhập user
su {user}
# Về thư mục home/user/sources
cd ~ && cd sources
# Dừng ứng dụng
pm2 stop {config}
#Kéo source về hay upload ftp, về folder sources
git pull
# Build source .netcore
dotnet publish /home/{user}/sources/SmartCsmNetCore.Site/SmartCsmNetCore.Site.csproj -r linux-x64 -o /home/{user}/public_html/
# Về thư mục đã build
cd ~ && cd public_html
# Khởi chạy ứng dụng
pm2 start {config}

# Trước đó phải chạy
pm2 start dotnet 'dll file' {config } -i max
# Hoặc tạo file config cho pm2
module.exports = {
  apps: [
    {
      name: '{config-name}',
      cwd: '/home/{user}/public_html',
      script: 'dotnet ',
      args: '{dll file}',     
    },
  ],
};

11. Firewall

Trên AWS muốn cho phép ứng dụng từ bên ngoài truy cập vào cần mở firewall, để mở firewall vào ứng dụng tìm Security Group để thêm tương ứng giao thức: TCP/UDP, IP và port.

Ngoài ra trên VPS EC2 còn có 1 firewall nữa, cấu hình theo link:

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-20-04

Danh sách các port cần mở:

To                         Action      From
--                         ------      ----
Nginx HTTP                 ALLOW       Anywhere (:80)
Nginx Full                 ALLOW       Anywhere (:80 - :443)
OpenSSH                    ALLOW       Anywhere (:22)
40000:50000/tcp            ALLOW       Anywhere --> Port truyền dữ liệu FTP
990/tcp                    ALLOW       Anywhere
6379/tcp                   ALLOW       Anywhere
20:21/tcp                  ALLOW       Anywhere
1338/tcp                   ALLOW       Anywhere
1337/tcp                   ALLOW       Anywhere
Nginx HTTP (v6)            ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)
OpenSSH (v6)               ALLOW       Anywhere (v6)
40000:50000/tcp (v6)       ALLOW       Anywhere (v6) --> Port truyền dữ liệu FTP
990/tcp (v6)               ALLOW       Anywhere (v6)
6379/tcp (v6)              ALLOW       Anywhere (v6)
20:21/tcp (v6)             ALLOW       Anywhere (v6)
1338/tcp (v6)              ALLOW       Anywhere (v6)
1337/tcp (v6)              ALLOW       Anywhere (v6)

12. Cấu hình s3 bucket

Để test s3 bucket, tốt nhất nên clone ra bucket mới

https://aws.amazon.com/premiumsupport/knowledge-center/move-objects-s3-bucket/

 

Trả lời

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 *