[도커] 도커 컨테이너 배포하기 Simple practice (NodeJS App)

리모트 시스템 설정, 리모트 호스팅 서버, SSH로 연결하기, 리모트 호스트에 Docker를 설치, 이미지 푸쉬와 풀링하기, 그리고 컨테이너를 실행하여 브라우저로 테스트하기를 할 것이다.


로컬에서 테스트하기

애플리케이션 도커화 하기

이러한 파일구조를 가지고 있는 디렉토리이다.


app.js

const path = require('path');

const express = require('express');

const app = express();

app.use(express.static('public'));

app.get('/', (req, res) => {
  const filePath = path.join(__dirname, 'views', 'welcome.html');
  res.sendFile(filePath);
});

app.listen(80);

80번 포트에서 수신 대기하는것을 볼 수 있다.


Dockerfile

FROM node:14-alpine

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

EXPOSE 80

CMD ["node", "app.js"]

도커 파일도 그냥 기본 스펙이다. 이 구성을 기반으로 빌드할것이다.

알파인 노드이미지를 쓴 이유는 이미지를 더 작게 만들고, 전체 빌드 속도와 배포 절차 속도를 높이기 위함이다.

docker build . -t simple-docker-deploy

빌드가 잘 되는것을 볼 수 있다.


docker run -d --name simple-node-app -p 80:80 simple-docker-deploy

이름은 simple-node-app으로 지정하고 80번 포트를 로컬 호스팅 머신에 노출한다.

그리고 localhost:80으로 접속해보면 서버가 잘 돌아가는것을 볼 수 있다.

docker run -d --name simple-node-app -p 80:80 -v /Users/june/Downloads/deployment-01-starting-setup/views:/app/views simple-docker-deploy

이렇게 바인드 마운트를 해주면

호스트머신에서 편집을해도 편집된 내용이 컨테이너에 잘 반영되는것을 볼 수있다.


개발용으로 사용할때에는 즉각 반영되어서 바인드 마운트가 편하지만 프로덕션용으로 빌드할 때에는 바인드 마운트대신 복사본을 사용해야한다.

이미지와 그 이미지를 기반으로 하는 컨테이너는 단 하나의 소스여야하는데, 이미지를 가져와서 이를 기반으로 컨테이너를 실행하면 한 어플리케이션에 필요한 모든것을 얻을 수 있어야한다는 것을 의미한다.

바인드 마운트를 할때 컨테이너를 run 할때 옵션으로 -v를 줘서 실행했으니, Dockerfile에 아무것도 코딩할 필요가 없다. 그래서 프로덕션 및 개발에 동일한 Dockerfile을 사용할 수 있다. (도커 컴포즈에 바인드 마운트 한 경우는 예외)


호스팅 프로바이더

리모트 서버, 리모트 머신을 사용하기 위한 호스팅 프로바이더.

여러가지가 있지만, AWS, Azure, GCP 이 세가지가 가장 크다.

나는 이번에 AWS를 호스팅 프로바이더로 사용해서 진행해보려고 한다.


EC2 인스턴스

AWS에서 호스팅하는 리모트 서버이다.

도커를 설치해서 이 서버에서 사용할 것이다.  
1. 인스턴스를 생성하고 시작해야한다. 그리고 이 인스턴스에 액세스를 통제하기 위해 VPC와 보안그룹을 구성 해줘야한다.

2. 필요한 모든 포트를 www에 노출하도록 보안 그룹을 구성해야한다. EC2인스턴스로 들어오는 트래픽을 가질 수 있도록.

3. ssh를 통해 인스턴스에 연결해야한다. 리모트 머신에 연결하기 위한 터미널 기반 접근방식이다. 그리고 EC2에서 명령을 실행할 수 있게 된다. 도커를 설치하고 컨테이너를 가져와 실행할거다.


AWS 서비스 콘솔에 들어가서 EC2를 누르고 Instance에 들어간다. 그리고 현재 실행중인 인스턴스가 없을것이니, 인스턴스 생성을 누른다.

