- ๋ชฉํ : AWS EC2 ์ธ์คํด์ค์ Express.js ๊ธฐ๋ฐ Node.js ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ๊ณ , ์ธ๋ถ์์ 80/3000 ํฌํธ๋ก ์ ์
- ์ฃผ์ ๊ธฐ์ : EC2, AMI, ๋ณด์ ๊ทธ๋ฃน, SSH ํค ํ์ด, Node.js(22.x), npm, Express, PM2, Nginx
ํ๊ฒฝ:
Amazon Linux 2023 (ap-northeast-2)
์ฑ:
Express.js ๊ธฐ๋ฐ ๊ฐ๋จํ “Hello from EC2 Express!” ์๋ฒ
์ด์ ๋๊ตฌ:
PM2(ํ๋ก์ธ์ค ๋งค๋์ ), Nginx(๋ฆฌ๋ฒ์ค ํ๋ก์), Let’s Encrypt SSL
AWS EC2์ Node.js(Express) ์ฑ ๋ฐฐํฌํ๊ธฐ: A to Z
์ด ๊ฒ์๋ฌผ์ ๋ชฉ์ฐจ๋ฅผ ๋จผ์ ์ ๋ฆฌํด๋๋ค.
1. EC2 ์ธ์คํด์ค ์ค๋น (์ด๊ฑด ์ ๊ฒ์๋ฌผ์ ์ด๋ฏธ ์ฌ๋ ค์ ์คํต)
2025.06.12 - [๐ฐ๐ท ํ๊ตญ์ด (Korean)/AWS] - [9] EC2 ์ธ์คํด์ค ์ฐ๊ฒฐ
2. Node.js & ์ ํ๋ฆฌ์ผ์ด์ ์ค์น
2.1 Node.js ์ค์น (NodeSource)
2.2 ํ๋ก์ ํธ ์ด๊ธฐํ ๋ฐ Express ์ค์น
2.3 package.json ์ค์
2.4 index.js ์์ฑ
2.5 ํ ์คํธ ์คํ
3. PM2๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ
4. Nginx ๋ฆฌ๋ฒ์ค ํ๋ก์ ์ค์
4.1 ์ค์น
4.2 ์ค์ ํ์ผ /etc/nginx/conf.d/my-node-app.conf ์์ฑ
4.3 ๊ฒ์ฆ & ์ฌ์์
4.4 ํ์ธ
5. ๋๋ฉ์ธ(Route 53) ์ฐ๊ฒฐ
5.1 Route 53 → ํธ์คํ ์์ญ(Hosted zones) → trill-server.com ์ ํ
5.2 ๋ ์ฝ๋ ์์ฑ(Create record)
5.3 ์ ์ฅ ํ dig +short trill-server.com → IP ํ์ธ
6. HTTPS ์ ์ฉ (Let’s Encrypt)
6.1 ๋ณด์ ๊ทธ๋ฃน: HTTPS(443) → 0.0.0.0/0 ์ถ๊ฐ
6.2 Certbot ์ค์น
6.3 ์ธ์ฆ์ ๋ฐ๊ธ & ์ค์น
6.4 ์๋ ๊ฐฑ์
6.5 ํ์ธ
[9] EC2 ์ธ์คํด์ค ์ฐ๊ฒฐ
์ด ํ๋ฉด์ “์ด ์ธ์คํด์ค์ ์ด๋ป๊ฒ ์ฐ๊ฒฐ(connect)ํ ๊ฒ์ธ์ง”๋ฅผ ์ ํํ๋ ์ฐ๊ฒฐ ํญ์ด๋ค. 1. EC2 ์ธ์คํด์ค ์ฐ๊ฒฐ (EC2 Instance Connect)๋ธ๋ผ์ฐ์ ์์ ๋ฐ๋ก SSH ์ฐ๊ฒฐํด ์ฃผ๋ AWS ๊ณต์ ๊ธฐ๋ฅ์ง์ OS: Amazon Linux 2, Ubu
yeonbikim.tistory.com
์ด ๊ฒ์๋ฌผ์
๋ชฉ์ฐจ์์ ๋ณด์ด๋
2. Node.js & ์ ํ๋ฆฌ์ผ์ด์ ์ค์น
2.1 Node.js ์ค์น (NodeSource)
2.2 ํ๋ก์ ํธ ์ด๊ธฐํ ๋ฐ Express ์ค์น
2.3 package.json ์ค์
2.4 index.js ์์ฑ
2.5 ํ ์คํธ ์คํ
๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ํ๋ฉด์ ๊ฒช์ ์ํ์ฐฉ์ค๋ค๊น์ง ๋ชจ๋ ๊ธฐ๋กํ ๊ฒ์ด๋ค.
< ๋ฐฐํฌ ๋จ๊ณ์์ Node.js ์ค์น์ ์ ํ๋ฆฌ์ผ์ด์ (Express ์ฝ๋) ๋ฐฐ์น๊ฐ ๋ฐ๋์ ํ์ํ ์ด์ >
1. ๋ฐํ์ ํ๊ฒฝ(provisioning) ํ๋ณด
Node.js๋ JavaScript ์ฝ๋๋ฅผ ์คํํด ์ฃผ๋ ์๋ฒ ์ธก ๋ฐํ์์ด๋ค.
EC2๋ ๋จ์ง “๋น ์ปดํจํฐ”์ด๊ธฐ ๋๋ฌธ์, ๋ด๊ฐ ์ด ์๋ฒ ์ฝ๋(Express, TypeScript ๋ฑ)๋ฅผ ์คํํ๋ ค๋ฉด
๊ทธ์ ๋ง๋ ๋ฐํ์(Node.js)๊ณผ ํจํค์ง ๊ด๋ฆฌ์(npm)๊ฐ ๋ฐ๋์ ์ค์น๋์ด ์์ด์ผ ํ๋ค.
2. ์์กด์ฑ(dependencies) ์ค์น
package.json์ ๋ช ์๋ Express, CORS, dotenv ๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์
npm install ๋ช ๋ น์ผ๋ก ์ค์ ์๋ฒ์ ๋ด๋ ค๋ฐ๊ณ ์ค์นํด์ผ๋ง,
์๋ฒ ์ฝ๋์์ import express from 'express' ๊ฐ์ ๊ตฌ๋ฌธ์ด ์๋ฌ ์์ด ๋์ํ๋ค.
3. ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋ ๋ฐฐ์น & ์คํ
3.1 ์ฝ๋ ๋ณต์ฌ - ๋ก์ปฌ ์ฝ๋(๋๋ ๋น๋ ์ฐ์ถ๋ฌผ)๋ฅผ EC2๋ก ์ ์ก
3.2 ํ๊ฒฝ ๊ตฌ์ฑ - .env ํ์ผ, ๋ก๊ทธ ๋๋ ํฐ๋ฆฌ, ์คํ ์คํฌ๋ฆฝํธ ๋ฑ ์ฑ ์คํ์ ํ์ํ ์ค์ ์ถ๊ฐ
3.3 ์๋ฒ ์คํ - node index.js ๋๋ PM2/systemd๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ
์ด ๊ณผ์ ์ “์ ํ๋ฆฌ์ผ์ด์ ๋ ์ด์ด(Application Layer)” ๋ฅผ EC2 ์ธ์คํด์ค ์์ ์ฌ๋ ค ์ฃผ๋ ๋จ๊ณ๋ผ๊ณ ๋ณผ ์ ์๋ค.
์ ๋ฆฌ
1. Node.js ์ค์น → JavaScript ์๋ฒ ์ฝ๋ ์คํ ๊ธฐ๋ฐ ๋ง๋ จ
2. npm install → ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Express ๋ฑ) ์ค์น
3. ์ฝ๋ ๋ฐฐ์น & ์คํ → ์ค์ HTTP ์๋ฒ / API ์๋ฒ ๊ฐ๋
์ด ์ธ ๊ฐ์ง๊ฐ ์์ผ๋ฉด, EC2์ ์๋ฌด๋ฆฌ ์ธ์คํด์ค๋ฅผ ๋์๋ ๋์ ์๋ฒ ์ฝ๋๋ “ํด์ํ ํ๊ฒฝ” ์์ฒด๊ฐ ์์ด์ ๋จ ํ ์ค๋ ์คํ๋์ง ์๋๋ค. ๋ฐ๋ผ์ ๋ฐฐํฌ ๋จ๊ณ์ ํต์ฌ ํ์ ์์ ์ผ๋ก ๋ฐ๋์ ์ํํด์ผ ํ๋ค.
๊ทธ๋ผ ๋๋ ์ Spring Boot ์ฑ์ ๋ฐฐํฌํ ๋ชฉ์ ์ธ๋ฐ Node.js/Express ์ฑ ๋ฐฐํฌ ๊ณผ์ ์ ์ ํํ ๊น?
AWS ์ธํ๋ผ ๊ตฌ์ฑ, ๋ณด์ ๊ทธ๋ฃน, Nginx ๋ฆฌ๋ฒ์ค ํ๋ก์, ๋๋ฉ์ธ·SSL ์ฐ๊ฒฐ ๊ฐ์ด “์ด๋ป๊ฒ ํด๋ผ์ฐ๋ ์์์ ์น ์๋น์ค๋ฅผ ๋์ฐ๊ณ ์ด์ํ๋์ง”์ ๊ธฐ๋ณธ๊ธฐ๋ฅผ ๋ค์ง๋๊ฒ ๋ชฉํ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์, ๊ทธ๋ผ ์์ํด๋ณด์
1. Node.js ์ค์นํ๋ ๋ฒ.
Amazon Linux 2023์์ Node.js๋ฅผ ์ค์นํ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ ๋ ๊ฐ์ง๊ฐ ์๋ค.
์๋ ์์๋ฅผ ์ฐธ๊ณ ํด์ ํธํ ์ชฝ์ ๊ณจ๋ผ ์งํํ๋ฉด ๋๋ค.
ํ์ง๋ง ๋๋ ์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์์ ์คํจ๋ฅผ ๊ฒช์๊ธฐ ๋๋ฌธ์ ๋๋ฒ์งธ๋ฅผ ๋ฐ๋ผํ๋๊ฒ์ ๊ถ์ฅํ๋ค.
๋ฐฉ๋ฒ 1. DNF ๋ชจ๋์ ์ด์ฉํ ์ค์น (Amazon Linux 2023 ๊ธฐ๋ณธ ๋ฐฉ์) - ์ด๊ฑด ์คํจ ๋ฐฉ๋ฒ์ด๋ ๋ฐ๋ก ๋ฐฉ๋ฒ2๋ฅผ ๋ฐ๋ผํ์ธ์!
- ์์คํ ํจํค์ง ์ต์ ํ
sudo dnf update -y

