기술 스택
- aws rds
- aws elasticbeanstalk
- github action
- nestjs
- typeorm
만났던 문제들
1. Database error
- synchronize: true였다가 false로 바꿨던 상황을 조금 뒤늦게 인지
- 로컬에서 pgAdmin으로 aws rds에 붙어서 확인해보니까 테이블 생성이 안 된 걸 확인
- 아 엔티티 스키마가 아예 반영이 안 됐구나
- 마이그레이션 해보자
2. .ebextensions/01_migration.config에 마이그레이션 명령어 추가
commands:
01_run_migration:
command: |
#!/bin/bash
cd /var/app/current
export DB_TYPE=$DB_TYPE
export DB_HOST=$DB_HOST
export DB_PORT=$DB_PORT
export DB_USERNAME=$DB_USERNAME
export DB_PASSWORD=$DB_PASSWORD
export DB_DATABASE=$DB_DATABASE
npx typeorm migration:run -d dist/data-source.js
leader_only: true
- 명령어 실행에 번번이 에러가 발생
- 확인해보니 빌드 결과물인 dist가 /var/app/current에 없음
- 이리저리 알아봤지만 이 방법은 안 됨
- 이상한 방법임
- 이 방법을 추천한 Grok을 처음으로 블랙홀에 던져버리고 싶었음
- Github Action 워크플로우에 npx typeorm migration..을 추가하기로 함
3. 환경변수 문제
- DataSource에 환경변수가 들어가는데, 리포지토리 설정에 추가해놨는데도 계속 못 읽음
- 알고 보니 GithubAction 스텝이 진행되면서 실행되는 코드는 다시 별도로 변수를 만들어줘야 함을 알게됨
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
DB_TYPE: ${{ secrets.DB_TYPE }}
DB_HOST: ${{ secrets.DB_HOST }}
DB_PORT: ${{ secrets.DB_PORT }}
DB_USERNAME: ${{ secrets.DB_USERNAME }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
DB_DATABASE: ${{ secrets.DB_DATABASE }}
ENV: ${{ secrets.ENV }}
4. no encrypt 이슈
- 이건 또 뭐임
- 알고 보니 ssl 설정이 필요한 거였음
- data-source.ts에 ENV === 'prod' 일 때는 ssl 설정이 적용될 수 있게 함
- rejectUnauthorized: false를 설정하더라도 ssl 설정은 추가해야함
dotenv.config();
export default new DataSource({
type: process.env.DB_TYPE as 'postgres',
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT || '5432'),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
synchronize: false,
logging: false,
entities: ['dist/**/*.entity.js'],
migrations: ['dist/database/migrations/*.js'],
...(process.env.ENV === envKeys.prod && {
ssl: {
rejectUnauthorized: false,
},
}),
});
5. 그리고 당연한 거지만 마이그레이션 파일이 dist 폴더에 이미 존재해야 함
6. 드디어 에러 메시지가 마이그레이션 관련 오류로 바뀜 users_roles_enum 테이블이 없다는 생전 처음 보는 에러 문구를 만남
- synchronize: true 일 때 알아서 해주던 것의 고마움을 잊고 살았음
- rbac을 하기 위해 users 테이블에서 Role enum 타입의 컬럼(배열)이 존재함
- enum 타입을 사용하기 위해 데이터베이스에 enum type을 만들어야 하는 거였음
- 그런데 알고 보니 enum은 숫자가 안 됨
- 난 그동안 숫자를 잘만 넣었는데? synchronize: true 고맙다..
- 알고 보니 데이터베이스에 enum type을 생성할 때 숫자는 안 되니까 user 엔티티의 Role 타입 컬럼의 type을 자동으로 int로 만들었던 것
- enum type은 자동으로 만들어주지도 않아서 마이그레이션 파일을 새로 만들어서 enum type이 만들어지고 나서 테이블이 생성되도록 조정해놨는데 필요 없는 설정이었음
- 다음처럼 해서 문제 해결
@Column({
type: 'int', // 'enum' 이었음
enum: Role,
default: [Role.user],
array: true,
})
roles: Role[];
7. 드디어 마이그레이션도 통과하고 ElasticBeanstalk(이하 EB)에서 환경설정이 업데이트 되는데 nest nof found 에러가 발생함
- 갑자기 웬 nest 명령어?
- 개발할 때 사용하는 nest cli이기 때문에 만나면 안 되는데
- 알고보니 가장 처음에 수동으로 zip 파일을 배포할 때 그냥 프로젝트 전체를 압축한 거라 섬세하게 생각하지 못했었는데
- 파일 압축할 때 Procfile을 빼먹었음
- nest.js는 express 혹은 fastify을 랩핑하는데 express 기준으로, 배포할 때 Profile에 명령어를 넣어줘야 함
- 그래서 nest.js 배포할 때도 넣어줘야 함
web: npm run start:prod
// package.json
"start:prod": "node dist/main",
8. 배포 파일을 압축할 때 Profile 파일을 포함
- zip -r deploy.zip dist package.json Procfile
9. 이제 진짜 된 거 같은데 EB 환경설정 업데이트를 계속 실패
- 자꾸 타임아웃 발생하고
- 메모리인지 CPU 사용량인지 엄청 올라감
- 아, 컴퓨터가 느린 거구나
10. 애플리케이션 재생성해서 t3.small로 해서 드디어 배포 성공!
이렇게 축약했을 때 10단계고 실제로는 더욱 지난한 과정이었다.
꼬박 하루(24시간)이 조금 더 걸림. 해결하고 나면 쉽지만 그 전까지는 어떤 문제인지 찾기가 너무 어렵다.
결론: 배포는 어렵다. 성취감은 좋다. 그런데 어렵다.
'개발 > Web' 카테고리의 다른 글
| [Docker] 메모리 부족 문제 (feat. Win11) (0) | 2025.09.24 |
|---|---|
| WSL2에서 윈도우 로컬 스프링 서버로 통신하기 (3) | 2025.07.29 |
| CI/CD에서의 gradle과 로컬에서의 gradle (3) | 2025.07.24 |
| [Spock Framework] Stubbing and Mocking (2) | 2025.07.23 |
| RSA 공개키 방식과 AWS EC2 (0) | 2023.12.30 |