[컴][웹] elasticbeanstalk 에서 nodejs server application 배포하기 (ts file)

 aws / node / express / typescript 배포 하기  /beanstalk 에서 typescript 배포하기

elasticbeanstalk 에서 nodejs server application 배포하기

환경

  • typescript 로 작성한 nodejs 서버 이다.
  • git 을 사용중인 prjoect folder 에서 작업을 한다.

ElasticBeanstalk 환경 생성

eb init

eb init 을 하면 환경설정을 하게 되고, 이 설정값들을 .elasticbeanstalk 에 저장하게 된다. 이 값을 가지고 eb create 을 하면 실제 환경을 만들어주게 된다.


(.ebcli-virtual-env) D:\a\prog\nodejs\myapi-kraken>eb init

Select a default region
1) us-east-1 : US East (N. Virginia)
...
10) ap-northeast-2 : Asia Pacific (Seoul)
...
22) af-south-1 : Africa (Cape Town)
(default is 3): 10


Select an application to use
1) test
2) [ Create new Application ]
(default is 2): 2


Enter Application Name
(default is "myapi-kraken"):
Application myapi-kraken has been created.

It appears you are using Node.js. Is this correct?
(Y/n):
Select a platform branch.
1) Node.js 12 running on 64bit Amazon Linux 2
2) Node.js 10 running on 64bit Amazon Linux 2
3) Node.js running on 64bit Amazon Linux
(default is 1): 1

Do you wish to continue with CodeCommit? (Y/n): n
Do you want to set up SSH for your instances?
(Y/n):

Select a keypair.
1) aws-eb
3) [ Create new KeyPair ]
(default is 1): 1


(.ebcli-virtual-env) D:\a\prog\nodejs\myapi-kraken>

eb ssh <env_name>

이제 ssh 접속을 할 수 있다. ~/.ssh 에 위에서 선택한 .pem file 을 가지고 있으면 된다. windows 는 c:\Users\<user>\.ssh 에 있으면 된다. 이 경우 user id 는 기본이 'ec2-user' 이다.(?)