2. ์ฌ์ฉ ๊ฐ๋ฅํ Node.js ๋ชจ๋ ์คํธ๋ฆผ ํ์ธ
sudo dnf module list nodejs
๋ก ์น๋

[ec2-user@ip-172-31-44-167 ~]$ sudo dnf module list nodejs
Last metadata expiration check: 0:41:47 ago on Thu Jun 12 09:03:32 2025.
Error: No matching Modules to list๋ผ๊ณ ๋์๋ค.
Amazon Linux 2023์์๋ RHEL ๊ณ์ด์ฒ๋ผ dnf module์ ํตํ Module Stream ๋ฐฉ์์ด ์๋๋ผ,
๊ธฐ๋ณธ ๋ ํฌ์งํ ๋ฆฌ์ Node.js ํจํค์ง๊ฐ ๋ฐ๋ก ๋ค์ด์๊ฑฐ๋, ์ธ๋ถ RPM ์ ์ฅ์๋ฅผ ์ถ๊ฐํด์ ์ค์นํ๋ ํํ๋ก ๋ฐฐํฌ๋๋ค.
๊ทธ๋์ ๋ฐฉ๋ฒ 2๋ฅผ ์ ํํ์ฌ์ผ ํ๋ค.
๋ฐฉ๋ฒ 2. NodeSource RPM ์ ์ฅ์ ์ด์ฉ (Red Hat ๊ณ์ด ๊ณตํต)
- ์์คํ ํจํค์ง ์ต์ ํ
sudo dnf update -y

