오늘 끝나면 이렇게 됩니다. 옆자리에 앉은 분이 자기 핸드폰을 꺼내서, 여러분이 만든 화면에 들어옵니다. 지금까지는 내 노트북에서만 돌던 앱이었죠. 오늘은 그걸 인터넷에 올립니다.
이 페이지는 위에서부터 순서대로 따라 하시면 됩니다. 명령어는 오른쪽 복사 버튼을 누르면
그대로 복사됩니다. 중간에 막히셔도 괜찮습니다 — 맨 아래에 막혔을 때 보는 표를 두었습니다.
준비물 세 가지
돈 이야기부터 하고 갈게요. 오늘 만드는 서버는 켜 둔 시간만큼 요금이 나갑니다.
한두 시간이면 커피값도 안 됩니다. 문제는 안 지우면 계속 나간다는 것이죠.
그래서 오늘은 요금 알림을 제일 먼저 걸고, 맨 마지막에 다 같이 지웁니다.
먼저 확인할 게 하나 있습니다.
있으시다면 — 새로 가입하지 마세요. 그 계정으로 로그인하시면 됩니다.
비밀번호가 기억나지 않으면 로그인 화면의 "비밀번호를 잊으셨나요" 로 재설정하세요.
왜냐하면 카드 한 장으로는 계정을 하나만 만들 수 있기 때문입니다.
예전에 쓰던 카드로 새로 가입하면 중간에 막힙니다. "나는 처음인데 왜 막히지?" 싶으시다면
예전에 만든 계정이 아직 살아 있는 것입니다. (강사도 여기서 막혀 봤습니다.)
가입 주소입니다.
https://portal.aws.amazon.com/billing/signup순서대로 이렇게 진행됩니다.
✅ 이게 보이면 성공 — 콘솔(관리 화면)이 열립니다.
화면 오른쪽 위에 지역 이름이 있습니다. 그걸 눌러서 아시아 태평양(서울) 으로 바꿔 주세요.
우리가 만들 서버가 어느 나라 데이터센터에 놓일지를 고르는 겁니다. 서울로 해두면 가깝고 빠릅니다.
⚠️ 이걸 안 바꾸면 나중에 "내가 만든 서버가 목록에 없어요" 가 됩니다. 다른 지역에 만들어져서요.
서버를 만들기 전에 겁니다. 만들고 나서 하면 "나중에 하지 뭐"가 되고, 그러다 요금이 나갑니다.
아래 주소로 들어가세요.
https://us-east-1.console.aws.amazon.com/costmanagement/home#/budgetsCreate budget (예산 생성) 을 누릅니다Use a template (템플릿 사용) 을 고릅니다Zero spend budget (제로 지출 예산) 을 고릅니다Create budget✅ 이게 보이면 성공 — 목록에 방금 만든 예산이 한 줄 생깁니다.
이게 무슨 뜻이냐면 — 이 계정에서 단돈 몇 십 원이라도 나가는 순간 이메일이 옵니다.
금액을 안 물어보는 이유가 그겁니다. "0원을 넘으면 알려줘"로 이미 정해져 있거든요.
잠깐, 아까 서울로 바꾸라고 하지 않았나요? 이 화면은 지역을 고를 수 없고
Global하나만 나옵니다. 정상입니다. 서버는 서울에 놓이지만, 청구서는 계정 전체에 하나뿐이라 지역이 없는 겁니다.
여기가 오늘 가장 오래 걸리는 단계입니다. 천천히 가겠습니다.
이 한 화면에서 세 가지가 한꺼번에 일어납니다 — 서버를 만들고 · 열쇠를 받고 · 들어올 문을 엽니다.
https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#LaunchInstances:위에서부터 차례대로 채워 나가시면 됩니다.
w3-demo 라고 적습니다버전 번호는 신경 쓰지 않으셔도 됩니다. 목록에 뜨는 걸 그냥 고르시면 돼요.
t3.micro)을 고릅니다가장 싼 것이고, 오늘 하려는 일에는 차고 넘칩니다.
Create new key pair 를 누릅니다w3-demo-key, 형식은 RSA, .pem 을 고릅니다✅ 다운로드 폴더에 w3-demo-key.pem 이 실제로 있는지 지금 확인하세요.
⚠️⚠️ 이 파일은 다시 받을 수 없습니다. 지금 이 순간에만 받을 수 있어요.
왜 비밀번호를 안 주고 파일을 줄까요? 비밀번호는 찍어서 맞힐 수 있지만,
이 파일은 그럴 수가 없습니다. 그래서 서버는 처음부터 열쇠 파일만 줍니다.
Edit (편집) 을 누릅니다누르면 이런 게 보입니다. 한 줄만 들어 있습니다.
Security group rule 1
Type: ssh Port: 22 Source: Anywhere우리는 두 줄이 필요합니다. 두 번째 줄은 직접 만들어야 합니다.
Add security group rule 버튼을 누릅니다Security group rule 2)을 이렇게 채웁니다Type: Custom TCP Port range: 8000 Source type: Anywhere✅ 이게 보이면 성공 — 규칙이 두 줄이 됩니다.
이게 무슨 뜻이냐면 — 서버는 기본적으로 모든 문이 잠겨 있습니다.
여기서 연 문으로만 들어올 수 있어요.
이 문을 안 열면, 앱은 잘 돌아가는데 밖에서는 아무도 못 들어옵니다.
Launch instance 를 누릅니다Running 이 되기를 기다립니다 (1분쯤 걸립니다)Public IPv4 address 를 복사해 둡니다 ← 이게 내 서버 주소입니다✅ 이게 보이면 성공 — 13.125.xxx.xxx 같은 숫자 네 덩어리가 보입니다.
앞으로 나오는 퍼블릭IP 자리에 이 숫자를 그대로 바꿔 넣으시면 됩니다.
⚠️ 다른 자료에서는 <퍼블릭IP> 처럼 꺾쇠로 표시하기도 하는데, 꺾쇠 < > 는 치는 게 아니라 지우는 것입니다.
이 문서는 헷갈리지 않게 처음부터 꺾쇠 없이 적어 두었습니다.
받은 열쇠 파일은 잠가야 쓸 수 있습니다. 안 잠그면 서버가 거절합니다.
🍎 맥을 쓰신다면 — 터미널을 열고
chmod 400 ~/Downloads/w3-demo-key.pem🪟 윈도우를 쓰신다면 — 파일을 우클릭 → 속성 → 보안 → 고급
이게 무슨 뜻이냐면 — "이 열쇠는 나만 읽을 수 있다" 고 표시하는 겁니다.
남들도 읽을 수 있는 열쇠는 열쇠가 아니니까요. 서버는 그런 열쇠를 아예 안 받아줍니다.
⚠️ 맥과 윈도우가 갈리는 건 이 단계 하나뿐입니다. 다음부터는 똑같습니다.
올릴 앱은 미리 준비해 두었습니다. 아직 안 받으셨다면 지금 받으세요.
https://github.com/seungwon1/w3-demo초록색 Code → Download ZIP → 압축을 풉니다.
이 단계에서 막히는 분이 제일 많은데, 원인은 오타가 아닙니다.
열쇠 파일과 앱 폴더가 서로 다른 곳에 있어서입니다 — 열쇠는 다운로드, 앱은 문서처럼요.
그래서 보내기 전에 둘을 같은 곳에 나란히 둡니다.
w3-demo 폴더를 아무 데나 좋으니 한 곳에 둔다 (예: 문서)w3-demo-key.pem 열쇠 파일을 그 폴더 옆으로 옮긴다 (⚠️ 폴더 안이 아니라 폴더와 나란히)✅ 이게 보이면 성공 — 터미널에 ls (윈도우는 dir) 를 쳤을 때
열쇠와 폴더가 둘 다 보입니다.
w3-demo ← 앱 폴더
w3-demo-key.pem ← 열쇠 파일⭐ 이 화면이 안 나오면 다음 명령은 반드시 실패합니다. 여기서 한 번 맞춰두면
뒤의 명령이 전부 짧아집니다 — 긴 경로를 칠 일이 없어지거든요.
왜 이걸 먼저 하나요? 명령어는 "지금 내가 서 있는 폴더"를 기준으로 파일을 찾습니다. 열쇠와 앱이 다른 곳에 있으면, 명령어를 아무리 정확히 쳐도 "그런 파일 없다" 가 납니다. 옮겨도 열쇠에 걸어둔 잠금(STEP 4)은 그대로 따라갑니다.
퍼블릭IP 자리에 아까 복사한 숫자를 넣으세요.
scp -r -i w3-demo-key.pem w3-demo ubuntu@퍼블릭IP:~/⚠️ 퍼블릭IP 를 숫자로 바꿔야 합니다. ubuntu@3.35.12.34:~/ 처럼 되어야 맞습니다.
그대로 두거나 꺾쇠를 붙이면 주소를 못 찾겠다 는 오류가 납니다.
✅ 이게 보이면 성공 — 파일 이름들이 주르륵 지나가고 끝납니다. 1~2초면 됩니다.
이게 무슨 뜻이냐면 — scp 는 아까 그 열쇠로 파일을 보내는 명령입니다.
방금 내 노트북에 있던 폴더가 저쪽 컴퓨터로 넘어갔습니다.
명령을 조각내면 이렇습니다.
-r — 폴더째로 보내라 (파일 하나가 아니라 폴더라서 필요합니다)-i w3-demo-key.pem — 이 열쇠를 쓰라 (지금 이 자리에 있으니 이름만 쓰면 됩니다)w3-demo — 보낼 폴더 이름ubuntu@ — 서버에서 쓸 사용자 이름입니다. Ubuntu 서버는 ubuntu 로 정해져 있습니다:~/ — 저쪽 컴퓨터의 내 폴더에 놓아라⚠️ w3-demo 자리는 "폴더 이름"입니다. 여기에
파일 이름(app.py)이나 긴 경로(/Users/kim/Documents/w3-demo)를 넣지 마세요.
-r 이 폴더 하나를 통째로 보내는 것이라 이름만 쓰면 안이 알아서 다 따라갑니다.
ssh -i w3-demo-key.pem ubuntu@퍼블릭IP처음 들어갈 때 "계속 연결하시겠습니까" 하고 물으면 yes 를 치고 엔터.
✅ 이게 보이면 성공 — 터미널 맨 앞의 글자가 바뀝니다.
kim@MacBook ~ % ← 원래는 내 노트북
ubuntu@ip-172-31-43-137:~$ ← 지금부터는 저쪽 서버⭐ 여기가 오늘 제일 중요한 순간입니다.
지금부터 치는 명령은 내 노트북이 아니라 저 서버가 실행합니다.
지난주에 "GitHub에 올리면 남들이 쓸 수 있나요?" 라는 질문이 나왔었죠.
답이 여기 있습니다. GitHub은 코드를 보관하는 곳이고, 실행하는 건 지금 이 서버입니다.
둘은 완전히 다른 컴퓨터예요.
이어서 올라온 파일을 확인해 봅시다.
cd w3-demo && ls✅ 이게 보이면 성공
README.md app.py img index.html test_app.py지금 보이는 이 목록은 내 노트북이 아니라 서버 안의 목록입니다.
방금 보낸 파일들이 저쪽에 잘 도착했다는 뜻이죠.
python3 app.py이제 브라우저를 열고 주소창에 이렇게 칩니다.
http://퍼블릭IP:8000✅ 이게 보이면 성공 — 「AI 프로필 사진관」 화면이 뜹니다.
⚠️ https 가 아니라 http 입니다. 자물쇠(보안 인증서)를 안 달았기 때문에,
https 로 들어가면 안 열립니다. 주소창에 직접 http:// 를 쳐 주세요.
이건 버그가 아니라 의도된 겁니다. 지난주에 본 "만들기 전에 먼저 팔아 본다" 가 이겁니다.
AI를 진짜로 만들기 전에, 사람들이 신청을 하는지부터 올려서 확인해 보는 거죠.
축하합니다. 이게 "남이 내 앱을 쓴다"는 것의 실물입니다.
이게 무슨 뜻이냐면 — 이 앱은 지금 그 터미널 창에 매달려 있었던 겁니다.
창을 닫으면 앱도 같이 꺼집니다. 진짜 서비스라면 이러면 안 되겠죠.
계속 켜져 있게 만드는 건 손으로 하면 꽤 깁니다. 그래서 다음 단계부터는 맡깁니다.
여기까지는 모두가 같은 앱을 올렸습니다. 그래서 명령어를 그대로 복사할 수 있었죠.
하지만 여러분이 만든 앱은 파일 이름도 다르고 포트도 다릅니다.
그래서 이제부터는 Claude Code에게 맡깁니다.
내 앱 폴더에서 Claude Code를 열고, 아래를 붙여넣으세요. 빈칸 두 개만 채우시면 됩니다.
이 폴더의 앱을 AWS EC2 서버에 올려서 밖에서 접속되게 해줘.
서버: ubuntu@퍼블릭IP ← 숫자로 바꿔 주세요
키: w3-demo-key.pem ← STEP 5에서 앱 폴더 옆으로 옮긴 그 파일
실행 파일: (예: app.py / main.py / npm start)
포트: (예: 8000)
의존성 설치까지 해주고, 터미널을 닫아도 계속 떠 있게 만들어줘.
끝나면 접속 주소를 알려줘.⚠️ 포트를 8000이 아닌 걸 쓰신다면, EC2 화면으로 먼저 가서 그 번호를 열어 주셔야 합니다
(STEP 3의 ⑤와 같은 방법입니다). 이걸 빠뜨리면 앱은 도는데 밖에서 안 보입니다.
⚠️ 데이터베이스를 쓰는 앱이라면 오늘 안에 다 안 끝날 수 있습니다.
그럴 땐 "화면이 일단 뜬다" 까지만 목표로 잡으세요. 데이터 이야기는 다음 주차에 다룹니다.
아직 만든 앱이 없으셔도 괜찮습니다. STEP 7까지 하신 것으로 오늘 목표는 이미 달성입니다. 옆자리 분이 내 주소로 들어왔으니까요.
오늘 가장 중요한 단계입니다. 안 지우면 요금이 계속 나갑니다.
https://ap-northeast-2.console.aws.amazon.com/ec2/home?region=ap-northeast-2#Instances:w3-demo 를 선택합니다Instance state → Terminate (delete) instance✅ 이게 보이면 성공 — 상태가 Terminated 로 바뀝니다.
(목록에서 잠깐 남아 있다가 곧 사라집니다.)
⚠️ Stop(중지)은 안 됩니다. 서버를 꺼도 저장 공간 요금은 계속 나갑니다.
완전히 없애려면 반드시 Terminate 여야 합니다.
STEP 2에서 걸어둔 요금 알림은 그대로 두셔도 됩니다. 앞으로도 지켜봐 줄 테니까요.
가장 먼저 확인할 것: 화면이 계속 로딩되나요, 아니면 바로 오류가 나나요?
이 둘은 원인이 완전히 다릅니다.
| 이런 증상이면 | 원인은 | 이렇게 하세요 |
|---|---|---|
| 브라우저가 한참 돌다가 안 열림 | ⭐ 8000번 문을 안 열었습니다 | EC2 → 보안 그룹 → 규칙 추가 (STEP 3-⑤) |
https 로 열리면서 안 됨 | 자물쇠를 안 달았습니다 | 주소창에 http:// 를 직접 치세요 |
Permission denied (publickey) | 열쇠를 안 잠갔거나 이름이 틀림 | STEP 4를 다시 · 사용자 이름은 ubuntu |
UNPROTECTED PRIVATE KEY FILE! | 열쇠 파일이 잠기지 않음 | STEP 4의 열쇠 잠그기 — 옮긴 뒤라면 그 자리에서 chmod 400 w3-demo-key.pem |
| 폴더를 못 보낸다고 나옴 | -r 이 빠졌습니다 | scp -r 을 확인 |
⭐ No such file or directory | 열쇠나 폴더가 지금 자리에 없습니다 | STEP 5 앞부분 — ls(dir)로 둘 다 보이는지 |
| ⭐ 주소가 이상하다고 나옴 | 꺾쇠 < > 를 안 지웠습니다 | ubuntu@3.35.12.34:~/ 처럼 숫자만 |
⭐ Not a directory 같은 오류 | 폴더 자리에 파일 이름·긴 경로를 넣었습니다 | 그 자리는 폴더 이름(w3-demo) |
Address already in use | 앱이 이미 켜져 있습니다 | Ctrl + C 로 끄고 다시 켜세요 |
| 만든 서버가 목록에 없음 | 지역이 서울이 아닙니다 | 오른쪽 위에서 서울로 바꾸세요 |
.pem 파일을 못 찾겠음 | 윈도우가 확장자를 숨기고 있을 수 있습니다 | 탐색기 → 보기 → 파일 확장명 체크 |
그래도 안 되시면 손 들어 주세요. 막히는 게 정상입니다 — 특히 8000번 문은
거의 모든 분이 한 번씩 걸리는 자리입니다.
**내 노트북에만 있던 앱을, 인터넷에 있는 컴퓨터 한 대를 빌려서 그 위에 올리고,
문을 하나 열어 남들이 들어올 수 있게 만들었습니다.**
그 과정에서 나온 것들 — 주소(퍼블릭 IP), 열쇠(pem 파일), 문(보안 그룹),
요금(켜 둔 만큼) — 이 넷이 지난주에 "올리는 순간 반드시 생긴다" 고 했던 그 넷입니다.