Skip to content

[재하] 1119(일) 개발기록

박재하 edited this page Nov 19, 2023 · 1 revision

목표

  • NCP에서 VPC/subnet 및 서버/DB 인스턴스 구성
  • DB(MySQL) 설치 및 원격 접속 가능하도록 설정
  • WEB, WAS Dockerfile 작성하고 build, push, pull
  • nginx 설정파일 작성 및 docker 네트워크 학습
  • docker-compose 설치, yml파일 작성, 실행

다음주엔 GitHub Actions 꼭 하자

체크리스트

  • Web, WAS용 서버 인스턴스
  • 서버 인스턴스에 Docker 설치
  • DB용 인스턴스 생성
  • MySQL 설치
  • WAS 서버 Dockerfile 작성
  • Docker build, push, pull로 WAS 배포
  • MySQL 원격 연결 설정
  • WEB 서버 Dockerfile 작성 후 build
  • Docker-Compose 설치, 설정파일 작성, 실행

Web, WAS용 서버 인스턴스

지난 주 목요일에 설정을 이미 마쳐서, 간단히 기록만 남기겠음

스크린샷 2023-11-19 오후 1 04 28

standard s2-g2 인스턴스를 만들었으며, 공인 IP 부여함.

스크린샷 2023-11-19 오후 5 59 21 스크린샷 2023-11-19 오후 6 00 08
  • VPC 만들고 그 내부에 (10.11.0.0/16)
    • public subnet 구성 (10.11.1.0/24)
    • private subnet 구성 (10.11.51)
    • nat subnet도 public으로 예비로 만들어뒀다
      • ncloud 내부 repository가 존재해 private의 NAT 연결이 불필요할 수 있어서, 추후 사용되지 않으면 삭제해도 좋을 것 같음.
스크린샷 2023-11-19 오후 6 09 11 스크린샷 2023-11-19 오후 6 09 00

라우팅 테이블은 위와 같이 구성했다.

스크린샷 2023-11-19 오후 6 11 00 스크린샷 2023-11-19 오후 6 11 05

ACG 규칙도 위와 같이 설정. Inbound 3000, 5173은 NGINX 리버스 프록시 배치 전 테스트를 위해 등록해놓았으며, NGINX 구동 이후 삭제 예정

스크린샷 2023-11-19 오후 1 06 23

여기 들어가면 인스턴스 생성 시 만든 키페어 파일을 이용해 os 계정 비번을 확인할 수 있음

스크린샷 2023-11-19 오후 1 06 07
ssh -i ./b1g1-server-key.pem root@175.106.98.101

이제 다운받은 키페어 파일과 확인한 공인IP, 비밀번호를 이용해 위와 같이 SSH 접근을 해보자.

스크린샷 2023-11-19 오후 6 06 12

permission에 대한 경고메시지. 물론 이대로도 잘 되지만 보안을 위해 수정해주자.

chmod 400 b1g1-server-key.pem
스크린샷 2023-11-19 오후 6 14 39 스크린샷 2023-11-19 오후 6 15 02

깔끔하게 접근 잘 됨!

서버 인스턴스에 Docker 설치

학습메모 4를 참고하여 서버 인스턴스에 Docker를 설치했다.

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

인터넷 외부 연결만 잘 설정되어 있으면, 위 내용을 순서대로 입력만 해주면 원활히 설치된다.

스크린샷 2023-11-19 오후 6 25 45

잘 설치됨!

DB용 인스턴스 생성

스크린샷 2023-11-19 오후 2 56 51

micro 서버로 DB용 Server 인스턴스를 만드려고 했더니, Classic 탭에 밖에 없는 줄 알고 다 만들어놓고 보니 VPC 설정 자체가 안되는 거였다...

VPC 탭에서 만들어야 한다...

스크린샷 2023-11-19 오후 2 57 03

그래서 쿨하게(사실 눈물을 머금음) 반납하고 다시 시작

스크린샷 2023-11-19 오후 6 32 59

왜 없나 했더니 64비트 우분투가 아니라, KVM 하이퍼바이저로 제공되는 우분투 이미지를 클릭해���만 micro 서버를 선택할 수 있다.. 참 비직관적이다..

스크린샷 2023-11-19 오후 2 57 51

그렇다고 함

스크린샷 2023-11-19 오후 2 58 53 스크린샷 2023-11-19 오후 3 01 15

