-
Docker란? (React 환경에서 Docker 사용하기)TIL 2022. 11. 30. 20:44
도커는 무엇인가요?
- 리눅스의 응용프로그램들을 소프트웨어 Container 안에 배치시키는 일을 자동화하는 오픈 소스 프로젝트
- 소프트웨어 실행에 필요한 모든 것들을 포함하는 완전한 파일 시스템 안에 감싼다. 여기에는 코드, 런타임, 시스템 도구, 시스템 라이브러리 등 서버에 설치되는 무엇이든 전부 아우른다. 이는 실행 중인 환경에 관계 없이 언제나 동일하게 실행될 것을 보증한다.
- → 바로 이 부분! “환경에 관계 없이 언제나 동일하게 실행”되는 것 때문에 도커를 사용한다.
- 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하며, 컨테이너는 라이브러리, 시스템 도구, 코드 등 소프트웨어 실행에 필요한 모든 것이 포함되어 있다. 즉, 도커는 컨테이너 환경에서 독립적으로 애플리케이션을 실행할 수 있도록 컨테이너를 만들고 관리하는 것을 도와주는 도구이다. 도커를 통해 애플리케이션을 실행하면 독립적인 환경에서 일관된 결과를 보장한다. 도커의 핵심 개념은 이미지와 컨테이너다
- 도커는 리눅스에서 운영체제 수준 가상화에 대한 추상화 및 자동화 계층을 추가적으로 제공한다. 또한, 리눅스 커널, 통합 파일 시스템의 리소스 격리 기능을 사용하며, 이를 통해 독립적인 Container가 하나의 리눅스 인스턴스 안에서 실행할 수 있게 함으로써 가상 머신에 대한 유지보수 부담을 덜어준다.
- vm과의 차이점
- 간단하게 이야기 해본다면 바로 게스트OS의 유무라고 할 수 있다. VM에는 Guest OS가 깔린다. 하지만 도커의 컨테이너는 그렇지 않다. 컨테이너에는 Guest OS를 설치하지 않는다. 이는 자원의 효율성 측면에서 차이가 난다. VM는 하나씩 늘 때마다 OS를 위한 자원을 할당해주어야 하는 반면에 도커는 어플리케이션을 구동하는데 필요한 모든 패키지만 있으면 컨테이너를 구동시킬 수 있다.
- 도커의 작동 원리
- Docker는 서비스의 요청자(Docker Client) 와 제공자(Docker Server) 간의 작업이 분리되어 동작하는 Client-Server Model로 되어있으며, Docker Client는 REST API를 사용하여 Docker Server를 제어한다.
- Docker server는 Docker client로 받은 요청에 따라 4가지 docker object를 생성하고 관리한다. 여기서 Docker client는 Docker deamon과 UNIX socket 또는 REST API를 사용하여 통신하며 Docker Deamon이 container를 구축, 실행 및 배포할 수 있도록 한다.
- 자세히 보면 client는 docker에 명령을 하고 docker daemon은 이 명령어를 통해 이미지를 생성하여 콘테이너에 전달하는 것을 볼 수 있다.
프론트엔드의 도커 사용 이유
- 배포환경에서의 개발
- 도커에는 컨테이너와 이미지란 개념을 통해 어떤 환경에서도 동일한 개발 환경을 구성할 수 있다. 이를 통해 배포 시에도 동일한 환경으로 배포하기 때문에 배포 때 문제가 발생하는 것을 방지할 수 있다.
- 동일한 개발 환경을 통해 CI/CD에 유리하다
- 개발 환경의 통일화
- 동료 팀원 개발환경에서는 에러가 나는데 왜 난 안나지..? 이런 경우가 종종 발생할 것이다. 하지만 도커를 사용하면 이러한 개발 환경 때문에 발생하는 에러를 줄일 수 있게 된다.
- 빠른 개발환경 세팅
- 도커는 도커만 설치하면 된다 이후 필요한 명령어들은 Dockerfile이라는 명세서만 입력해서 실행하면 모든 환경이 세팅된다.
- 환경이 이상하다면? 그냥 컨테이너와 이미지를 지우고 Dockerfile을 수정해서 새로 생성하면 된다!
- Docker Desktop을 사용하면 프로젝트 관리가 더 편해진다
-
- 포트 번호 확인이 용이하다.
- 컨테이너를 on/off 하기 간편하다.
- 터미널도 간편하게 킬 수 있고 vscode도 간편하게 킬 수 있다.
컨테이너란?
- 컨테이너는 격리된 공간에서 프로세스가 동작하는 기술이다. 기존의 가상화 방식인 OS 가상화가 아닌 프로세스를 격리하는 방식으로 동작한다. 리눅스에서 프로세스를 격리하는 방식을 리눅스 컨테이너라고 한다. 단순히 프로세스를 격리하기 때문에 가볍고 빠르다. 또한 CPU나 메모리는 프로세스가 필요한 만큼만 추가 사용하여서 성능적으로 거의 손실이 없다.
- 시스템의 전반적인 것을 가상화하는 것이 아닌, Application을 구동할 수 있는 환경 즉, CPU와 Memory 영역 등을 가상화하고 구동하는데 필요한 운영체제나 라이브러리는 호스트 시스템과 공용으로 사용한다.
이러한 방식으로 인해 mac 환경에서 windows app의 실행은 불가능하다. ( vm에서는 가능 )
이미지란?
- 이미지는 컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않는다(Immutable).
- 이미지는 Docker hub를 이용하여 다운로드/업로드 할 수 있다.
- https://hub.docker.com/search?q=
- 도커 hub 사용 방법
- base 이미지 사용 방법
- docker hub에서 원하는 이미지를 선택한다
- 선택한 이미지에서 제공하는 버전을 확인하여 필요한 버전을 확인한다.
- 명령어나 Dockerfile에 base image를 입력하여 설정한다.
- 커스텀 이미지 업로드 방법
- docker hub에 가입한다.
- docker 로그인
- 가입 완료 후 터미널에서 docker login 명령어를 이용하여 로그인 한다.
$ docker login
- 보편적으로 docker도 1개의 계정만 로그인 가능하다. 다중으로 로그인도 가능하다고 하는데 이 부분은 조금 어려워서 보통 1개만 사용한다고 한다.
- 올릴 이미지 생성
- docker hub에 이미지를 올릴 때는 이미지 이름을 [Docker Hub 사용자 계정]/[이미지 이름]:[태그] 형태로 생성해야 한다.
- 이미지만 따로 생성하는 것은 번거로우니 컨테이너 생성과 함께 이미지를 생성한다.
docker build -t [계정명]/[이미지명]:[태그] .
- 이미지 푸쉬
- 위 명령어를 사용하여 이미지를 푸쉬한다.
- $ docker push **[Docker Hub 사용자 계정]/[이미지 이름]:[태그]**
- 푸쉬한 이미지 확인
- docker hub에 접속하면 확인 가능하다
- 커스텀 이미지는 docker hub에서 업로드/다운로드 할 수 있으며 계정이 있어야 가능하다.
- base 이미지 사용 방법
- 컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장된다. 같은 이미지에서 여러개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있다.
📌 이미지 저장 tip 이미지는 sha256 방식으로 이미지마다 해시키로 등록한다. 이 방식으로 한번 저장한 이미지는 다시 다운로드 하지 않고 저장된 해시키를 이용하여 이전에 다운로드한 이미지를 호출하여 바인딩 하는 방식을 사용한다. ⇒ node:14.06 이미지를 다운 받은 이후 해당 이미지를 베이스로 새로운 이미지 생성 시 node:14.06 이미지는 다운로드 하지 않고 이전에 저장된 이미지를 재사용한다. $ docker inspect [이미지 이름] 을 터미널에 입력하면 Layers 항목이 있는데 이미지를 어떻게 저장하는지 알 수 있다.
볼륨이란?
- container가 삭제되면 data도 같이 삭제되며 다른 프로세스테어 container에 저장된 data를 사용하기 어렵다. 또 container는 독립적인 환경 탓에 Data를 안전하게 존속시킬 수 있는 방식으로 **volume, bind mounts, tmpfs**의 3가지 방식을 제공한다. 주로 valume을 사용한다.
- volume은 docker가 생성하고 관리하는 방식을 사용한다. volume이 생성되면 docker host의 데렉토리에 저장된다. 해당 volume을 container에 mount하면 host의 디렉토리가 mount 된다. volume은 여러 container에 mount가 가능하며 사용하지 않는 volume은 정리할 수 있다.
Dockerfile 명령어 (참고 - https://www.daleseo.com/dockerfile/)
FROM FROM <이미지>:<태그> 베이스 이미지를 node를 사용하며 14.19.1 버전을 사용하겠다는 뜻 WORKDIR WORKDIR <이동할 경로> 컨테이너 상에서 작업 디텍토리로 전환을 위해서 사용 ENV ENV <키> <값> 환경 변수를 설정하기 위해서 사용, 이미지 빌드 시에도 사용됨은 물론이고, 해당 컨테이너에서 돌아가는 애플리케이션도 접근할 수 있다 COPY COPY <src>... <dest> 호스트 컴퓨터에 있는 디렉터리나 파일을 Docker 이미지의 파일 시스템으로 복사하기 위해서 사용 RUN RUN ["<커맨드>", "<파라미터1>"] 쉘(shell)에서 커맨드를 실행하는 것 처럼 이미지 빌드 과정에서 필요한 커맨드를 실행하기 위해서 사용 EXPOSE EXPOSE <포트>/<프로토콜> 트래픽(traffic)을 리스닝(listening)하는 포트와 프로토콜를 지정하기 위해서 사용 CMD CMD ["<파라미터1>","<파라미터2>"] 해당 이미지를 컨테이너로 띄울 때 디폴트로 실행할 커맨드 기본적인 도커 사용 방법
- 컨테이너 생성 방법
- 아래의 명령어를 입력한다.
- docker run -d -p 80:80 [image name]
- -d : 백그라운드에서 컨테이너 실행
- -p 80:80 : 호스트의 포트 80을 컨테이너의 포트 80에 매핑 ( 3002/3000 으로 하면 호스트의 3002번 포트를 도커의 3000 포트로 매핑되어 localhost:3002로 접속하면 도커의 3000포트가 열린다. )
위와 같이 입력한 image name이 설정된 컨테이너가 생성됨 - 이미지 빌드
- 프로젝트 경로에 Dockerfile을 생성하고 아래와 같이 입력한다
FROM node:12-alpine RUN apk add --no-cache python2 g++ make WORKDIR /app COPY . . RUN yarn install --production CMD ["node", "src/index.js"] EXPOSE 3000
- 이미지를 생성하고 실행하려면 아래의 명령어를 입력
- docker build -t [image name] .
- 앱 시작
- docker run -dp 3000:3000 [image name]
- 명령어 입력 시 localhost:3000에서 앱이 실행
위와 같이 3000포트로 새롭게 컨테이너가 실행 된 것을 확인할 수 있음 프론트엔드 도커 사용(react - web)
- Dockerfile 작성
- 프로젝트 root 경로에 Dockerfile을 생성한다.
- 해당 파일에 아래와 같이 작성한다
FROM node:14.19.1 WORKDIR /app ENV PATH /app/node_modules/.bin:$PATH COPY package.json /app/package.json RUN npm install RUN npm install react-scripts@3.0.1 -g COPY . . // hot reload를 위해 설정해줘야 한다. EXPOSE 3003 ENV PORT=3003 ENV CHOKIDAR_USEPOLLING=true CMD ["npm", "start"]
- node 버전은 원하는 버전을 선택하여 사용하면 된다.
- react-scripts 버전도 원하는 버전을 선택하면 된다.
- docker-compose.yml 작성
- 리엑트의 경우 수정된 사항이 즉시 반영되기 위해 volume을 지정해줘야 한다. 이를 간편하게 사용하기 위해 docker compose를 사용하도록 한다. ( docker compose 사용이 싫다면 docker 명령어를 통해 직접 볼륨을 설정해줄 수 있다. )
- 프로젝트 root 경로에 docker-compose.yml 파일을 생성한다.
- 해당 파일에 아래와 같이 작성한다.
version: '3.7' services: web: container_name: [프로젝트 이름] build: context: . dockerfile: Dockerfile volumes: - '.:/app' // 호스트 : 도커 기준으로 볼륨을 설정 - '/app/node_modules' ports: - '3003:3003' environment: NODE_ENV: development CHOKIDAR_USEPOLLING: 'true' // hot reload를 위해 설정하는 옵션 stdin_open: true // 편집기 오픈하는 기능을 사용할 것인지 tty: true // 터미널(TTY)을 애뮬레이션해주는 옵션
- docker-compose up -d —bulid 옵션으로 도커 컴포즈를 실행한다.
'TIL' 카테고리의 다른 글
[react] useEffect의 return이 정상적으로 실행되지 않던 문제 (0) 2022.01.26 [TIL] tdd 강의 시작! (0) 2022.01.19 [TIL] useCallback 사용 시 주의점(?) (0) 2022.01.15 [TIL] jest에서는 import, export와 같은 es6 문법이 사용되지 않는다. (0) 2022.01.13 [TIL] tdd 스터디 대 실패... (0) 2022.01.11