다음주엔 GitHub Actions 꼭 하자
지난 주 목요일에 설정을 이미 마쳐서, 간단히 기록만 남기겠음
standard s2-g2 인스턴스를 만들었으며, 공인 IP 부여함.
라우팅 테이블은 위와 같이 구성했다.
ACG 규칙도 위와 같이 설정. Inbound 3000, 5173은 NGINX 리버스 프록시 배치 전
테스트를 위해 등록해놓았으며, NGINX 구동 이후 삭제 예정
여기 들어가면 인스턴스 생성 시 만든 키페어 파일을 이용해 os 계정 비번을 확인할 수 있음
ssh -i ./b1g1-server-key.pem root@175.106.98.101
이제 다운받은 키페어 파일과 확인한 공인IP, 비밀번호를 이용해 위와 같이 SSH 접근을 해보자.
permission에 대한 경고메시지. 물론 이대로도 잘 되지만 보안을 위해 수정해주자.
chmod 400 b1g1-server-key.pem
깔끔하게 접근 잘 됨!
학습메모 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
인터넷 외부 연결만 잘 설정되어 있으면, 위 내용을 순서대로 입력만 해주면 원활히 설치된다.
잘 설치됨!
micro 서버로 DB용 Server 인스턴스를 만드려고 했더니, Classic 탭에 밖에 없는 줄 알고 다 만들어놓고 보니 VPC 설정 자체가 안되는 거였다...
VPC 탭에서 만들어야 한다...
그래서 쿨하게(사실 눈물을 머금음) 반납하고 다시 시작
왜 없나 했더니 64비트 우분투가 아니라, KVM 하이퍼바이저로 제공되는 우분투 이미지를 클릭해야만 micro 서버를 선택할 수 있다.. 참 비직관적이다..
그렇다고 함
설정은 최종적으로 이렇게 해 줬다. private 서브넷 이용.
Network Interface가 설정되지 않아서 넘어가지 않는 거였는데, 에러도 안뜨고
공인 IP 연결을 위해 Public Subnet을 선택하라는 걸 마치 에러처럼 표시해줘서
한참을 헤맸다. 참 비직관적...
최대 무료 스토리지 용량으로.
키 페어는 public쪽과 분리해주는 게 좋다고 함. 보안을 위해 새로 생성해뒀다.
ACG는 ssh용 22번, MySQL용 3306, ping 테스트용 ICMP까지 우선 열어뒀다.
추가되는 데이터베이스는 사용할 때 열어주기로 함.
Inbound, Outbound 모두 소스를 10.11.0.0/16
으로 설정해줬다.
VPC 내에서만 접근이 가능하도록 설정한 것!
그래서 외부에서 SSH로 접근하려면 public인 웹서버 인스턴스에 SSH 접속 후
거기서 SSH로 다시 private인 DB 인스턴스로 접근해야 한다.
적용 후 서버 생성!
SCP를 활용해 private 키페어를 서버 인스턴스로 넘겨준다.
비밀번호 확인 후 앞서 말한 대로 서버 인스턴스를 타고 접근! 성공이다.
sudo apt update
sudo apt install mysql-server
나는 한 인스턴스에 여러 DB를 설치하다보니 인스턴스 순정을 유지하기 위해
docker로 관리하는 게 맞다고 생각했지만, 데이터 손실 우려 등으로 로컬에다
설치하는 게 맞다는 페어분의 의견으로 인스턴스에 직접 설치하기로 했다.
apt로 설치. update 찍어보니 ncloud에 repo가 따로 있어서 따로 NAT 설정을
하지 않아도 설치가 가능했다! 오우.. NAT 필요없겠는걸?
mysql-server 설치 완료
잘됨!
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
로 실행해준다.
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 -t qkrwogk/web16-b1g1-be -f ./Dockerfile-server .
docker push qkrwogk/web16-b1g1-be
인스턴스에서 docker pull
docker pull qkrwogk/web16-b1g1-be
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 로딩 오류
학습메모 3을 참고하니, bcrypt가 python에 의존하는데
alpine linux에 python이 기본 설치가 안돼있어서 생기는 오류랜다 ㅎ
그래서 bcryptjs모듈을 쓰거나 python을 따로 설치해주면 된다고 함.
bcryptjs 쓰기로함 ㅋ
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
docker 이미지 빌드. 태그도 달아줬다.
docker push qkrwogk/web16-b1g1-be:week2
push!
서버 인스턴스에셔 pull!
latest 태그는 자동으로 바뀌지 않는다. 앞으로 같이 push해주거나 latest 태그로 넣어줘야 할듯.
docker container run -d -p 3000:3000 --name was qkrwogk/web16-b1g1-be:week2
실행 잘 되고요
근데 안되네요 TypeORM 설정을 다 채웠어야 하는데!
sudo apt install mysql-client
mysql client를 설치해서 DB 인스턴스에 연결이 되는지부터 보자.
응 안됨
SELECT Host,User,plugin,authentication_string FROM mysql.user;
그래 설정이 돼있을리가 없지.. 하자
host가 localhost인 user만 있으니까 다른 host로의 user를 추가해줘야 함.
학습메모 6 참고.
CREATE USER 'noroot'@'10.11.1.6' identified by '비밀번호';
GRANT ALL PRIVILEGES ON *.* to 'noroot'@'10.11.1.6';
FLUSH PRIVILEGES;
SHOW GRANTS FOR 'noroot'@'10.11.1.6';
이제 다시 원격 접속이 되는지 확인해보자.
안됨 ㅡㅡ 아 왜
service mysql restart
service mysql status
mysql service 재실행
그래도 안됨 후..
이거다 분명함 (학습메모 7)
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address 0.0.0.0
으로 바꾸고 (전체 허용)
다시 재실행
드디어 된다 이말씀.. 후 내가 이래서
.env 파일을 docker에 --env-file 옵션으로 전달하면 된다고 하니,
우선 이것부터 해보자.
docker run -d -p 3000:3000 --name was --env-file ./.env qkrwogk/web16-b1g1-be:week2
와 이거 될것같은데?
와 된다 대박
아 너무 행복해
DB에도 잘 들어가는거 확인 ^^
이제 FE랑 NGINX 차례다.
빌드한 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 설정파일은 위와 같이
리버스 프록시가 잘 안되는 것 같은데 연구가 필요하겠다. 연구 완료!
2번에 대해서 부연설명을 하자면 docker 내부 네트워크가 bridge 형태로 vmware 네트워크 설정처럼 따로 구성되어 있다.
docker inspect [container id] | grep IPAddress
그래서 각 주소가 위와 같이 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 주소 자리에 넣어주시면 되겠다.
정적 파일 서빙 잘 된다! 근데 왜 landing만 뜨는거지 이건 좀 여쭤봐야 알듯.
된다된다!
docker build -t qkrwogk/web16-b1g1-fe:week2 -f ./Dockerfile-web . --platform linux/amd64
docker push qkrwogk/web16-b1g1-fe
이제 배포할 때, docker 땡겨와서 --link 옵션으로 was 주소를 설정해주는 걸 해보자. nginx.conf에서 WAS 컨테이너 주소는 was
로 채워줬다.
# 서버 인스턴스에서
docker pull qkrwogk/web16-b1g1-fe:week2
이제 학습메모 5를 참고해서 네트워크를 연결한 채로 컨테이너를 돌려보자.
docker container run -d -p 80:80 --name web --link was:was qkrwogk/web16-b1g1-fe:week2
요렇게 하면 될 것 같긴 한데,
가만히 보니 그리 좋은 방법은 아닌 듯 하다. 언제 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
링크 옵션 빼고 이걸로 실행
was 주소때문에 안됨.
was 네트워크를 먼저 띄우고, network에 등록하고, 그 다음에 web을 띄워야겠다.
connect가 안 된 상태로 띄우니 매한가지로 에러.. 아니 그럼 순서를 어떡해야함?
학습메모 11에서 docker-compose로 해결할 방법을 찾음..
결국 오늘 docker-compose까지 건드리게 되는 건가 나.?
에라 모르겠다 끝까지 한 번 가보자 오늘. 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
옮겨주고
이것저것 남아있던 컨테이너들 정리해주고
sudo docker-compose up
대망의 up
!
한 번에 되면 기분이 참 좋았을텐데..
찾아보니 이 version이 내가 정하는 태그같은게 아니라 docker-compose 버전이였다 ㅎ 머쓱 '3' 가자.
이것이 성공의 맛..?
나는 운다.. 감격받아서..
근데 이게 foreground로 계속 실행되고, 끄면 꺼지더라. 그래서 백그라운드로 실행시키는 -d 옵션을 줘서 실행함.
sudo docker-compose up -d
ssh 접속 끊어져도 되면 참 좋겠다.
된다 참 좋다.
오늘은 발 뻗고 잘 수 있겠다.
진짜 이사람 괴물이다 하
존경합니다 재하님 너무 잘 읽었습니다..