β
AMI μ ν (Ubuntu, Amazon Linux)
β
μΈμ€ν΄μ€ μ ν (t2.micro - ν리ν°μ΄)
β
ν€νμ΄ μμ± λ° λ€μ΄λ‘λ
β
보μ κ·Έλ£Ή μ€μ
- SSH (22λ² ν¬νΈ)
- HTTP (80λ² ν¬νΈ)
- HTTPS (443λ² ν¬νΈ)
- 컀μ€ν
(API μλ² ν¬νΈ)
β
μ€ν λ¦¬μ§ μ€μ (κΈ°λ³Έ 8GB)
β
νλ ₯μ IP μ°κ²° (μ΅μ
)
# Node.js μ€μΉ (Ubuntu)
sudo apt-get update
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# PM2 μ€μΉ (νλ‘μΈμ€ κ΄λ¦¬)
sudo npm install -g pm2
# μλ² μ€ν
pm2 start app.js --name api-server
pm2 startup # μ¬λΆν
μ μλ μμ
pm2 save
β
μΈμ€ν΄μ€ μ’
λ£
β
νλ ₯μ IP 릴리μ¦
β
보μ κ·Έλ£Ή μμ (μ ν)
β
ν€νμ΄ μμ (μ ν)
1. λλ©μΈ ꡬ맀 (Route 53 λλ μΈλΆ)
2. νΈμ€ν
μμ μμ±
3. λ μ½λ μΆκ°
- api.domain.com β EC2 λλ ELB
- www.domain.com β CloudFront
4. λ€μμλ² νμΈ
β
λλ©μΈ μ΄μ λλ μμ
β
νΈμ€ν
μμ λ΄ λ μ½λ μμ
β
νΈμ€ν
μμ μμ
1. λ‘λλ°Έλ°μ μμ± (ALB μ ν)
2. λ€νΈμν¬ λ§€ν (κ°μ© μμ μ ν)
3. 보μ κ·Έλ£Ή μ€μ
- HTTP (80)
- HTTPS (443)
4. λμ κ·Έλ£Ή μμ±
- νλ‘ν μ½: HTTP
- ν¬μ€μ²΄ν¬ κ²½λ‘: /health
5. EC2 μΈμ€ν΄μ€ λ±λ‘
6. 리μ€λ κ·μΉ μ€μ
1. ACMμμ SSL μΈμ¦μ λ°κΈ
- λλ©μΈ κ²μ¦ (DNS κ²μ¦ μΆμ²)
2. ELB 리μ€λ μΆκ°
- ν¬νΈ: 443
- νλ‘ν μ½: HTTPS
- μΈμ¦μ μ ν
3. HTTP β HTTPS 리λ€μ΄λ μ
μ€μ
β
λ‘λλ°Έλ°μ μμ
β
λμ κ·Έλ£Ή μμ
β
ACM μΈμ¦μ μμ (μ ν)
1. DB μμ§ μ ν (MySQL 8.0)
2. ν
νλ¦Ώ μ ν (ν리ν°μ΄)
3. μΈμ€ν΄μ€ μ€μ
- DB μΈμ€ν΄μ€ μλ³μ
- λ§μ€ν° μ¬μ©μ/μνΈ
4. μ°κ²° μ€μ
- VPC
- μλΈλ· κ·Έλ£Ή
- νΌλΈλ¦ μ‘μΈμ€ (κ°λ°: μ, μ΄μ: μλμ)
5. 보μ κ·Έλ£Ή μ€μ (3306 ν¬νΈ)
6. νλΌλ―Έν° κ·Έλ£Ή μμ± λ° μ μ©
character_set_client: utf8mb4
character_set_connection: utf8mb4
character_set_database: utf8mb4
character_set_filesystem: utf8mb4
character_set_results: utf8mb4
character_set_server: utf8mb4
collation_connection: utf8mb4_unicode_ci
collation_server: utf8mb4_unicode_ci
time_zone: Asia/Seoul
// Node.js + TypeORM
{
type: "mysql",
host: "your-rds-endpoint.amazonaws.com",
port: 3306,
username: "admin",
password: "password",
database: "mydb"
}
β
μ΅μ’
μ€λ
μ· μμ± μ¬λΆ κ²°μ
β
μλ λ°±μ
보쑴 μ²΄ν¬ ν΄μ
β
DB μΈμ€ν΄μ€ μμ
β
νλΌλ―Έν° κ·Έλ£Ή μμ
β
μλΈλ· κ·Έλ£Ή μμ
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
1. λ²ν· μμ±
2. νΌλΈλ¦ μ‘μΈμ€ μ°¨λ¨ ν΄μ
3. λ²ν· μ μ±
μΆκ°
4. μ μ μΉ νΈμ€ν
νμ±ν
- μΈλ±μ€ λ¬Έμ: index.html
- μ€λ₯ λ¬Έμ: error.html
5. νμΌ μ
λ‘λ
1. IAM μ¬μ©μ μμ±
2. AmazonS3FullAccess μ μ±
μ°κ²°
3. μ‘μΈμ€ ν€ λ°κΈ
4. SDKλ‘ μ°λ
// Multer-S3 μ€μ
const upload = multer({
storage: multerS3({
s3: s3Client,
bucket: 'my-bucket',
key: (req, file, cb) => {
cb(null, Date.now() + '-' + file.originalname)
}
})
})
β
λ²ν· λ΄ λͺ¨λ κ°μ²΄ μμ
β
λ²ν· μμ
β
IAM μ¬μ©μ λ° μ‘μΈμ€ ν€ μμ
1. λ°°ν¬ μμ±
2. μ€λ¦¬μ§ μ€μ
- S3 μ μ μΉμ¬μ΄νΈ μλν¬μΈνΈ
- λλ ELB/EC2
3. κΈ°λ³Έ μΊμ λμ μ€μ
- Viewer Protocol Policy: Redirect HTTP to HTTPS
- Allowed HTTP Methods: GET, HEAD
4. λ°°ν¬ μ€μ
- λ체 λλ©μΈ μ΄λ¦ (CNAME)
- SSL μΈμ¦μ (ACM - λ²μ§λμ λΆλΆ)
- κΈ°λ³Έ λ£¨νΈ κ°μ²΄: index.html
5. μ€λ₯ νμ΄μ§ μ€μ (SPAμ©)
- 403 β /index.html (200)
- 404 β /index.html (200)
aws cloudfront create-invalidation \
--distribution-id E1234567890ABC \
--paths "/*"
β
CloudFront λ°°ν¬ λΉνμ±ν
β
λ°°ν¬ μμ (λΉνμ±ν ν κ°λ₯)
β
ACM μΈμ¦μ μμ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β μ¬μ©μ β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
ββββββββΌβββββββ
β Route 53 β (DNS)
ββββββββ¬βββββββ
βββββββββββββ΄ββββββββββββ
β β
ββββββΌββββββ βββββββΌβββββ
βCloudFrontβ β ELB β
ββββββ¬ββββββ βββββββ¬βββββ
β β
ββββββΌββββββ βββββββΌβββββ
βS3 (Web) β β EC2 β
ββββββββββββ βββββββ¬βββββ
β
ββββββββββββΌβββββββββββ
β β β
ββββββΌββββ βββββΌββββ ββββββΌβββββ
β RDS β β S3 β β ElastiCacheβ
ββββββββββ βββββββββ βββββββββββ
ELB 보μ κ·Έλ£Ή:
μΈλ°μ΄λ: 80 (HTTP), 443 (HTTPS) - 0.0.0.0/0
μμλ°μ΄λ: All traffic
EC2 보μ κ·Έλ£Ή:
μΈλ°μ΄λ: 80 (HTTP) - ELB 보μ κ·Έλ£Ή
μΈλ°μ΄λ: 22 (SSH) - λ΄ IP
μμλ°μ΄λ: All traffic
RDS 보μ κ·Έλ£Ή:
μΈλ°μ΄λ: 3306 (MySQL) - EC2 보μ κ·Έλ£Ή
μμλ°μ΄λ: All traffic
name: Deploy to EC2
on:
push:
branches: [main]
paths: ['api-server/**']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /home/ubuntu/app
git pull origin main
npm install
npm run build
pm2 restart api-server
name: Deploy to S3/CloudFront
on:
push:
branches: [main]
paths: ['web-client/**']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm run build
- uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
aws-region: ap-northeast-2
- run: |
aws s3 sync dist/ s3://${{ secrets.S3_BUCKET }} --delete
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.CF_DISTRIBUTION_ID }} \
--paths "/*"
EC2_HOST: EC2 IP λλ λλ©μΈ
EC2_SSH_KEY: .pem νμΌ λ΄μ©
AWS_ACCESS_KEY: IAM μ‘μΈμ€ ν€
AWS_SECRET_KEY: IAM μν¬λ¦Ώ ν€
S3_BUCKET: S3 λ²ν· μ΄λ¦
CF_DISTRIBUTION_ID: CloudFront λ°°ν¬ ID
μ΄ κ°μ΄λλ μ€μ νλ‘μ νΈ κ²½νμ λ°νμΌλ‘ μμ±λμμΌλ©°, AWS μλΉμ€λ₯Ό νμ©ν νμ€ν μ ν리μΌμ΄μ ꡬμΆμ νμν ν΅μ¬ λ΄μ©μ λ΄κ³ μμ΅λλ€.