Elastic Beanstalk에 Express 애플리케이션 배포 - AWS Elastic Beanstalk

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Elastic Beanstalk에 Express 애플리케이션 배포

이 단원에서는 Elastic Beanstalk 명령줄 인터페이스(EB CLI)를 사용하여 샘플 애플리케이션을 Elastic Beanstalk에 배포한 후, Express 프레임워크를 사용하도록 애플리케이션을 업데이트하는 절차를 살펴봅니다.

필수 조건

이 튜토리얼의 사전 요구 사항은 다음과 같습니다:

  • Node.js 런타임

  • 기본 Node.js 패키지 관리자 소프트웨어인 npm

  • 익스프레스 커맨드 라인 생성기

  • Elastic Beanstalk 명령줄 인터페이스(EB CLI)

나열된 처음 세개 구성 요소의 설치 및 로컬 개발 환경 설정에 대한 자세한 내용은 Node.js 개발 환경 설정을 참조하십시오. 이 자습서에서는 참조된 항목에서도 언급한 Node.js AWS SDK를 설치할 필요가 없습니다.

EB CLI 설치 및 구성에 대한 자세한 내용은 EB CLI 설치EB CLI 구성 단원을 참조하세요.

Elastic Beanstalk 환경 생성

귀하의 애플리케이션 디렉터리

이 튜토리얼에서는 애플리케이션 소스nodejs-example-express-rds 번들용으로 호출되는 디렉터리를 사용합니다. 이 튜토리얼을 위한nodejs-example-express-rds 디렉토리를 만드세요.

~$ mkdir nodejs-example-express-rds
참고

이 장의 각 튜토리얼에서는 애플리케이션 소스 번들용 자체 디렉토리를 사용합니다. 디렉터리 이름은 튜토리얼에서 사용하는 샘플 응용 프로그램의 이름과 일치합니다.

현재 작업 디렉터리를 nodejs-example-express-rds로 변경합니다.

~$ cd nodejs-example-express-rds

이제 Node.js 플랫폼과 샘플 애플리케이션을 실행하는 Elastic Beanstalk 환경을 설정합니다. Elastic Beanstalk 명령줄 인터페이스(EB CLI)를 사용할 것입니다.

