웹사이트 검색

Ubuntu 14.04에서 Docker 및 Docker Compose를 사용하여 지속적 통합 테스트 환경을 구성하는 방법


Docker의 기사

소개

지속적인 통합(CI)은 개발자가 가능한 한 자주 코드를 통합하고 에 의해 공유 저장소에 병합되기 전과 후에 모든 커밋이 테스트되는 방식을 나타냅니다. 자동화된 빌드.

CI는 개발 프로세스를 가속화하고 프로덕션에서 중요한 문제의 위험을 최소화하지만 설정하기가 쉽지 않습니다. 자동화된 빌드는 런타임 종속성 설치 및 외부 서비스 구성이 로컬 및 개발 환경과 다를 수 있는 다른 환경에서 실행됩니다.

애플리케이션 및 기본 OS와 독립적인 Docker Compose.

이 자습서에서는 Docker Compose를 사용하여 CI 워크플로의 자동화를 보여줍니다.

우리는 Dockerized "Hello world\ 유형의 Python 애플리케이션과 Bash 테스트 스크립트를 생성할 것입니다. Python 애플리케이션을 실행하려면 두 개의 컨테이너가 필요합니다. 하나는 앱 자체용이고 다른 하나는 앱의 종속성으로 필요한 스토리지용 Redis 컨테이너입니다.

그런 다음 테스트 스크립트는 자체 컨테이너에서 Docker화되고 전체 테스트 환경은 docker-compose.test.yml 파일로 이동되어 모든 테스트 실행을 새롭고 균일한 애플리케이션 환경.

이 접근 방식은 애플리케이션을 테스트할 때마다 종속성을 포함하여 애플리케이션에 대해 동일하고 새로운 테스트 환경을 구축하는 방법을 보여줍니다.

따라서 테스트 중인 애플리케이션 및 기본 인프라와 독립적으로 CI 워크플로를 자동화합니다.

요구 사항

시작하기 전에 다음이 필요합니다.

  • 우분투 14.04 서버
  • sudo 권한이 있는 루트가 아닌 사용자. 이 자습서를 따라 이를 설정할 수 있습니다.\n
  • Docker Compose에 익숙함 이 튜토리얼 중에 소프트웨어를 설치하므로 링크는 참조용입니다.\n
  • 테스트, 테스트 및 기타 (자동) 테스트! 개발 워크플로에 CI를 테스트하고 적용하는 것의 이점에 대해 이미 확신하고 있어야 합니다.\n

1단계 - 도커 설치

서버에서 아직 Docker를 사용할 수 없는 경우 가장 쉬운 방법은 공식 Docker 설치 스크립트를 다운로드하여 실행하는 것입니다. 이 스크립트는 sudo 암호를 입력하라는 메시지를 표시합니다(Docker 설치에 대한 자세한 내용은 여기 참조).

  1. wget -qO- https://get.docker.com/ | sh

Docker 작업을 더 쉽게 하려면 다음 명령을 사용하여 사용자를 docker 그룹에 추가하십시오.

  1. sudo usermod -aG docker $(whoami)

로그아웃한 다음 서버에 로그인하여 사용자의 docker 그룹을 활성화합니다.

2단계 - Docker Compose 설치

Docker Compose는 선언적 접근 방식을 사용하여 다중 컨테이너 애플리케이션을 정의하고 실행하기 위한 오픈 소스 도구입니다. Docker Compose를 설치하려면 다음 명령을 실행합니다.

  1. sudo apt-get update
  2. sudo apt-get -y install python-pip
  3. sudo pip install docker-compose

다음을 실행하여 docker-compose가 올바르게 설치되었는지 확인합니다.

  1. docker-compose --version

다음과 같은 내용이 표시되어야 합니다.

docker-compose version 1.6.2, build 4d72027

이것은 설치한 docker-compose 버전을 알려줄 것입니다.

3단계 — \Hello World\ Python 애플리케이션 생성

이 단계에서는 이 설정으로 테스트할 수 있는 애플리케이션 유형의 예로 간단한 Python 애플리케이션을 생성합니다.

다음을 실행하여 애플리케이션을 위한 새 폴더를 만듭니다.

  1. cd ~
  2. mkdir hello_world
  3. cd hello_world

nano를 사용하여 새 파일 app.py를 편집합니다.

  1. nano app.py

다음 콘텐츠를 추가합니다.

from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host="redis")

@app.route("/")
def hello():
    visits = redis.incr('counter')
    html = "<h3>Hello World!</h3>" \
           "<b>Visits:</b> {visits}" \
           "<br/>"
    return html.format(visits=visits)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=80)