.ebextensions/*.config

필요한 환경설정등을 .ebextensions/*.config 에 만들어 준다. 이 부부을 eb create 이후에 한다면, eb deploy 를 통해 적용할 수 있다.

# 01_envar.config
option_settings:
  aws:elasticbeanstalk:application:environment:
    PORT: 8080
    NODE_ENV: production

# 02_nodecommand.config
option_settings:
  aws:elasticbeanstalk:container:nodejs:
    NodeCommand: "npm run start"
    NodeVersion: 14.8.0

eb create

이제 환경을 생성하자 eb create.elasticbeanstalk 폴더에 있는 내용을 보고 환경을 생성하게 된다. 아래는 nodejs server 환경을 생성하다가 실패한 경우이다. 하지만 성공한 경우와 큰 차이는 없다.

(.ebcli-virtual-env) D:\a\prog\nodejs\myapi-kraken>eb create
Enter Environment Name
(default is myapi-kraken-dev): myapi-kraken-env
Enter DNS CNAME prefix
(default is myapi-kraken-env):

Select a load balancer type
1) classic
2) application
3) network
(default is 2): 2


Would you like to enable Spot Fleet requests for this environment? (y/N):
Creating application version archive "app-ffc3-201114_172517".
Uploading myapi-kraken/app-ffc3-201114_172517.zip to S3. This may take a while.
Upload Complete.
Environment details for: myapi-kraken-env
  Application name: myapi-kraken
  Region: ap-northeast-2
  Deployed Version: app-ffc3-201114_172517
  Environment ID: e-29wg7isd2b
  Platform: arn:aws:elasticbeanstalk:ap-northeast-2::platform/Node.js 12 running on 64bit Amazon Linux 2/5.2.3
  Tier: WebServer-Standard-1.0
  CNAME: myapi-kraken-env.ap-northeast-2.elasticbeanstalk.com
  Updated: 2020-11-14 08:25:17.867000+00:00
Printing Status:
2020-11-14 08:25:16    INFO    createEnvironment is starting.
2020-11-14 08:25:18    INFO    Using elasticbeanstalk-ap-northeast-2-436912540370 as Amazon S3 storage bucket for environment data.
2020-11-14 08:25:38    INFO    Created target group named: arn:aws:elasticloadbalancing:ap-northeast-2:436912540370:targetgroup/awseb-AWSEB-14LKDYTHZOP4I/a84457c3808ce6b7
2020-11-14 08:25:38    INFO    Created security group named: sg-087371d1d47d6d3bb
2020-11-14 08:25:54    INFO    Created security group named: awseb-e-29wg7isd2b-stack-AWSEBSecurityGroup-1PHYYVGESOIIO
2020-11-14 08:25:54    INFO    Created Auto Scaling launch configuration named: awseb-e-29wg7isd2b-stack-AWSEBAutoScalingLaunchConfiguration-XKMWT9FWZJQ3
2020-11-14 08:27:11    INFO    Created Auto Scaling group named: awseb-e-29wg7isd2b-stack-AWSEBAutoScalingGroup-1TIV3BQ7UPKPK
2020-11-14 08:27:11    INFO    Waiting for EC2 instances to launch. This may take a few minutes.
2020-11-14 08:27:11    INFO    Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-2:436912540370:scalingPolicy:4022508e-deba-47ff-adeb-a3b335a73b25:autoScalingGroupName/awseb-e-29wg7isd2b-stack-AWSEBAutoScalingGroup-1TIV3BQ7UPKPK:policyName/awseb-e-29wg7isd2b-stack-AWSEBAutoScalingScaleDownPolicy-B1HXPLL7X39P
2020-11-14 08:27:11    INFO    Created Auto Scaling group policy named: arn:aws:autoscaling:ap-northeast-2:436912540370:scalingPolicy:8f71ad5b-01b4-49a7-b413-081eaa783b13:autoScalingGroupName/awseb-e-29wg7isd2b-stack-AWSEBAutoScalingGroup-1TIV3BQ7UPKPK:policyName/awseb-e-29wg7isd2b-stack-AWSEBAutoScalingScaleUpPolicy-1SHCH6FXIPDQR
2020-11-14 08:27:14    INFO    Created CloudWatch alarm named: awseb-e-29wg7isd2b-stack-AWSEBCloudwatchAlarmLow-EEG4M338JDYT
2020-11-14 08:27:15    INFO    Created CloudWatch alarm named: awseb-e-29wg7isd2b-stack-AWSEBCloudwatchAlarmHigh-1E76U1N3AB3NF
2020-11-14 08:27:46    INFO    Created load balancer named: arn:aws:elasticloadbalancing:ap-northeast-2:436912540370:loadbalancer/app/awseb-AWSEB-6UJ9SUHQ4Q9T/bbfeeaee34a8b129
2020-11-14 08:27:46    INFO    Created Load Balancer listener named: arn:aws:elasticloadbalancing:ap-northeast-2:436912540370:listener/app/awseb-AWSEB-6UJ9SUHQ4Q9T/bbfeeaee34a8b129/b990129d759086a1
2020-11-14 08:27:49    INFO    Instance deployment: You didn't specify a Node.js version in the 'package.json' file in your source bundle. The deployment didn't install a specific Node.js version.
2020-11-14 08:28:03    ERROR   Instance deployment failed. For details, see 'eb-engine.log'.
2020-11-14 08:28:03    ERROR   Instance deployment failed to generate a 'Procfile' for Node.js. Provide one of these files: 'package.json', 'server.js', or 'app.js'. The deployment failed.
2020-11-14 08:28:05    ERROR   [Instance: i-0b72af3580a9339fd] Command failed on instance. Return code: 1 Output: Engine execution has encountered an error..
2020-11-14 08:28:05    INFO    Command execution completed on all instances. Summary: [Successful: 0, Failed: 1].
2020-11-14 08:29:08    ERROR   Create environment operation is complete, but with errors. For more information, see troubleshooting documentation.

ERROR: ServiceError - Create environment operation is complete, but with errors. For more information, see troubleshooting documentation.

eb logs

위에서 실패한 경우에 error log 를 확인할 수 있다. log 에도 적혀 있지만 일단 1차적으로 eb-engine.log 를 확인해 보면 된다. eb-engine.log 를 확인하기 위해서는 eb logs 를 사용하면 된다.

(.ebcli-virtual-env) D:\a\prog\nodejs\myapi-kraken>eb logs
Retrieving logs...
============= i-0b72af3580a9339fd ==============
----------------------------------------
/var/log/eb-engine.log
----------------------------------------
...
d@1.0.1 /var/app/staging/node_modules/es5-ext/node_modules/d
type@1.2.0 /var/app/staging/node_modules/type
-- More  --

여기서의 이슈는 .ts 로 된 nodejs application 이어서 문제가 됐다. server.js 나 app.js 가 없기 때문이다. 지금 상황은 environment 는 생성된 상황이므로, 다시 시도를 하고 싶다면 eb deploy 를 하면 된다.

eb deploy

eb deploy 로 배포를 하게 되면 var/app/staging 에 file 들을 설치한다. 이 경로는 추후에 변경될 수도 있다. 이것은 find . -name node_modules 로 찾으면 된다.

이 경로로 갔다가 최종 위치final location 로 복사된다. final location 은 var/app/current 이다.

.ebextensions/source_compile.config 에서 아래처럼 container_commands 를 사용하면 이 staging folder 에서 작업을 하게 된다.(참고: https://i5on9i.blogspot.com/2020/10/aws-elastic-beanstalk_30.html)

이유는 모르지만, 아래의 command 는 compile 에서 error 가 떴다. 아마도 ./node_modules/.bin/tsc 이 문제인 듯 싶다. 여하튼 그래서 scripts 안에서 다 처리해 버렸다. 

이 때의 문제는 file permission 같은 문제가 발생한다. 그래서 test 를 해보고, 혹시 sudo 등으로 처리해야 할 것들이 있다면, container_commands 를 이용하는 것이 낫다.

# source_compile.config
container_commands:
  compile:
    command: "./node_modules/.bin/tsc -p tsconfig.json"

아래는 정상적으로 동작했다.

# .ebextensions/source_compile.config
# source_compile.config
container_commands:
  compile:
    command: "npm run myscript"

주의할 점은 package.jsondevDependencies 는 설치를 하지 않는다. 그러므로 typescript 는 dependencies 에 넣어놔야 한다. 만약 test file 도 같이 있다면, test framwork 나 @types등도 tsc 할때 인식해야 해서 필요하다.

node path

참고로 현재 node 는 /opt/elasticbeanstalk/node-install 에 설치된다.

  • /opt/elasticbeanstalk/node-install

tsc 실행

.ebextensions 를 이용해야 한다. 관련내용이 ref. 2, 3, 4 에 있다.

간단하게 npm start 안에 필요한 내용을 넣는 것이 낫다

// package.json
"scripts": {
    "start": "export NODE_ENV=production & npm run build & node dist/server.js",
    "copy": "copyfiles -e src/ts/**/*.ts -u 2 src/ts/**/*.* dist",
    "build": "tsc && npm run copy",
},