설정은 최종적으로 이렇게 해 줬다. private 서브넷 이용.

Network Interface가 설정되지 않아서 넘어가지 않는 거였는데, 에러도 안뜨고 공인 IP 연결을 위해 Public Subnet을 선택하라는 걸 마치 에러처럼 표시해줘서 한참을 헤맸다. 참 비직관적...

스크린샷 2023-11-19 오후 3 01 42

최대 무료 스토리지 용량으로.

스크린샷 2023-11-19 오후 3 01 52

키 페어는 public쪽과 분리해주는 게 좋다고 함. 보안을 위해 새로 생성해뒀다.

스크린샷 2023-11-19 오후 3 02 32

ACG는 ssh용 22번, MySQL용 3306, ping 테스트용 ICMP까지 우선 열어뒀다. 추가되는 데이터베이스는 사용할 때 열어주기로 함.

스크린샷 2023-11-19 오후 3 04 05 스크린샷 2023-11-19 오후 3 05 14

Inbound, Outbound 모두 소스를 10.11.0.0/16으로 설정해줬다. VPC 내에서만 접근이 가능하도록 설정한 것!

그래서 외부에서 SSH로 접근하려면 public인 웹서버 인스턴스에 SSH 접속 후 거기서 SSH로 다시 private인 DB 인스턴스로 접근해야 한다.

스크린샷 2023-11-19 오후 3 05 45 스크린샷 2023-11-19 오후 3 05 53 스크린샷 2023-11-19 오후 3 06 04 스크린샷 2023-11-19 오후 3 06 26

적용 후 서버 생성!

스크린샷 2023-11-19 오후 3 10 54

SCP를 활용해 private 키페어를 서버 인스턴스로 넘겨준다.

스크린샷 2023-11-19 오후 3 11 52 스크린샷 2023-11-19 오후 3 12 58

비밀번호 확인 후 앞서 말한 대로 서버 인스턴스를 타고 접근! 성공이다.

MySQL 설치

sudo apt update
sudo apt install mysql-server

나는 한 인스턴스에 여러 DB를 설치하다보니 인스턴스 순정을 유지하기 위해 docker로 관리하는 게 맞다고 생각했지만, 데이터 손실 우려 등으로 로컬에다 설치하��� 게 맞다는 페어분의 의견으로 인스턴스에 직접 설치하기로 했다.

스크린샷 2023-11-19 오후 3 18 05

apt로 설치. update 찍어보니 ncloud에 repo가 따로 있어서 따로 NAT 설정을 하지 않아도 설치가 가능했다! 오우.. NAT 필요없겠는걸?

스크린샷 2023-11-19 오후 3 18 11

mysql-server 설치 완료

스크린샷 2023-11-19 오후 6 54 14

잘됨!

WAS 서버 Dockerfile 작성

BE

FROM node:20-alpine

WORKDIR /app

ADD . /app

RUN yarn workspace server build

EXPOSE 3000

ENTRYPOINT ["yarn", "workspace", "server", "start:prod"]

WAS 서버용 도커파일이다. node:20-alpine으로 작업폴더에 프로젝트를 옮기고, build 후 3000번 포트를 열고 yarn workspace server start:prod로 실행해준다.

FE

FROM node:20-alpine

WORKDIR /app

ADD . /app

EXPOSE 5173

ENTRYPOINT ["yarn", "workspace", "client", "dev"]

클라이언트용은 build를 해주는 게 맞다고 판단되지만, 현재 fe 프로젝트가 빌드 시 에러가 떠서, 문제를 해결할 때 까지 yarn workspace client dev로 했었다.

이제 문제가 해결되어 WEB 서버에 build 한 내용을 정적으로 집어넣어 주는 것으로 변경.

Docker build, push, pull로 WAS 배포

docker build -t qkrwogk/web16-b1g1-be -f ./Dockerfile-server .
스크린샷 2023-11-19 오후 3 39 21
docker push qkrwogk/web16-b1g1-be
스크린샷 2023-11-19 오후 3 42 13

인스턴스에서 docker pull

docker pull qkrwogk/web16-b1g1-be
docker platform 문제
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
95ea437f6b11ba59b710e519ba8741ad6ae3df169664bb6265d5274ba1f8a6b0

플랫폼 에러! linux/amd64로 다시 빌드