인스턴스의 이름은 적당하게 지어주고, 나는 ubuntu 환경에서 빌드할것이다.

 

인스턴스 타입은 T.2 micro가 프리티어니까 돈 쓰기 싫으니 이걸로 선택하자

키페어는 없다면 생성하고, 있다면 있는것으로 선택하자

VPC는 디폴트로 설정해줘도 좋다.

밑에 퍼블릭 아이피 자동 할당은 Enable해주도록한다.

 

세큐리티 그룹은 새로 만들어주기로 하자. 일단은 적당한 이름으로 지어주고, 기본 옵션으로 설정한 뒤 인스턴스를 생성한다.

https://heea.tistory.com/entry/EC2-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-ssh%EC%97%B0%EA%B2%B0%EB%A1%9C-%EB%B9%84%EC%A3%BC%EC%96%BC-%EC%8A%A4%ED%8A%9C%EB%94%94%EC%98%A4%EB%A1%9C-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%97%85%ED%95%98%EA%B8%B0?category=577404 

 

 

EC2 인스턴스 ssh연결로 비주얼 스튜디오로 코드 작업하기

VS code로 연결 퍼블릭 IPv4 DNS 주소를 복사한다. VS code내에서 remote -SSH 확장자를 설치한다. 설치완료하면 왼쪽 밑에 파란 바람개비가 나온다 바람개비를 누르고 connect current window to Host를 누르면..

heea.tistory.com

 

위 링크의 글을 참고하여 편하게 ssh로 연결하여 vs code로 EC2에서 작업해보자.

이렇게 왼쪽 밑 바람개비가 SSH:aws-ec2 로 표시가 되고, 터미널 창이 ubuntu@<ip> 이렇게 뜨면 리모트머신으로 접속이 되었다는것이다.

이제 리보트 머신에서 로컬에서 빌드한 이미지를 가져오고, 컨테이너를 실행하고 보안그룹을 구성하면 된다.


EC2 인스턴스에 도커 설치하기

https://shanepark.tistory.com/237

 

Ubuntu 20.04 LTS ) Docker 설치하기

Intro Docker는 제가 회사에서 사용하는 노트북의 OS를 Windows 에서 Ubuntu 로 변경하게 된 트리거 였습니다. Docker를 사용하면 정말 편하게 격리된 컨테이너들을 구성해 가상화의 장점을 정말 잘 살릴

shanepark.tistory.com

위 링크를 참고하여 순서대로 명령어를 입력하여 도커가 설치되었는지 확인한다.


로컬 이미지를 도커허브로 푸쉬하기

로컬 이미지를 리모트 머신으로 가져와야 한다.  이를 위한 두가지 방법이 있다.

하나는 소스 코드를 배포하는 것이다.

Dockerfile 파일을 포함한 소스코드 디렉토리를 리모트 머신에 복사하는 방식이다. 그리고 거기서 빌드할 수 있다.

다른 한가지 방법은 로컬머신에서 미리 이미지를 빌드하는 것이다. 그리고 구축된 이미지를 리모트 머신에 배포하기만 하면 된다. 그리고 리모트 머신에서 그 이미지를 받아서 docker run을 실행하기만 하면 된다 .

나는 두번째 방법을 사용하려고 한다.


도커허브에 로그인 한 뒤, Create repository를 눌러서 새로운 저장소를 만들어준다.

d이름은 원하는 것으로 지정해주면 되고, 퍼블릭으로 만들어준다.

 

create로 생성을 한뒤 위 커멘드로 저 저장소에 푸쉬를할 수 있게된다


로컬 호스트 머신에 .dockerignore 파일을 추가하여서 node_modules,Dockerfile, 각종 Pem 키들이 이미지에 들어가는것을 막는다.

 docker build . -t simple-node

 

그리고 simple-node 라는 이름으로 이미지를 빌드한다. 이렇게 하면 로컬에 이미지가 생성이 된 것이다.

 