2. NodeSource ์ค์น ์คํฌ๋ฆฝํธ ๋ค์ด๋ก๋ & ์คํ
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -

NodeSource ๋ ํฌ์งํ ๋ฆฌ๋ง ์ถ๊ฐ๋ ์ํ์ด๋ค.์ด์ ์ค์ ๋ก Node.js ํจํค์ง๋ฅผ ์ค์นํ๋ฉด ๋๋ค!
๋ค์ ๋จ๊ณ๋ก!
< ์ด์ ์ฌ๊ธฐ์ ํ๊ฒ ๋ ํ๋ ๊ณผ์ ์ ์ด์ ์ ๋ชฉ์ ์ค๋ช >
1. ๋ฐํ์ ์ค์น ํ์ธ → “Node.js๊ฐ EC2์์ ๋ฌธ์ ์์ด ๋์ํ๋ค”
2. ์ฑ ํ๊ฒฝ ๊ตฌ์ฑ → “์์กด์ฑ ๊ด๋ฆฌ(package.json), ES ๋ชจ๋ ์ค์ (type:module)”
3. ์ต์ ์น ์๋ฒ ๋์ฐ๊ธฐ → “๋คํธ์ํฌ ๋ ์ด์ด(Nginx→3000ํฌํธ)๊น์ง ์ฐ๋ํ๊ธฐ์ ์์ ์์ Node.js ์๋น์ค๊ฐ ์ ์ ์๋”
์ด๋ ๊ฒ “๋ฐํ์ → ์์กด์ฑ → ์ฝ๋ → ์คํ”์ ํ๋ฆ ์ ์ฒด๋ฅผ ํ ๋ฒ ์ ๊ฒํด ๋๋ฉด,
๋ค์ ๋จ๊ณ์ธ PM2/NGINX/SSL ์ค์ ์ด๋ CI/CD ์๋ํ๋ก ๋์ด๊ฐ์ ๋
“์ด๋์ ๋ฌธ์ ๊ฐ ์๊ฒจ๋ ์์ธ์ด ๋ฐํ์์ธ์ง, ์ฝ๋์ธ์ง, ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ธ์ง”๋ฅผ
๋น ๋ฅด๊ฒ ๊ตฌ๋ถํ ์ ์๋ค.
์ฆ, ์ด ๊ณผ์ ์ “๋ฐฐํฌ ์ ๊ฒ์ฆ” ๊ฒธ “์ฑ ๋ถํธ์คํธ๋ฉ” ๋จ๊ณ์ด๋ค.
2. Node.js & ์ ํ๋ฆฌ์ผ์ด์ ์ค์น
2.1 Node.js ์ค์น
sudo dnf install -y nodejs