docker build -t qkrwogk/web16-b1g1-be -f ./Dockerfile-server . --platform linux/amd64

bcrypt 관련 트러블 슈팅

잘 빌드해서 실행시켰는데, 실행이 안된다!

스크린샷 2023-11-19 오후 4 23 34 스크린샷 2023-11-19 오후 4 23 21

에러 로그를 보니 bcrypt 로딩 오류

학습메모 3을 참고하니, bcrypt가 python에 의존하는데 alpine linux에 python이 기본 설치가 안돼있어서 생기는 오류랜다 ㅎ

그래서 bcryptjs모듈을 쓰거나 python을 따로 설치해주면 된다고 함.

bcryptjs 쓰기로함 ㅋ

Docker push & pull

bcryptjs로 의존성을 변경해서 다시 build해보자.

yarn workspace server remove bcrypt
yarn workspace server add bcryptjs
// from
import * as bcrypt from 'bcrypt';
// to
import * as bcrypt from 'bcryptjs';

의존성 변경

docker build -t qkrwogk/web16-b1g1-be:week2 -f ./Dockerfile-was . --platform linux/amd64
스크린샷 2023-11-19 오후 8 26 09

docker 이미지 빌드. 태그도 달아줬다.

docker push qkrwogk/web16-b1g1-be:week2
스크린샷 2023-11-19 오후 8 28 53

push!

스크린샷 2023-11-19 오후 8 31 26

서버 인스턴스에셔 pull!

latest 태그는 자동으로 바뀌지 않는다. 앞으로 같이 push해주거나 latest 태그로 넣어줘야 할듯.

docker container run -d -p 3000:3000 --name was qkrwogk/web16-b1g1-be:week2
스크린샷 2023-11-19 오후 8 36 52

실행 잘 되고요

스크린샷 2023-11-19 오후 8 41 15

근데 안되네요 TypeORM 설정을 다 채웠어야 하는데!

MySQL 원격 연결 설정

sudo apt install mysql-client
스크린샷 2023-11-19 오후 8 45 50

mysql client를 설치해서 DB 인스턴스에 연결이 되는지부터 보자.

스크린샷 2023-11-19 오후 8 53 10

응 안됨

SELECT Host,User,plugin,authentication_string FROM mysql.user;
스크린샷 2023-11-19 오후 8 52 36

그래 설정이 돼있을리가 없지.. 하자

host가 localhost인 user만 있으니까 다른 host로의 user를 추가해줘야 함.

학습메모 6 참고.

CREATE USER 'noroot'@'10.11.1.6' identified by '비밀번호';
스크린샷 2023-11-19 오후 9 05 06
GRANT ALL PRIVILEGES ON *.* to 'noroot'@'10.11.1.6';
FLUSH PRIVILEGES;
SHOW GRANTS FOR 'noroot'@'10.11.1.6';
스크린샷 2023-11-19 오후 9 09 43

이제 다시 원격 접속이 되는지 확인해보자.

스크린샷 2023-11-19 오후 9 23 08

안됨 ㅡㅡ 아 왜

service mysql restart
service mysql status
스크린샷 2023-11-19 오후 9 22 29

mysql service 재실행

그래도 안됨 후..

ERROR 2003 (HY000): Can't connect to MySQL server on 'x.x.x.x' (111)

스크린샷 2023-11-19 오후 9 31 34

이거다 분명함 (학습메모 7)

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
스크린샷 2023-11-19 오후 9 34 22 스크린샷 2023-11-19 오후 9 34 35

bind-address 0.0.0.0으로 바꾸고 (전체 허용)

스크린샷 2023-11-19 오후 9 35 00

다시 재실행

스크린샷 2023-11-19 오후 9 35 18

드디어 된다 이말씀.. 후 내가 이래서

Docker 환경설정으로 MySQL 접근정보 전달

스크린샷 2023-11-19 오후 9 56 33

.env 파일을 docker에 --env-file 옵션으로 전달하면 된다고 하니, 우선 이것부터 해보자.

docker run -d -p 3000:3000 --name was --env-file ./.env qkrwogk/web16-b1g1-be:week2
스크린샷 2023-11-19 오후 10 01 20

와 이거 될것같은데?

스크린샷 2023-11-19 오후 10 04 08 스크린샷 2023-11-19 오후 10 06 01