docker tag simple-node crowssnest/simple-node

그리고 docker tag로 이미지의 이름을 바꿀 수 있다.

docker push crowssnest/simple-node:tagname

그리고 도커 허브에 있는 이 명령어로 푸쉬할 수 있다.

터미널에서 푸쉬가 완료가 된것을 확인하고, dockerhub 콘솔에서 latest 태그로 이미지가 하나 올라온것을 볼 수 있다.


docker run -d --rm -p 80:80 crowssnest/simple-node

인스턴스 안에서 도커 허브에 올린 이미지를 다운받고 실행하기 위해 명령을 한다. -d로 detach모드로 실행하고, 종료되면 컨테이너가 삭제되게 --rm 옵션을 준다. 그리고 호스트머신 포트80과 컨테이너 포트80을 매핑한다.

그렇게 컨테이너 실행을 하면 권한 오류가 나온다....? ㅜ

sudo docker run -d --rm -p 80:80 crowssnest/simple-node

앞에 sudo 를 붙이면 해결이 된다...!

crowssnest/simple-node가 local에 없어서 다운로드를 하고 실행이될 줄 알았는데... ㅜ

WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested

이런 메세지가 표시가되고 docker ps로 컨테이너 상태를 확인해봐도 존재하지 않는다.

https://sas-study.tistory.com/425

 

[Docker] 이미지 플랫폼 관련 에러(The requested image's platform (linux/arm64/v8) does not match the detected host plat

도커 허브를 통해 ec2 인스턴스에 배포하고자 하였음. Dockerfile 만들고. ec2에 도커 설치하고 systemctl docker start 로 도커를 딱 켜고! 도커 허브에서 이미지 땡겨받아서 run만 하면 되는데....! 다음과

sas-study.tistory.com

이 블로그를 참고하여서 문제를 해결했다.

--platform linux/amd64

linux/arm64/v8 이므로 이를 linux/amd64 플랫폼 형태의 이미지로 빌드해야한다.

docker build --platform amd64 -t crowssnest/simple-node .
docker push crowssnest/simple-node

이 명령으로 빌드하고 도커 허브로 푸쉬를 한다.

그리고  인스턴스에서 docker run을 하면, 새롭게 도커 허브에 푸쉬 된 이미지가 정상적으로 다운로드 되어서 docker ps로 실행되고 있는 컨테이너가 있는것을 확인할 수 있다.


리모트 머신에서 컨테이너를 테스트하는법

퍼블릭 Ipv4 주소를 복사하여 주소창에 붙여넣으면

사이트에 연결할 수 없음이 표시된다.

보안에 22번 포트만 오픈이 되어있어서 그렇다.

인바운드 규칙 편집에서 80번 포트를 오픈해준다.

그리고 IPv4 주소를 주소창에 붙여넣으면 노드앱이 잘 작동하는것을 확인할 수 있다.


이 접근방식의 단점

EC2 인스턴스 같은 클라우드 호스팅 프로바이더의 도움으로 자체 리모트 서버를 이용하려고 한다면, 이 리모트 머신이 나의 완전한 소유여야한다. 가장 중요한 보안에 대한 책임을 가진다는 것이다. 보안 그룹인 네트워크를 관리해야 하니, 방화벽도 관리해야한다. 

그리고 웹 개발자로서 기본적으로 알아야할 것들을 배워야한다. SSH를 통해 머신에 연결하기, 그리고 그렇게 들어간 곳에서 도커를 설치하기 등등 말이다.

그리고 우리는 조금 더 관리된 접근 방식을 원한다. 예를 들어 호스트 머신에서 소스코드를 작성하고 배포까지 자동으로 되는 것.

AWS의 관리형 서비스 ECS 를 통해 해결해보려고 한다.

JUNE .

20'S LIFE IN SYDNEY and BUSAN

    이미지 맵

    DevOps Study/Docker 다른 글

    이전 글

    다음 글