app.py는 Redis 데이터 서비스에 연결되는 Flask 기반 웹 애플리케이션입니다. visits = redis.incr(counter) 줄은 방문 횟수를 늘리고 Redis에서 이 값을 유지합니다. 마지막으로 방문 횟수가 포함된 Hello World 메시지가 HTML로 반환됩니다.

우리 애플리케이션에는 FlaskRedis라는 두 가지 종속성이 있으며 처음 두 줄에서 볼 수 있습니다. 애플리케이션을 실행하기 전에 이러한 종속성을 정의해야 합니다. 새 파일 편집:

  1. nano requirements.txt

내용 추가:

Flask
Redis

4단계 — \Hello World\ 애플리케이션 도커화

Docker는 Dockerfile이라는 파일을 사용하여 지정된 애플리케이션에 대한 Docker 이미지를 빌드하는 데 필요한 단계를 나타냅니다. 새 파일 편집:

  1. nano Dockerfile

다음 내용을 추가합니다.

FROM python:2.7

WORKDIR /app

ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt

ADD app.py /app/app.py

EXPOSE 80

CMD ["python", "app.py"]

각 줄의 의미를 분석해 보겠습니다.

  • FROM python:2.7: "Hello World\ 애플리케이션 이미지가 공식 python:2.7 Docker 이미지에서 빌드되었음을 나타냅니다.
  • WORKDIR /app: Docker 이미지 내부의 작업 디렉토리를 /app
  • 로 설정합니다.\n
  • addition requirements.txt /app/requirements.txt: requirements.txt 파일을 Docker 이미지에 추가합니다.
  • RUN pip install -r requirements.txt: 애플리케이션 pip 종속성 설치
  • ADD app.py /app/app.py: 애플리케이션 소스 코드를 Docker 이미지에 추가
  • EXPOSE 80: 포트 80(표준 공용 웹 포트)에서 애플리케이션에 도달할 수 있음을 나타냅니다.
  • CMD [\python\, \app.py\]: 애플리케이션을 시작하는 명령

Dockerfile 파일에는 "Hello World\ 애플리케이션의 기본 구성 요소를 빌드하는 데 필요한 모든 정보가 있습니다.

종속성

이제 예제의 더 정교한 부분에 도달합니다. 우리 애플리케이션은 외부 서비스로 Redis가 필요합니다. 이는 전통적인 Linux 환경에서 매번 동일한 방식으로 설정하기 어려울 수 있는 종속성 유형이지만 Docker Compose를 사용하면 매번 반복 가능한 방식으로 설정할 수 있습니다.

Docker Compose 사용을 시작하기 위해 docker-compose.yml 파일을 만들어 보겠습니다.

새 파일 편집:

  1. nano docker-compose.yml

다음 내용을 추가합니다.

web:
  build: .
  dockerfile: Dockerfile
  links:
    - redis
  ports:
    - "80:80"
redis:
  image: redis

이 Docker Compose 파일은 "Hello World\ 애플리케이션을 두 개의 Docker 컨테이너에서 로컬로 실행하는 방법을 나타냅니다.

webredis라는 두 개의 컨테이너를 정의합니다.

  • webbuild 컨텍스트에 현재 폴더를 사용하고 방금 만든 Dockerfile 파일에서 Python 애플리케이션을 빌드합니다. 이것은 Python 애플리케이션용으로 만든 로컬 Docker 이미지입니다. redis 컨테이너 IP에 액세스하기 위해 redis 컨테이너에 대한 링크를 정의합니다. 또한 Ubuntu 서버의 공용 IP를 사용하여 인터넷에서 포트 80에 공개적으로 액세스할 수 있습니다.\n
  • redisredis라는 표준 공용 Docker 이미지에서 실행됩니다.\n

5단계 - \Hello World\ 애플리케이션 배포

이 단계에서는 애플리케이션을 배포하고 마지막에는 인터넷을 통해 액세스할 수 있게 됩니다. 동일한 방식으로 애플리케이션을 여러 번 배포할 수 있으므로 배포 워크플로의 목적을 위해 이를 개발, 스테이징 또는 프로덕션 환경으로 간주할 수 있습니다.

docker-compose.ymlDockerfile 파일을 사용하면 다음을 실행하여 로컬 환경 배포를 자동화할 수 있습니다.

  1. docker-compose -f ~/hello_world/docker-compose.yml build
  2. docker-compose -f ~/hello_world/docker-compose.yml up -d