애플리케이션용 EB CLI 리포지토리를 구성하기 위해 Node.js 플랫폼을 실행하는 Elastic Beanstalk 환경을 생성합니다
  1. eb init 명령을 사용하여 리포지토리를 만듭니다.

    ~/nodejs-example-express-rds$ eb init --platform node.js --region <region>

    이 명령은 애플리케이션의 환경을 생성하기 위한 설정을 지정하는 .elasticbeanstalk라는 이름의 폴더에 구성 파일을 만들고 현재 폴더의 이름을 딴 Elastic Beanstalk 애플리케이션을 만듭니다.

  2. eb create 명령을 사용하여 샘플 애플리케이션을 실행하는 환경을 생성합니다.

    ~/nodejs-example-express-rds$ eb create --sample nodejs-example-express-rds

    이 명령은 Node.js 플랫폼의 기본 설정과 다음 리소스를 사용하여 로드 밸런싱 수행 환경을 만듭니다.

    • EC2 인스턴스(EC2 instance) - 선택한 플랫폼에서 웹 앱을 실행하도록 구성된 Amazon Elastic Compute Cloud(Amazon EC2) 가상 머신입니다.

      특정 언어 버전, 프레임워크, 웹 컨테이너 또는 그 조합을 지원하도록 각 플랫폼마다 특정 소프트웨어, 구성 파일 및 스크립트 세트를 실행합니다. 대부분의 플랫폼에서는 웹 앱 앞에 위치해 웹 앱으로 요청을 전달하고, 정적 자산을 제공하고, 액세스 및 오류 로그를 생성하는 역방향 프록시로 Apache 또는 NGINX를 사용합니다.

    • 인스턴스 보안 그룹(Instance security group) - 포트 80에서 인바운드 트래픽을 허용하도록 구성된 Amazon EC2 보안 그룹입니다. 이 리소스를 통해 로드 밸런서의 HTTP 트래픽이 웹 앱을 실행하는 EC2 인스턴스에 도달할 수 있습니다. 기본적으로 다른 포트에서는 트래픽이 허용되지 않습니다.

    • 로드 밸런서(Load balancer) - 애플리케이션을 실행하는 인스턴스로 요청을 분산하도록 구성된 Elastic Load Balancing 로드 밸런서입니다. 또한 로드 밸런서가 있으면 인터넷에 인스턴스를 직접 노출할 필요가 없습니다.

    • 로드 밸런서 보안 그룹(Load balancer security group) - 포트 80에서 인바운드 트래픽을 허용하도록 구성된 Amazon EC2 보안 그룹입니다. 이 리소스를 통해 인터넷의 HTTP 트래픽이 로드 밸런서에 도달할 수 있습니다. 기본적으로 다른 포트에서는 트래픽이 허용되지 않습니다.

    • Auto Scaling 그룹(Auto Scaling group) - 인스턴스가 종료되거나 사용할 수 없게 될 경우 인스턴스를 대체하도록 구성된 Auto Scaling 그룹입니다.

    • Amazon S3 버킷(Amazon S3 bucket) - Elastic Beanstalk 사용 시 생성된 소스 코드, 로그 및 기타 아티팩트의 스토리지 위치입니다.

    • Amazon CloudWatch alarms — 환경 내 인스턴스의 부하를 모니터링하고 부하가 너무 높거나 낮을 경우 트리거되는 두 개의 CloudWatch 경보입니다. 경보가 트리거되면 이에 대한 응답으로 Auto Scaling 그룹이 스케일 업 또는 축소됩니다.

    • AWS CloudFormation 스택 — Elastic AWS CloudFormation Beanstalk는 사용자 환경에서 리소스를 시작하고 구성 변경 사항을 전파하는 데 사용합니다. 리소스는 AWS CloudFormation 콘솔에서 볼 수 있는 템플릿에서 정의됩니다.

    • 도메인 이름(Domain name) - subdomain.region.elasticbeanstalk.com 형식으로 웹 앱으로 라우팅되는 도메인 이름입니다.

      참고

      Elastic Beanstalk 애플리케이션의 보안을 강화하기 위해 elasticbeanstalk.com 도메인이 공개 서픽스 목록(PSL)에 등록되어 있습니다. 보안 강화를 위해 Elastic Beanstalk 애플리케이션 기본 도메인 이름에 민감한 쿠키를 설정해야 하는 경우 __Host- 접두사가 있는 쿠키를 사용하는 것이 좋습니다. 이렇게 쿠키를 설정하면 교차 사이트 요청 위조 시도(CSRF)로부터 도메인을 보호하는 데 도움이 됩니다. 자세한 내용은 Mozilla 개발자 네트워크의 Set-Cookie 페이지를 참조하세요.

  3. 환경 생성이 완료되면 eb open 명령을 사용하여 기본 브라우저에서 환경의 URL을 엽니다.

    ~/nodejs-example-express-rds$ eb open

이제 샘플 애플리케이션을 사용하여 Node.js Elastic Beanstalk 환경을 생성했습니다. 자체 애플리케이션으로 업데이트할 수 있습니다. 다음으로 Express 프레임워크를 사용하도록 샘플 애플리케이션을 업데이트합니다.

Express를 사용하도록 애플리케이션을 업데이트하려면

샘플 애플리케이션이 있는 환경을 생성한 후 이를 자체 애플리케이션으로 업데이트할 수 있습니다. 이 절차에서는 먼저expressnpm install 명령을 실행하여 애플리케이션 디렉터리에 Express 프레임워크를 설정합니다. EB CLI를 사용하여 Elastic Beanstalk 환경에 업데이트된 애플리케이션을 배포합니다.

