-
[4월 3주차-4/15-16]Node.js & AWS를 활용한 이미지 갤러리 웹사이트 구축기Why Not SW CAMP 5기/수업 기록 2025. 4. 16. 11:32
🚀 프로젝트 개요
Node.js와 Express, 그리고 AWS의 다양한 서비스를 활용하여 이미지 업로드 및 갤러리 웹사이트를 구축했습니다. EC2에 직접 서버를 띄우고 S3를 이미지 저장소로 활용했으며, CloudFront를 이용해 퍼포먼스를 개선하고 PM2로 서버 프로세스를 관리하도록 설정했습니다.
✔️ EC2 인스턴스 설정
- EC2 인스턴스 생성: myserver
- SSH 접속 후 시스템 업데이트 및 Node.js 설치:
# 패키지 목록 업데이트 sudo apt-get update # 패키지 설치 sudo apt-get install -y ca-certificates curl gnupg # 디렉터리 생성 sudo mkdir -p /etc/apt/keyrings # 해당 디렉터리에 .gpg 파일 다운로드 curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg # 설치할 node.js 버전 정의 NODE_MAJOR=20 sudo apt-get install -y curl curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh sudo -E bash nodesource_setup.sh # node.js 설치 sudo apt-get install nodejs -y # 버전 확인 node --version
✨ Express 프로젝트 설정
- Express Generator로 프로젝트 생성:
# 권한 변경 sudo mkdir project sudo chown ubuntu:ubuntu project/ # 초기화 npm init -y npm install express sudo npx express-generator --view=ejs project sudo chown -R ubuntu:ubuntu project/ cd project npm install npm start
- 보안 그룹에서 3000 포트 인바운드 열기
- 웹브라우저로 퍼블릭 IP:3000 접속 → Express 홈페이지 확인
📁 이미지 업로드 구현 (Multer)
- npm install multer
- routes/images.js 생성:
const express = require('express'); const router = express.Router(); const fs = require('fs'); const path = require('path'); const multer = require('multer'); const upload = multer({ dest: path.join(__dirname, '..', 'uploads') }); router.post('/', upload.single('new-image'), function (req, res, next) { console.dir(req.file); res.send(); }); module.exports = router;
- app.js에 라우터 등록:
const imagesRouter = require('./routes/images'); app.use('/images', imagesRouter);
📈 클라이언트 HTML + jQuery File Upload
views/index.ejs에 파일 업로드 폼 및 업로드 스크립트 작성:
<input type="file" class="form-control" id="file-upload" name="new-image"> <div id="progress" class="progress"> <div class="progress-bar" style="width: 0%"></div> </div> <div id="image-list"></div> <script> $(function () { $('#file-upload').fileupload({ url: '/images', dataType: 'json', progressall: function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $('#progress .progress-bar').css('width', progress + '%'); } }); }); </script>
☁️ S3와 연동
- @aws-sdk/client-s3 설치
npm install @aws-sdk/client-s3
- 이미지 업로드 시 S3로 전송:
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); const s3Client = new S3Client({ region: 'ap-northeast-2' }); fs.readFile(req.file.path, function (err, data) { s3Client.send(new PutObjectCommand({ Bucket: 'rubi-bucket-20250416', Key: req.file.filename, Body: data, ContentType: req.file.mimetype, })); });
- IAM 역할에 AmazonS3FullAccess 부여
- S3 버킷 생성: rubi-bucket-20250416
🌍 이미지 목록 불러오기 + CloudFront 연동
- S3 → CloudFront 배포 생성 후 오리진 접근 권한 설정
- images.js에 목록 불러오기 코드 추가:
const { ListObjectsV2Command } = require('@aws-sdk/client-s3'); s3Client.send(new ListObjectsV2Command({ Bucket: 'rubi-bucket-20250416', MaxKeys: 50, })).then(data => res.send(data.Contents));
- 클라이언트에서 이미지 출력:
$.getJSON('/images', function (data) { $.each(data, function (i, e) { var img = $('<img>').attr('src', 'https://[CloudFront 도메인]/' + e.Key) .attr({ width: '200px', height: '200px' }) .addClass('img-thumbnail'); $('#image-list').append(img); }); });
⚙️ 서버 운영 최적화 (PM2)
- PM2 설치 및 실행
sudo npm install -g pm2 pm2 start ./bin/www
- 부팅 시 자동 시작 설정
pm2 startup # 출력된 명령어 복사해서 실행 pm2 save
- EC2 재부팅 후에도 서비스 정상 동작 확인
🙌 마무리
이 프로젝트를 통해 EC2 설정부터 Express 웹 서버 구축, S3와 CloudFront 연동, 그리고 서버 프로세스 관리까지 풀스택으로 다뤄볼 수 있었습니다. 실습을 통해 AWS 서비스들을 실전에서 어떻게 연동하는지 경험해볼 수 있어 매우 유익했습니다.
'Why Not SW CAMP 5기 > 수업 기록' 카테고리의 다른 글
[4월 4주차-4/22]📝 Django로 블로그 만들기 – 글/댓글/썸네일까지 (0) 2025.04.22 [4월 4주차-4/21]🍔 Django로 햄버거 검색 웹 만들기 (0) 2025.04.21 [4월 3주차-4/14]AWS 실무 핵심 개념 총정리 💡 | DynamoDB, Lambda, SDK, CLI 완전 이해 (1) 2025.04.14 [4월 2주차-4/11]AWS 기본 서비스(DNS(Route 53), IAM, CloudWatch) 실습 정리 (0) 2025.04.14 [4월 2주차-4/10][AWS 실습] S3 정적 웹 호스팅 & CloudFront CDN 연동하기 (1) 2025.04.10