npm start

기본적으로 Procfile(Extending Elastic Beanstalk Linux platforms - AWS Elastic Beanstalk) 이라는 것이 내 source root 에 있으면, 여기에서 지정한 command 를 실행한다. 하지만 이 file 이 존재하지 않고, package.json 이 있다면 기본적으로 npm start 를 실행한다.(이것도 자동으로 Procfile 을 만들어서 그 안에 npm start 를 넣은 것이다.)

둘다 없으면, app.jsserver.js 를 찾아서 실행한다.

debugging deploy

ssh 로 접속해서 tail -f /var/log/eb-engine.log 를 하면, deploy 과정을 확인할 수 있다.

tail -f /var/log/eb-engine.log

또는 아래 메뉴로 가서 log 를 확인하자.

Elastic Beanstalk --> Environments --> my-application-js --> Logs

정상적으로 실행이 됐다면, ps aux 를 통해서도 node 가 실행되는 것을 확인할 수 있다. 로그안에 log path(로그 경로) 도 같이 나와 있다.


 

See Also

  1. Configuring the proxy server - AWS Elastic Beanstalk :port 설정등
  2. elastic beanstalk에서 wkhtmltopdf 설치하기

Reference

  1. Deploying an Express application to Elastic Beanstalk - AWS Elastic Beanstalk
  2. How I automatically deployed Typescript to Elastic Beanstalk to speed up server-side development | by Andrew Chung | Quick Code | Medium
  3. Deploying a TypeScript, ExpressJS app into ElasticBeanstalk NodeJS server | by Viet Hoang Le | Medium
  4. Typescript and the Beanstalk | Errietta’s blog ☕: CircleCI 를 이용해서 tsc build 를 하고, CircleCI 에서 beanstalk 로 deploy 하는 방법을 이야기 한다.
  5. Manually run scripts that require access to environment variables on Elastic Beanstalk instances for Amazon Linux 2
  6. How to deploy a Node.js app to the AWS Elastic Beanstalk
  7. Extending Elastic Beanstalk Linux platforms - AWS Elastic Beanstalk

댓글 없음:

댓글 쓰기