Express를 사용하도록 애플리케이션을 업데이트하려면
  1. express 명령을 실행합니다. 이는 package.json, app.js 및 몇 개의 디렉터리를 생성합니다.

    ~/nodejs-example-express-rds$ express

    계속할지 여부를 묻는 메시지가 표시되면 y를 입력합니다.

    참고

    express명령이 작동하지 않는 경우 이전 사전 요구 사항 섹션에 설명된 대로 Express 명령줄 생성기를 설치하지 않았기 때문일 수 있습니다. 또는express 명령을 실행하려면 로컬 시스템의 디렉터리 경로 설정을 설정해야 할 수 있습니다. 개발 환경 설정에 대한 자세한 단계는 필수 조건 섹션을 참조하십시오. 그러면 이 자습서를 계속 진행할 수 있습니다.

  2. 로컬 종속 항목을 설정합니다.

    ~/nodejs-example-express-rds$ npm install
  3. (선택) 웹 앱 서버가 시작되는지 확인합니다.

    ~/nodejs-example-express-rds$ npm start

    다음과 유사한 출력 화면이 표시되어야 합니다.

    > nodejs@0.0.0 start /home/local/user/node-express > node ./bin/www

    서버는 기본적으로 포트 3000에서 실행됩니다. 테스트하려면 다른 터미널에서 curl http://localhost:3000을 실행하거나 로컬 컴퓨터에서 브라우저를 열고 http://localhost:3000으로 이동하십시오.

    Ctrl+C를 눌러 서버를 중지합니다.

  4. eb deploy 명령으로 Elastic Beanstalk 환경으로 변경된 애플리케이션을 배포합니다.

    ~/nodejs-example-express-rds$ eb deploy
  5. 환경이 녹색이고 준비되면 URL을 새로 고쳐서 작동하는지 확인합니다. Welcome to Express라는 웹 페이지가 보일 것입니다.

다음으로 정적 파일을 제공하고 새 페이지를 추가하도록 Express 애플리케이션을 업데이트하겠습니다.