첫 번째 줄은 Dockerfile 파일에서 로컬 애플리케이션 이미지를 빌드합니다. 두 번째 줄은 docker-compose.yml에 지정된 대로 데몬 모드(-d)에서 webredis 컨테이너를 실행합니다. 파일.

다음을 실행하여 애플리케이션 컨테이너가 생성되었는지 확인합니다.

  1. docker ps

그러면 helloworld_web_1helloworld_redis_1이라는 두 개의 실행 중인 컨테이너가 표시됩니다.

응용 프로그램이 작동하는지 확인합시다. 다음을 실행하여 helloworld_web_1 컨테이너의 IP를 얻을 수 있습니다.

  1. WEB_APP_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' helloworld_web_1)
  2. echo $WEB_APP_IP

웹 애플리케이션이 적절한 메시지를 반환하는지 확인합니다.

  1. curl http://${WEB_APP_IP}:80

이는 다음과 같이 반환되어야 합니다.

<h3>Hello World!</h3><b>Visits:</b> 1<br/>

방문 횟수는 이 끝점에 도달할 때마다 증가합니다. Ubuntu 서버의 공용 IP 주소를 방문하여 브라우저에서 "Hello World\ 애플리케이션에 액세스할 수도 있습니다.

자신의 애플리케이션에 맞게 사용자 정의하는 방법

자체 애플리케이션 설정의 핵심은 앱을 자체 Docker 컨테이너에 넣고 자체 컨테이너에서 각 종속 항목을 실행하는 것입니다. 그런 다음 예제에 설명된 대로 Docker Compose를 사용하여 컨테이너 간의 관계를 정의할 수 있습니다. Docker Compose는 이 Docker Compose 기사에서 자세히 다룹니다.

여러 컨테이너에서 애플리케이션을 실행하는 방법에 대한 또 다른 예는 Docker Compose로 WordPressphpMyAdmin 실행에 대한 이 문서를 참조하세요.

6단계 - 테스트 스크립트 만들기

이제 Python 애플리케이션에 대한 테스트 스크립트를 생성합니다. 이것은 애플리케이션의 HTTP 출력을 확인하는 간단한 스크립트입니다. 이 스크립트는 연속 통합 배포 프로세스의 일부로 실행할 수 있는 테스트 유형의 예입니다.

새 파일 편집:

  1. nano test.sh

다음 내용을 추가합니다.

sleep 5
if curl web | grep -q '<b>Visits:</b> '; then
  echo "Tests passed!"
  exit 0
else
  echo "Tests failed!"
  exit 1
fi

test.sh는 "Hello World\ 애플리케이션의 기본 웹 연결을 테스트합니다. cURL을 사용하여 방문 수를 검색하고 테스트 통과 여부를 보고합니다.

7단계 - 테스트 환경 만들기

애플리케이션을 테스트하려면 테스트 환경을 배포해야 합니다. 그리고 5단계에서 생성한 라이브 애플리케이션 환경과 동일한지 확인하고 싶습니다.

먼저 새 Dockerfile 파일을 만들어 테스트 스크립트를 Dockerize해야 합니다. 새 파일 편집:

  1. nano Dockerfile.test

다음 내용을 추가합니다.

FROM ubuntu:trusty

RUN apt-get update && apt-get install -yq curl && apt-get clean

WORKDIR /app

ADD test.sh /app/test.sh

CMD ["bash", "test.sh"]

Dockerfile.test는 공식 ubuntu:trusty 이미지를 확장하여 curl 종속성을 설치하고 tests.sh를 이미지 파일 시스템이며 Bash로 테스트 스크립트를 실행하는 CMD 명령을 나타냅니다.

테스트가 Docker화되면 복제 가능하고 불가지론적인 방식으로 실행할 수 있습니다.

다음 단계는 테스트 컨테이너를 "Hello World\ 애플리케이션에 연결하는 것입니다. 여기서 Docker Compose가 다시 구출됩니다. 새 파일을 편집합니다.

  1. nano docker-compose.test.yml

다음 내용을 추가합니다.

sut:
  build: .
  dockerfile: Dockerfile.test
  links:
    - web
web:
  build: .
  dockerfile: Dockerfile
  links:
    - redis
redis:
  image: redis

Docker Compose 파일의 후반부는 이전 docker-compose.yml과 동일한 방식으로 기본 web 애플리케이션과 해당 redis 종속성을 배포합니다. 파일. webredis 컨테이너를 지정하는 파일의 일부입니다. 유일한 차이점은 web 컨테이너가 더 이상 포트 80을 노출하지 않으므로 테스트 중에 공용 인터넷을 통해 애플리케이션을 사용할 수 없다는 것입니다. 따라서 라이브 배포에서와 정확히 동일한 방식으로 애플리케이션과 해당 종속성을 빌드하고 있음을 알 수 있습니다.