node -v
npm -v
์ค์น ํ์ธ๋ ๋ช ๋ น์ด๋ฅผ ์คํํด๋ณด์.

์ ๋๋ก ์ค์น๊ฐ ๋์๋ค.
์ด์ ๊ฐ๋จํ “[Hello, EC2!]” ์ฐ์ด๋ณด๋ฉด์ ํ ์คํธ ํด ๋ณด์!
1) ํฐ๋ฏธ๋์์ ๋ฐ๋ก ํ์ธํ๊ธฐ
node -e 'console.log("โ
Node.js is working!");'

์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ๋ฉด ํฐ๋ฏธ๋์ โ Node.js is working! ์ด ์ถ๋ ฅ๋๋ค.
2) ๊ฐ๋จํ Express ์๋ฒ ๋์ ๋ณด๊ธฐ
1. ์ ๋๋ ํฐ๋ฆฌ ์์ฑ & ์ง์
mkdir ~/my-node-app && cd ~/my-node-app

2. ํ๋ก์ ํธ ์ด๊ธฐํ & Express ์ค์น
npm init -y
npm install express
๋ฌธ์ ๋ฐ์!! ๋ฌธ์ ํด๊ฒฐํ๊ณ ๊ฐ๊ธฐ!

์ง๊ธ ํฐ๋ฏธ๋ ๋ก๊ทธ๋ฅผ ๋ณด๋, ๋ ๊ฐ์ง๊ฐ ์์ฌ ์๋ค.
- ์๋ฌ ์์ด npm init·npm install express ๊น์ง ์ ์คํ → package.json ํ์ผ์ด ์์ฑ๋๊ณ , express ๋ชจ๋๋ ์ค์น๋จ
- ๊ทธ ๋ค์์ “node index.js”๋ฅผ ์คํํ์ง๋ง, index.js ํ์ผ์ด ์์ด์ ์๋์ ๊ฐ์ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ฌ๋ค.
Error: Cannot find module '/home/ec2-user/my-node-app/index.js'