정적 파일을 구성하고 Express 애플리케이션에 새 페이지를 추가하려면
  1. .ebextensions 폴더에 다음 콘텐츠가 포함된 두 번째 구성 파일을 추가합니다:

    nodejs-example-express-rds/.ebextensions/staticfiles.config

    option_settings: aws:elasticbeanstalk:environment:proxy:staticfiles: /stylesheets: public/stylesheets

    이 설정은 애플리케이션의 public 경로에서 /public 폴더에 있는 파일을 제공하도록 프록시 서버를 구성합니다. 프록시 서버에서 정적으로 파일을 제공하면 애플리케이션의 부하가 감소합니다. 자세한 내용은 이 장의 앞부분에 있는 Stic 파일을 참조하십시오.

  2. (선택 사항) 정적 매핑이 올바르게 구성되었는지 확인하려면 에서 정적 매핑 구성을 주석nodejs-example-express-rds/app.js 처리하십시오. 이렇게 하면 노드 애플리케이션에서 매핑이 제거됩니다.

    // app.use(express.static(path.join(__dirname, 'public')));

    이전 단계의 파일에 있는 정적staticfiles.config 파일 매핑은 이 줄을 주석 처리한 후에도 여전히 스타일시트를 성공적으로 로드할 것입니다. 정적 파일 매핑이 익스프레스 응용 프로그램이 아닌 프록시 정적 파일 구성을 통해 로드되었는지 확인하려면 다음 값을 제거하십시오option_settings:. 정적 파일 구성과 노드 응용 프로그램 모두에서 스타일시트를 제거한 후에는 스타일시트를 로드할 수 없습니다.

    테스트가staticfiles.config 끝나면nodejs-example-express-rds/app.js 및 의 콘텐츠를 모두 재설정해야 합니다.

  3. nodejs-example-express-rds/routes/hike.js를 추가합니다. 다음을 입력합니다.

    exports.index = function(req, res) { res.render('hike', {title: 'My Hiking Log'}); }; exports.add_hike = function(req, res) { };
  4. 새로운 세 줄을 포함하도록 nodejs-example-express-rds/app.js를 업데이트합니다.

    먼저 다음 줄을 추가하여 이 경로에 require를 추가합니다.

    var hike = require('./routes/hike');

    파일은 다음 조각과 비슷해야 합니다.

    var express = require('express'); var path = require('path'); var hike = require('./routes/hike');

    그런 다음 nodejs-example-express-rds/app.js에 다음 두 줄을 추가하여 var app = express(); 뒤에 놓습니다.

    app.get('/hikes', hike.index); app.post('/add_hike', hike.add_hike);

    파일은 다음 조각과 비슷해야 합니다.

    var app = express(); app.get('/hikes', hike.index); app.post('/add_hike', hike.add_hike);
  5. nodejs-example-express-rds/views/index.jadenodejs-example-express-rds/views/hike.jade에 복사합니다.

    ~/nodejs-example-express-rds$ cp views/index.jade views/hike.jade
  6. eb deploy명령을 사용하여 변경 내용을 배포합니다.

    ~/nodejs-example-express-rds$ eb deploy
  7. 몇 분 후 환경이 업데이트됩니다. 환경이 녹색이고 준비되면 브라우저를 새로 고치고 URL의 끝에 hikes를 추가하여(예: http://node-express-env-syypntcz2q.elasticbeanstalk.com/hikes) 작동하는지 확인합니다.

    My Hiking Log라는 제목의 웹 페이지가 보일 것입니다.

Express 프레임워크 를 사용하는 웹 애플리케이션을 생성합니다. 다음 섹션에서는 Amazon 관계형 데이터베이스 서비스(RDS) 를 사용하여 하이킹 로그를 저장하도록 애플리케이션을 수정하겠습니다.

Amazon RDS를 사용할 수 있도록 애플리케이션을 업데이트합니다

다음 단계에서는 Amazon RDS for MySQL RDS를 사용하도록 애플리케이션을 업데이트합니다.

MySQL용 RDS를 사용하도록 애플리케이션을 업데이트하려면
  1. Elastic Beanstalk 환경에 연결된 MySQL용 RDS 데이터베이스를 생성하려면 이 장 뒷부분에 포함된 데이터베이스 추가 항목의 지침을 따르십시오. 데이터베이스 인스턴스를 추가하는 데 약 10분이 걸립니다.

  2. package.json에서 종속성 섹션을 다음 내용으로 업데이트하십시오:

    "dependencies": { "async": "^3.2.4", "express": "4.18.2", "jade": "1.11.0", "mysql": "2.18.1", "node-uuid": "^1.4.8", "body-parser": "^1.20.1", "method-override": "^3.0.0", "morgan": "^1.10.0", "errorhandler": "^1.5.1" }
  3. npm install를 실행합니다.

    ~/nodejs-example-express-rds$ npm install
  4. app.js업데이트하여 데이터베이스에 연결하고, 테이블을 생성하고, 단일 기본 하이킹 로그를 삽입하세요. 이 앱을 배포할 때마다 이전 hikes 테이블을 삭제하고 다시 생성합니다.

    /** * Module dependencies. */ const express = require('express') , routes = require('./routes') , hike = require('./routes/hike') , http = require('http') , path = require('path') , mysql = require('mysql') , async = require('async') , bodyParser = require('body-parser') , methodOverride = require('method-override') , morgan = require('morgan') , errorhandler = require('errorhandler'); const { connect } = require('http2'); const app = express() app.set('views', __dirname + '/views') app.set('view engine', 'jade') app.use(methodOverride()) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.use(express.static(path.join(__dirname, 'public'))) app.set('connection', mysql.createConnection({ host: process.env.RDS_HOSTNAME, user: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, port: process.env.RDS_PORT})); function init() { app.get('/', routes.index); app.get('/hikes', hike.index); app.post('/add_hike', hike.add_hike); } const client = app.get('connection'); async.series([ function connect(callback) { client.connect(callback); console.log('Connected!'); }, function clear(callback) { client.query('DROP DATABASE IF EXISTS mynode_db', callback); }, function create_db(callback) { client.query('CREATE DATABASE mynode_db', callback); }, function use_db(callback) { client.query('USE mynode_db', callback); }, function create_table(callback) { client.query('CREATE TABLE HIKES (' + 'ID VARCHAR(40), ' + 'HIKE_DATE DATE, ' + 'NAME VARCHAR(40), ' + 'DISTANCE VARCHAR(40), ' + 'LOCATION VARCHAR(40), ' + 'WEATHER VARCHAR(40), ' + 'PRIMARY KEY(ID))', callback); }, function insert_default(callback) { const hike = {HIKE_DATE: new Date(), NAME: 'Hazard Stevens', LOCATION: 'Mt Rainier', DISTANCE: '4,027m vertical', WEATHER:'Bad', ID: '12345'}; client.query('INSERT INTO HIKES set ?', hike, callback); } ], function (err, results) { if (err) { console.log('Exception initializing database.'); throw err; } else { console.log('Database initialization complete.'); init(); } }); module.exports = app
  5. 다음 콘텐츠를 routes/hike.js에 추가합니다. 이렇게 하면 경로에서 새 하이킹 로그를 HIKES 데이터베이스에 삽입할 수 있습니다.

    const uuid = require('node-uuid'); exports.index = function(req, res) { res.app.get('connection').query( 'SELECT * FROM HIKES', function(err, rows) { if (err) { res.send(err); } else { console.log(JSON.stringify(rows)); res.render('hike', {title: 'My Hiking Log', hikes: rows}); }}); }; exports.add_hike = function(req, res){ const input = req.body.hike; const hike = { HIKE_DATE: new Date(), ID: uuid.v4(), NAME: input.NAME, LOCATION: input.LOCATION, DISTANCE: input.DISTANCE, WEATHER: input.WEATHER}; console.log('Request to log hike:' + JSON.stringify(hike)); req.app.get('connection').query('INSERT INTO HIKES set ?', hike, function(err) { if (err) { res.send(err); } else { res.redirect('/hikes'); } }); };
  6. routes/index.js의 내용을 다음으로 바꿉니다:

    /* * GET home page. */ exports.index = function(req, res){ res.render('index', { title: 'Express' }); };
  7. 다음 jade 템플릿을 추가하여 하이킹 로그를views/hike.jade 추가하기 위한 사용자 인터페이스를 제공합니다.

    extends layout block content h1= title p Welcome to #{title} form(action="/add_hike", method="post") table(border="1") tr td Your Name td input(name="hike[NAME]", type="textbox") tr td Location td input(name="hike[LOCATION]", type="textbox") tr td Distance td input(name="hike[DISTANCE]", type="textbox") tr td Weather td input(name="hike[WEATHER]", type="radio", value="Good") | Good input(name="hike[WEATHER]", type="radio", value="Bad") | Bad input(name="hike[WEATHER]", type="radio", value="Seattle", checked) | Seattle tr td(colspan="2") input(type="submit", value="Record Hike") div h3 Hikes table(border="1") tr td Date td Name td Location td Distance td Weather each hike in hikes tr td #{hike.HIKE_DATE.toDateString()} td #{hike.NAME} td #{hike.LOCATION} td #{hike.DISTANCE} td #{hike.WEATHER}
  8. eb deploy명령을 사용하여 변경 내용을 배포합니다.

    ~/nodejs-example-express-rds$ eb deploy

정리

Elastic Beanstalk 작업을 완료한 경우 환경을 종료할 수 있습니다.

eb terminate 명령을 사용하여 환경과 환경에 있는 모든 리소스를 종료합니다.

~/nodejs-example-express-rds$ eb terminate The environment "nodejs-example-express-rds-env" and all associated instances will be terminated. To confirm, type the environment name: nodejs-example-express-rds-env INFO: terminateEnvironment is starting. ...