😮내가 백엔드를 시작하면서 꼭 해보고 싶었던 작업이 있다. 그것은 바로 🌠"배포"🌠 다!!!
왜인지 모르겠지만 백엔드 경험 전에 배포에 대한 환상이 있었던 것 같다. 뭔가 보이지 않는 저장소를 다루면서 기냥 멋있어 보였다랄까..?
나의 배포 경험
사실, 이 글에서는 내가 MySQL를 배포하면서 겪은 수많은 오류와 우여곡절을 기록하려 하기 때문에 프로젝트를 배포한 경험은 다른 글에서 정리해보겠다. (사실 아직도 긴가민가해서 확실히 다시 해보고 기록해야 할 것 같다.)
항상 팀원이 연결해주는 데이터베이스만 받아서 쓰다가 제일 먼저 데이터베이스를 활용하여 테스트를 해볼 일이 생겨 그래, 이번 기회에 내가 DB를 연결해보자! 하고 시작하게 되었다.
프로젝트에서는 NestJS
와 TypeORM
을 사용하기로 했고, 역시나 모든게 처음인 나는.. 당황하지 않고 뭐를 찾자? 공식문서... 👏🏻 ( NestJS
한국어 매뉴얼 감사해요,,, 💕)
근데 TypeORM이 뭐지?
공식문서에 따르면 TypeORM
은 node.js
에서 가장 성숙한 객체 관계형 매퍼(ORM)이라고 한다. TypeScript
로 작성되어 NestJS
와도 잘 맞는다고 한다. 그니까, 한마디로 SQL쿼리를 직접 작성하지 않아도 데이터베이스의 데이터를 자동으로 매핑시켜주는 프레임워크라고 할 수 있다.
일단, 설치부터 해보자.
$ npm install --save @nestjs/typeorm mysql2
설치가 완료되면 TypeOrmModule
을 루트 AppModule
로 가져올 수 있다.
app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost', //process.env.DB_HOST
port: 3306,
username: 'root', //process.env.DB_USER
password: 'root', //process.env.DB_PASSWORD
database: 'test', //process.env.DB_DATABASE
entities: [],
synchronize: true,
}),
],
})
export class AppModule {}
구성 객체를 forRoot()에 직접 작성하지 않고 루트 디렉토리에 ormconfig.json파일로도 저장할 수 있다.
우리는 .env파일을 따로 만들어 변수로 저장하고 있었기 때문에 아래 변수에 각각 뭐가 들어가야되나 고민하다가 처음엔 localhost로 지정해주었다.
# mysql DB
DB_USER=root
DB_HOST=
DB_PASSWORD=
DB_DATABASE=
#jwt key
SECRET_KEY=''
근데 당연하게도(?) localhost는 로컬에서만 돌아가니까 데이터를 팀원과 공유할 수 없었다. 그래서 전에 배포할 때 썼던 AWS EC2를 이용해서 데이터베이스를 배포하기로 했다.
AWS EC2로 MySQL 배포
우선, MobaXterm을 이용하여 ubuntu에 mysql을 설치했다.
$ apt-get update
$ sudo apt-get install mysql-server
$ mysql -u root -p
그리고 mysql을 시작해보려는데,
아니.. 왜 안되는건데.. 💦💦
비밀번호도 맞게 입력했는데 자꾸 권한이 아니랜다. 왜지? 구글링 해보니까 root권한으로 실행시키면 보안상 위험할 수 있어서 특정 사용자로 실행시키는 것이 좋다고 한다. (근데 왜 비번이 아니라는건지는 모르겠다..ㅠㅠ)
$ /usr/bin/mysql -u root -p
휴,, 일단 mysql실행은 시켰다. 그리고 특정 사용자로 실행시켰으니 권한도 부여해준다.
mysql> create user 'root'@'%' identified by '[password]';
mysql> grant all privileges on *.* to 'root'@'%' with grant option;
그리고 이제 됐겠지? 하고 Workbench에서 TestConnection을 시도했지만 여전히 에러... 대체 왜지??
그래서 mysql
이 실행 상태가 아닌가..? 하고 상태 확인도 해줬다.
$ systemctl status mysql # mysql 상태확인
$ systemctl stop mysql # mysql 실행중지
$ netstat -tnlp # 포트확인
근데 아주 active하기만 한 mysql.... 그리고 포트를 확인했는데
음?? 왜 127.0.0.1 ...? 뭐지? 하고 폭풍 구글링. 현재 mysql은 로컬로 연결되어 있기때문에 당연히 안되는 것이었다. 그래서 리눅스 포트 외부접속을 허용해줘야 하는데, vi로 mysql.config 파일을 열어 IP주소를 변경해 주어야 한다.
$ cd etc/mysql/mysql.conf.d
$ vi mysqld.cnf
bind-adress
를 바꿔주고 저장하려는데 :wq
가 안먹는다. 'readonly' option is set
오류가 난다. 진짜 산넘어 산이구나.
또 폭풍검색.. 💨💨
해당 오류는 vi편집기로 파일 수정 후 쓰기 권한이 없어서 나는 오류라고 한다. 해결방법은 :wq!
느낌표를 붙여서 강제 저장하거나 그것도 안되면 sudo
를 통해 관리자 권한으로 다시 열어야 한다.
(참고 : 우분투 vi 편집 저장시 'readonly' option is set 오류)
이제 진짜 다 됐겠지..? 하고 TestConnection해보니 드디어 연결!!!!!
진짜진짜마지막_최종(5).pdf
🐛그리고 진짜 진짜 마지막 오류..
해당 오류는 캡쳐는 못했지만, 프로젝트 실행 후, postman
을 이용하여 DB에 값을 넣으려니 저런 에러가 나왔다.
Error Number: 1267
Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='
SELECT COUNT(*) as num from keywords WHERE campaignId='12' AND LCASE(keyword)='hello again 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'
뭔진 모르겠는데 뭔가 utf8 이러는거 보니까 한글때문에 오류가 난 것 같았다. 또 구글링. (구글신님은 모든걸 알고계시지..)
SET collation_connection = 'utf8_general_ci';
ALTER DATABASE your_database_name CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
StackOverFlow(참고링크)에서 나와 같은 오류를 겪은 사람의 도움을 받아 겨우 오류를 해결했다.....
부족한 점
부족한 점이야.. 차고 넘치지.. 그래도 다시 꼭 봐야할 것은,
ubuntu에 익숙하고 네트워크를 잘 알았다면 조금 더 빨리 해결할 수 있었을까? 반성하면서 오늘도 공부할게 하나씩 늘어간다.. 그래도, 정말 우여곡절 끝에 나와 같은 오류를 겪었던 분들, 알려주신 분들 구글링 덕분에 혼자 힘으로 해결할 수 있었다 ㅠ.ㅠ
에러는 마주치면 답답하고 미치겠는데, 찾고찾고 또 찾아서 해결하면 알아가고 얻어가는게 많은 것 같다. 그래도 너무 많이는 말고 조금만 발생해 주면 안되겠니..? ㅠㅠ 🐾
👍