Docker, TravisCi

Docker

  • 도커 이미지 안에는 도커를 실행시키는 파일 스냅샷과 명령어가 닮겨 있다. docker run 명령어를 실행하면 파일 스넵샷을 컨테이너로 옮기고 실행 명령어를 통해 실행한다. docker run <이미지> <명령어> 를 통해 뒤에 명령어를 컨테이너가 생성된후 실행 시킬 수 있다.
  • Docker에 Container는 C-grop과 네임스페이스를 통해 격리된 환경을 제공하는데, 리눅스에서 가능한 작업이 다른 호스트 os에서도 가능한 이유는 Docker 가 내부적으로 리눅스 vm을 사용하고 리눅스 커널을 공유하는 격리된 컨텐이너를 만들기 때문이다.
  • docker Stop 은 SIGTERUM 을 주어서 SIGKILL을 진행하기 전에 완료되지 않은 작업이 있다면 완료한다음 컨테이너를 종료시키고, docker kill 은 SIGTERUM 을 주지 않고 바로 컨테이너를 중지시킨다.
  • 실행중인 컨테이너에서 명령을 실행시키려면 exec 으로 실행시켜야 한다. docker exec -it <containerID> 명령어 이런식으로 사용하는 -it 는 -i (interactive), -t (terminal) 을 합성한 것으로 명령을 실행하고 바로 나와버리는 것이 아니라 실행한 후에 터미널에서 추가적인 명령을 입력할 수 있도록 해준다.
  • 쉘의 접속하고 싶다면 docker exect -it <containerId> sh 로 쉘의 접속할 수 있다. sh 는 bash, zsh 등 사용하는 컨테이너에 따라 다양하게 사용 가능하다.

DockerFile

  1. baseimage 설정 FROM
  2. 워킹 디렉터리를 설정해줌 → 파일 시스템덮어씌워지는것 방지, 관리하기 용이하게 WORKDIR
  3. 추가적인 스넵샷 및 shellscript 추가 RUN
  4. 리소스 복사 COPY
  5. 이미지 시작후 명령어 CMD

이미지가 생성되는 순서

dockerfile → 이미지 생성 → 임시 컨테이너 생성 → 임시컨테이너로 이미지 생성 → 이미지 생성 완료

dockerfile → dockerClient → dockerServer → 이미지 생성

네트워크 연결하기

docker run -p <로컬 포트>:<컨테이너 포트> <이미지이름>

백그라운드 실행

docker run -d -p 5000:8000 rnwkdbs12/node

-d : detach 의 약자로 바로 빠져나온다는 의미 → 즉 백그라운드에서 실행시키고 터미널로 바로 나옴.

종속성 다시 다운로드 안받게 하려면..

npm install 전의 package.json을 따로 copy 하고 npm install 후에 다른 소스 파일을 copy 하도록 하면 된다.

다시 빌드하지 않으려면

volumn 을 설정하여 컨테이너가 로컬을 단순히 복사하는 것이 아닌 참조할 수 있도록 해야 한다.

docker run -dp 5000:8000 -v /usr/src/app/node_modules -v /$(pwd):/usr/src/app rnwkdbs12/node 처음 설정한 -v 옵션은 참조하지 않을 경로를 의미하고 두번째로 표시한 -v 테그는 참조할 디렉터리를 현제 로컬의 디렉터리로 매핑한 것을 의마한다.

Docker Compose

여러개의 컨테이너를 묶어서 실행할 수 있다.

docker-compose.yml 사용

1
2
3
4
5
6
7
8
version: "3" 
services:
redis-server: // 네트워크에 이름이 된다.
image: "redis"
node-app: // 다른 컨테이너가 된다.
build: . // 현제 폴더에서 Dcokerfile을 찾아서 build
ports:
- "8080:8080"

docker-compose up

docker-compose up --build build 하면서 up

docker-compose up -d background 실행

docker-compose down 실행 종료

간단한 앱 배포

개발 환경

개발 환경을 위한 Dockerfile 은 명시적으로 Dockerfile.dev 를 사용한다.

docker build -f Dockerfile.dev ./ 를 통해서 명시적으로 이름을 지정해 주어야 한다.

Dockercompose 로 간단하가게 구성하기

1
2
3
4
5
6
7
8
9
10
11
12
version: '3'
services:
react:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- /usr/src/app/node_modules
- ./:/usr/src/app
stdin_open: true

test

test 를 위해서는 추가적인 명령어를 붙히면 된다.

docker run -it rnwkdbs12/reactdev yarn run test

테스트 파일도 실시간으로 변경 사항을 적용하기 위해서는 volumn을 연결해야 한다.

dockercompose 파일을 추가하여 tests 컨테이너를 추가하면 실행과 동시에 테스트까지 진행할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '3'
services:
react:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- /usr/src/app/node_modules
- ./:/usr/src/app
stdin_open: true
tests:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- /usr/src/app/node_modules
- ./:/usr/src/app
command: ["yarn", "run", "test"]

운영을 위한 배포

1
2
3
4
5
6
7
8
9
FROM node:alpine as builder
WORKDIR '/usr/src/app'
COPY package.json .
RUN yarn install
COPY ./ ./
RUN yarn run build

FROM nginx
COPY --from=builder /usr/src/app/build /usr/share/nginx/html

build 후에 nginx 이미지를 설정하여 정적 파일을 옮겨 준다. nginx 에 기본 설정이 /usr/share/nginx/html 로 되어 있기 때문에 build 파일을 옮겨 준 것이다.

이미지를 실행할때 컨테이너 포트로 80번 포트를 사용하는데 nginx 기본 설정이 80번 포트를 사용하기 때문이다. 이 또한 설정에서 변경 가능하다.

TravisCI 사용

travisCI 는 .tavis.yml 파일을 이용해서 설정 파일을 작성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo: required

language: generic

services:
- docker

before_install:
- echo "start creating an image with dockerfile"
- docker build -t rnwkdbs12/reactdev -f Dockerfile.dev .

script:
- docker run -e CI=true rnwkdbs12/reactdev yarn run test -- --coverage

after_success:
- echo "Test success"
  • sudo : 관리자 권한이 필요함
  • language : 언어 설정
  • services : docker 와 함께 사용함 명시
  • before_install : script 실행전 필요한 명령 실행 → docker를 사용함으로 이미지 build v필요
  • script : 이미지 실행, test 실행
  • after_sucess: 스크립트 실행 후에 실행될 명령.

AWS 를 이용한 배포

EC2와 Elastic Beanstalk를 이용하여 서비스를 배포한다. travis 를 통해서 테스트에 성공한 소스를 AWS Elastic Beanstalk에 자동으로 배포하는 부분을 travis 파일에 넣어준다.

travis CI 에서 가지고 있는 파일을 압축해서 S3에 보낸다. S3 는 Elastic Beanstalk를 생성할때 자동으로 생성된다.

IAM 사용자 생성

처음 가입하고 사용하면 Root 계정으로 가입 되어서 모든 리소스에 대한 액세스 권한이 있다. Root 사용자를 사용하는 것은 좋지 않아서 보안을 위해서 IAM 유저를 생성 권한을 부여하는 방식을 사용한다.