와 된다 대박

스크린샷 2023-11-19 오후 10 07 59 스크린샷 2023-11-19 오후 10 09 09 스크린샷 2023-11-19 오후 10 09 46

아 너무 행복해

스크린샷 2023-11-19 오후 10 10 40

DB에도 잘 들어가는거 확인 ^^

이제 FE랑 NGINX 차례다.

WEB 서버 Dockerfile 작성 후 build

빌드한 fe 프로젝트와 nginx 이미지를 활용해서, NGINX + 정적 파일 서빙(FE)을 수행하는 Docker 이미지를 build해보자.

yarn workspace client build

우선 빌드해서 dist 폴더를 만들고

FROM nginx:alpine

WORKDIR /usr/share/nginx/html

ADD ./packages/client/dist /usr/share/nginx/html

COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

해당 폴더를 /usr/share/nginx/html로 옮긴 후 실행

# nginx.conf
server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ =404;
    }

    location /api {
        proxy_pass http://[WAS 컨테이너 주소]:3000;

        # /api 경로를 /로 재작성
        rewrite ^/api(/.*)$ $1 break;
    }
}

nginx 설정파일은 위와 같이 리버스 프록시가 잘 안되는 것 같은데 연구가 필요하겠다. 연구 완료!

  1. /api 경로를 WAS에 전달 시 /로 재작성 하는 건 위와 같이 rewrite 구문으로 해결할 수 있음
  2. proxy_pass를 localhost로 하면 컨테이너 안쪽으로만 요청이 가기 때문에, 다른 컨테이너인 WAS로 요청이 들어가려면 그 IP로 접근해야 함.

2번에 대해서 부연설명을 하자면 docker 내부 네트워크가 bridge 형태로 vmware 네트워크 설정처럼 따로 구성되어 있다.

docker inspect [container id] | grep IPAddress
스크린샷 2023-11-19 오후 10 23 44

그래서 각 주소가 위와 같이 172.17 대역으로 자동 부여가 되는데, 서로서로 통신을 해주려면 이 IP로 직접 접근을 하거나(근데 예측할수가 없지)

학습메모 5를 참고하여 --link 옵션으로 실행 시 네트워크를 연결해주면 되시겠다. 좀이따가 해보자.

docker container run -d -p 7777:80 --name nginx-test qkrwogk/web16-b1g1-fe:latest

로컬에서 테스트할 때는 호스트에서 BE 서버를 실행시켜놨으므로 host.docker.internal을 BE 주소 자리에 넣어주시면 되겠다.

스크린샷 2023-11-19 오후 7 22 20 스크린샷 2023-11-19 오후 7 23 05

정적 파일 서빙 잘 된다! 근데 왜 landing만 뜨는거지 이건 좀 여쭤봐야 알듯.

스크린샷 2023-11-19 오후 7 59 37 스크린샷 2023-11-19 오후 7 58 30 스크린샷 2023-11-19 오후 7 58 38

된다된다!

docker build -t qkrwogk/web16-b1g1-fe:week2 -f ./Dockerfile-web . --platform linux/amd64
docker push qkrwogk/web16-b1g1-fe
스크린샷 2023-11-19 오후 10 25 36 스크린샷 2023-11-19 오후 10 26 13

다른 도커 컨테이너 주소에 접근하도록 설정

이제 배포할 때, docker 땡겨와서 --link 옵션으로 was 주소를 설정해주는 걸 해보자. nginx.conf에서 WAS 컨테이너 주소는 was로 채워줬다.

# 서버 인스턴스에서
docker pull qkrwogk/web16-b1g1-fe:week2
스크린샷 2023-11-19 오후 10 27 26

이제 학습메모 5를 참고해서 네트워크를 연결한 채로 컨테이너를 돌려보자.

스크린샷 2023-11-19 오후 10 29 26
docker container run -d -p 80:80 --name web --link was:was qkrwogk/web16-b1g1-fe:week2

요렇게 하면 될 것 같긴 한데,

스크린샷 2023-11-19 오후 10 29 58

가만히 보니 그리 좋은 방법은 아닌 듯 하다. 언제 deprecated 될지 모르니 도커 네트워크를 직접 정의해주면 되시겠다.

docker network create b1g1-network
docker network connect b1g1-network web
docker network connect b1g1-network was