์ฆ,
๋ฌธ์ ์์ฝ
๋ฌธ์ : index.js ํ์ผ์ด ์์ด์ Node๊ฐ ์คํํ ์ง์ ์ (์ํธ๋ฆฌ) ๋ชจ๋์ ์ฐพ์ ์ ์์.
๋ฐ์ ๋จ๊ณ: “์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋ ์์ฑ ๋จ๊ณ” — ๋ฐํ์(ํ๊ฒฝ) ์ค๋น๊ฐ ๋๋๊ณ ์ค์ ์๋ฒ ์ฝ๋๋ฅผ ๋ง๋ค์ด์ ์คํํด ๋ณด๋ ๋จ๊ณ์ด๋ค.
ํด๊ฒฐ์ฑ
- ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋
cd ~/my-node-app
2. index.js ํ์ผ ์์ฑ & ์ฝ๋ ์์ฑ - ํธ์ง๊ธฐ(์: vi, nano)๋ก ์ด๊ณ ์๋ ์ฝ๋๋ฅผ ๋ถ์ฌ ๋ฃ์ด์ผ ํ๋ค.
vi index.js
๋ฅผ ์ ๋ ฅํ๋ฉด

์ด๋ฌํ ์ฐฝ์ด ๋จ๊ณ ์๋์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํด์ฃผ๋ฉด ๋๋ค.
import express from 'express';
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello from EC2 Express!');
});
app.listen(PORT, () => {
console.log(`๐ Server listening on http://localhost:${PORT}`);
});
Vi ์ฌ์ฉ๋ฒ :
1) i ๋๋ฌ INSERT ๋ชจ๋ ์ง์ ์ฝ๋๋ฅผ ๋ถ์ฌ๋ฃ๊ธฐ
2) Esc → :wq → Enter ๋ก ์ ์ฅ ํ ์ข ๋ฃ
Nano ์ฌ์ฉ๋ฒ:
1) ์ฝ๋ ๋ถ์ฌ๋ฃ๊ธฐ
2) Ctrl+O → Enter (์ ์ฅ)
3) Ctrl+X (์ข ๋ฃ)
3. package.json์ ES ๋ชจ๋ ํ์ ์ง์
package.json์ ๋ค์ ํ ์ค์ ์ถ๊ฐํด์ผ import ๋ฌธ๋ฒ์ด ๋จนํ๋ค.
๋ ์๋์ ๋ช ๋ น์ด๋ฅผ ์ณ์ package.json ํ์ผ ๋ด์ฉ์ ์์ ํด์ผ ํ๋ค.
vi package.json
{
"name": "my-node-app",
"version": "1.0.0",
"type": "module", // ES ๋ชจ๋ ์ฌ์ฉ ์ ์ธ
"main": "index.js", // ์ง์
ํ์ผ
"scripts": {
"start": "node index.js" // ๋์ค์ npm start ๋ก ์คํ ๊ฐ๋ฅ
},
"dependencies": {
"express": "^4.18.2" // ์ด๋ฏธ ์ค์น๋ express ๋ฒ์
}
}

์ ์ ์คํ ๋์ด์ ํฐ๋ฏธ๋์ ์๋์ ๊ฐ์ ๋ฉ์์ง๊ฐ ๋ํ๋ฌ๋ค.
๐ Server listening on http://localhost:3000
ํ๋์ ๋จ๊ณ ์ ๋ฆฌ
1. vi index.js (๋๋ nano index.js)
2. JS ์ฝ๋ ๋ถ์ฌ๋ฃ๊ธฐ → ์ ์ฅ
3. package.json์ "type":"module" ์ถ๊ฐ
4. node index.js๋ก ์คํ
์ด๋ ๊ฒ ํ์๋ฉด Bash๊ฐ ์๋๋ผ Node๊ฐ ์ฝ๋๋ฅผ ์คํํ๊ฒ ๋์ด ์๋ฌ ์์ด ์๋ฒ๊ฐ ๋ฌ๋ค.