docker-compose.test.yml 파일은 통합 테스트 실행을 담당하는 sut 컨테이너(테스트 대상 시스템의 이름)도 정의합니다. . sut 컨테이너는 현재 디렉토리를 build 디렉토리로 지정하고 Dockerfile.test 파일을 지정합니다. web 컨테이너에 연결되어 test.sh 스크립트에서 애플리케이션 컨테이너의 IP 주소에 액세스할 수 있습니다.

자신의 애플리케이션에 맞게 사용자 정의하는 방법

docker-compose.test.yml에는 수십 개의 외부 서비스와 여러 테스트 컨테이너가 포함될 수 있습니다. Docker는 모든 컨테이너가 기본 OS를 공유하기 때문에 단일 호스트에서 이러한 모든 종속성을 실행할 수 있습니다.

애플리케이션에서 실행할 테스트가 더 있는 경우 위에 표시된 Dockerfile.test 파일과 유사한 추가 Dockerfile을 생성할 수 있습니다.

그런 다음 추가 Dockerfile을 참조하여 docker-compose.test.yml 파일의 sut 컨테이너 아래에 추가 컨테이너를 추가할 수 있습니다.

8단계 - \Hello World\ 애플리케이션 테스트

마지막으로 Docker 아이디어를 로컬 환경에서 테스트 환경으로 확장하면 다음을 실행하여 Docker를 사용하여 애플리케이션을 테스트하는 자동화된 방법이 있습니다.

  1. docker-compose -f ~/hello_world/docker-compose.test.yml -p ci build

이 명령은 docker-compose.test.yml에 필요한 로컬 이미지를 빌드합니다. -f를 사용하여 docker-compose.test.yml을 가리키고 -p를 사용하여 특정 프로젝트 이름을 나타냅니다.

이제 다음을 실행하여 새로운 테스트 환경을 가동하십시오.

  1. docker-compose -f ~/hello_world/docker-compose.test.yml -p ci up -d

다음을 실행하여 sut 컨테이너의 출력을 확인합니다.

  1. docker logs -f ci_sut_1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    42  100    42    0     0   3902      0 --:--:-- --:--:-- --:--:--  4200
Tests passed!

마지막으로 sut 컨테이너의 종료 코드를 확인하여 테스트가 통과되었는지 확인합니다.

  1. docker wait ci_sut_1
0

이 명령을 실행한 후 테스트를 통과하면 $?의 값은 0이 됩니다. 그렇지 않으면 응용 프로그램 테스트가 실패했습니다.

다른 CI 도구는 코드 리포지토리를 복제하고 이러한 몇 가지 명령을 실행하여 런타임 종속성 또는 외부 서비스 구성에 대한 걱정 없이 애플리케이션의 최신 비트로 테스트가 통과하는지 확인할 수 있습니다.

그게 다야! 프로덕션 환경과 동일하게 새로 구축된 환경에서 테스트를 성공적으로 실행했습니다.

결론

Docker 및 Docker Compose 덕분에 애플리케이션 빌드 방법(Dockerfile), 로컬 환경 배포 방법(docker-compose.yml), 테스트 이미지(Dockerfile.test)를 빌드하는 방법 및 모든 애플리케이션에 대한 테스트(통합) 실행(docker-compose.test.yml) 방법.

특히 테스트에 docker-compose.test.yml 파일을 사용하는 이점은 테스트 프로세스가 다음과 같다는 것입니다.

  • 자동화 가능: 도구가 docker-compose.test.yml을 실행하는 방식은 테스트 대상 애플리케이션과 무관합니다.
  • 경량: 수백 개의 외부 서비스를 배포할 수 있습니다.\n복잡한 (통합) 테스트 환경을 시뮬레이션하는 단일 호스트
  • 독지적: CI 공급자 종속을 방지하고 테스트를 모든 환경에서 실행할 수 있습니다.\n인프라 및 Docker를 지원하는 모든 OS에서
  • 불변: 로컬 컴퓨터에서 전달되는 테스트는 CI 도구에서 전달됩니다.

이 튜토리얼은 간단한 "Hello World\ 애플리케이션을 테스트하는 방법의 예를 보여줍니다.

이제 고유한 애플리케이션 파일을 사용하고 고유한 애플리케이션 테스트 스크립트를 Dockerize하고 고유한 docker-compose.test.yml을 생성하여 새롭고 변경 불가능한 환경에서 애플리케이션을 테스트할 차례입니다.