그럼 자동으로 DNS가 세팅된다고 하니 최고다. 해보자.

docker container run -d -p 80:80 --name web qkrwogk/web16-b1g1-fe:week2

링크 옵션 빼고 이걸로 실행

스크린샷 2023-11-19 오후 10 34 47

was 주소때문에 안됨.

was 네트워크를 먼저 띄우고, network에 등록하고, 그 다음에 web을 띄워야겠다.

스크린샷 2023-11-19 오후 10 37 54

connect가 안 된 상태로 띄우니 매한가지로 에러.. 아니 그럼 순서를 어떡해야함?

스크린샷 2023-11-19 오후 10 50 51

학습메모 11에서 docker-compose로 해결할 방법을 찾음..

결국 오늘 docker-compose까지 건드리게 되는 건가 나.?

Docker-Compose 설치, 설정파일 작성, 실행

스크린샷 2023-11-19 오후 10 45 19 스크린샷 2023-11-19 오후 10 46 22

에라 모르겠다 끝까지 한 번 가보자 오늘. docker-compose 설치부터 함.

version: '3' # docker-compose 버전임. 이거 'week2'로 했다가 에러남

services:
  was:
    container_name: was
    image: qkrwogk/web16-b1g1-be:week2
    ports:
      - 3000:3000
    env_file:
      - .env
    networks:
      - b1g1-network
  web:
    container_name: web
    image: qkrwogk/web16-b1g1-fe:week2
    ports:
      - 80:80
    networks:
      - b1g1-network

networks:
  b1g1-network:
    driver: bridge

난 똑똑하니까 뚝딱 만들어버림

scp -i b1g1-server-key.pem ./docker-compose.yml root@175.106.98.101:/root/

scp로 docker-compose.yml 옮겨주고

스크린샷 2023-11-19 오후 10 56 58

이것저것 남아있던 컨테이너들 정리해주고

sudo docker-compose up

대망의 up!

스크린샷 2023-11-19 오후 10 59 11

한 번에 되면 기분이 참 좋았을텐데..

스크린샷 2023-11-19 오후 11 01 45

찾아보니 이 version이 내가 정하는 태그같은게 아니라 docker-compose 버전이였다 ㅎ 머쓱 '3' 가자.

스크린샷 2023-11-19 ᄋ��후 11 04 04 스크린샷 2023-11-19 오후 11 04 51

이것이 성공의 맛..?

스크린샷 2023-11-19 오후 11 05 51 스크린샷 2023-11-19 오후 11 06 11 스크린샷 2023-11-19 오후 11 06 32

나는 운다.. 감격받아서..

근데 이게 foreground로 계속 실행되고, 끄면 꺼지더라. 그래서 백그라운드로 실행시키는 -d 옵션을 줘서 실행함.

스크린샷 2023-11-19 오후 11 08 48
sudo docker-compose up -d
스크린샷 2023-11-19 오후 11 10 28

ssh 접속 끊어져도 되면 참 좋겠다.

스크린샷 2023-11-19 오후 11 11 22 스크린샷 2023-11-19 오후 11 11 36

된다 참 좋다.

오늘은 발 뻗고 잘 수 있겠다.

학습메모

  1. MySQL 설치
  2. 도커파일 이름 지정하여 빌드하기
  3. bcrypt 모듈 에러 나는 이유
  4. Ubuntu에 Docker 설치 방법 공식문서
  5. docker --link 옵션으로 컨테이너 네트워크 연결
  6. MySQL 유저 원격접속 허용하기
  7. ERROR 2003 (HY000): Can't connect to MySQL server on 'x.x.x.x' (111)
  8. Docker Compose에서 각 서비스 컨테이너에 쓰이는 환경변수를 다루는 방법
  9. [Docker] 도커의 환경변수 설정
  10. Docker container IP 확인
  11. 컨테이너 환경 nginx에서 컨테이너 환경의 다른 어플리케이션 접근을 위한 네트워크 구성
  12. install docker compose 공식문서
  13. 도커 컴포즈를 활용하여 완벽한 개발 환경 구성하기
  14. Docker Compose 커맨드 사용법

소개

규칙

학습 기록

[공통] 개발 기록

[재하] 개발 기록

[준섭] 개발 기록

회의록

스크럼 기록

팀 회고

개인 회고

멘토링 일지

Clone this wiki locally