Dart Programmer 되기 [45]

< Container 개발 – Dart HTTP Server over Docker, Part.1 >

이번 글에서는 Dart 언어로 만든 서버 프로그램을 Container 기술에 적용하는 방법을 다루도록 하겠습니다. Container 기술은 Docker를 사용할 예정이며, 이를 위해서 독자는 Docker를 포함한 Conainer 기술에 대한 이해가 필요합니다.

[1단계] Stagehand를 통한 Start Application의 생성

작업을 수행할 적절한 디렉토리를 만든 후, 다음의 명령으로 간단한 console 어플리케이션의 템플리트가 만들어 지도록 합니다. 저의 경우는 dartserver 라는 디렉토리에 다음 명령을 수행 하였습니다.

stagehand console-simple

[2단계] main.dart 프로그램의 변경

다음 단계는 bin 디렉토리 하단의 main.dart 프로그램을 Docker 상에서 container로 동작할 HTTP 서버 프로그램으로 변경하는 일 입니다. 이를 위해서, 작업 폴더를 Visual Code로 엽니다. 이번 글에서는 새로운 HTTP 서버를 만들기 보다는, 이미 우리가 tutorial을 진행하면서 만든 HTTP 서버 프로그램을 재사용 합니다.

앞서 27번 글에서 만든 darttutorial-27-02.dart 프로그램의 내용을 복사하여, main.dart의 내용을 덮어 쓰도록 합니다.

이 프로그램은 Docker container 환경에서 그대로 사용할 수 없습니다. 이유는 main()의 HOST 값 설정이 InternetAddress.loopbackIPv4로 되어 있는데, 이는 같은 컴퓨터 안에서의 접속만 허용함으로, Docker container의 경우는 OS레벨의 가상화를 지원하는 일종의 논리적인 별도의 컴퓨터에서 동작하므로, 이 값을 InternetAddress.anyIPv4로 변경하여, 외부에서의 접속을 허가하도록 수정합니다. 그리고 PORT 값 설정을 4040에서 8080으로 변경합니다. 이에 대한 이유는 추후 설명 하도록 하겠습니다.

[3단계] Dcokerfile 작성

Dockerfile은 container image를 생성하기 위한 화일로, Docker를 다뤄본 사람이라면 당연하게 알고 있는 화일 입니다. 작업 폴더의 루트 위치에 Dockerfile을 생성합니다.

[4단계] google/dart-runtime 도커 이미지의 이해

Dockerfile의 내용을 작성하는 단계에서, Google이 제공하는 dart-runtime 이미지를 이해할 필요가 있습니다. Docker Hub에 등록(https://hub.docker.com/r/google/dart-runtime)된 이 이미지는 Dart 언어로 만들어진 어플리케이션을 Docker 상에서 개발하기 위한 베이스 이미지 입니다. 특별히 Web 서버와 같이 8080 류의 통신 포트를 통해서 외부와 통신하는 경우를 위하여, Google이 만들고 배포한 이미지 입니다.

이번 글에서 우리는 이 이미지를 베이스 이미지로 사용할 것인데, 다음의 4가지 전제 조건을 충족하는 경우에만 사용할 수 있습니다.

  • pubspec.yaml 화일을 포함하여, 화일간 의존성을 명시할 수 있을 것
  • 실행할 프로그램이 bin/server.dart로 제공되어 entry point로 사용할 수 있을 것
  • 8080 통신 포트를 통해서 외부 요청을 받을 것
  • Container 생성시 프로그램이 의존하는 모든 패키지의 접근이 가능할 것

첫번째 조건은 Stagehand를 통한 프로젝트 생성시 자동으로 pubspec.yaml 화일이 생성되어 만족 합니다. 두번째 조건을 위해서는 bin/main.dart 프로그램의 이름을 bin/server.dart로 수정할 필요가 있습니다. 세번째 조건을 만족시키기 위하여, 2단계에서 4040인 포트 번호를 8080으로 변경했습니다. 네번째 조건은 접근 불가한 패키지가 없으니 현 상태에서 만족 합니다.

이렇게 조건을 만족한 경우, Dockerfile에는 다음의 한줄만 들어가면 됩니다.

FROM google/dart-runtime

[5단계] Container Image의 빌드

Docker container image의 build는 일반적인 절차대로 수행하면 됩니다. 다음은 이를 수행하는 명령을 예시로 적었습니다.

docker build –tag dartserver:1.0 .

Docker를 사용해 본 경험이 있는 경우 바로 이해 가능하겠지만, dartserver 라는 이름의 이미지로 버전을 1.0으로 주는 형태로 태그를 만들었습니다.

[6단계] Container Image의 실행

이제 Docker를 통해서 image를 실행할 단계 입니다. 실행은 일반적인 container의 실행과 다르지 않습니다. 다음의 명령은 이의 예시 입니다.

docker run –name mydartserver -d -p 8081:8080 dartserver:1.0

dartserver:1.0 이미지에서 실행하는 컨테이너의 이름은 mydartserver로 했으며, 통신 포트 매핑을 localhost:8081이 container의 8080에 대응 하도록 하였습니다.

[7단계] Container 동작 확인

27번 글의 실행처럼 Web 브라우저를 통한 접속도 정상적으로 동작하며, Docker를 다룬다면 보다 친숙한 다음의 명령으로 정상 동작을 확인 합니다.

curl localhost:8081

결과는 27번 글에서와 동일하게 아래와 같은 문구가 출력될 것 입니다 (시간 정보는 실행에 따라 다름).

2020-05-09 04:41:43.079079: Hello World!

마무리

Dart 언어를 통하여 서버 프로그램을 만드는 것은 아직 활성화 되지 않아 보이지만, 언어가 가지는 매력으로 많은 개발자들이 관심을 기울이니, 서버에서의 인기도 조만간 많이 늘어날 것으로 보입니다. 특히 Google에서 Docker를 위한 Dart 기반 서버의 베이스 이미지를 제공하는 덕에 조금 더 수월하게 HTTP 기반의 서버를 구동할 수 있다는 것을 이번 글에서 느낄수 있습니다. 다음 글에서는 Google에서 제공하는 또 다른 Docker용 베이스 이미지를 다루어 보겠습니다.

Creative Commons License (CC BY-NC-ND)

Dart Programmer 되기 [46]

< Container 개발 – Dart HTTP Server over Docker, Part.2 >

이번 글에서는 Dart 언어로 만든 서버 프로그램을 Container 기술에 적용하는 경우에 Part.1에서 다룬 HTTP 서버에 특화된 google/dart-runtime 베이스 이미지가 아닌, google/dart 베이스 이미지를 사용하는 방법으로 접근하도록 하겠습니다. 앞서 Part.1과는 독립적으로 다루기 위해서, 완전히 새로운 프로젝트를 열고 작업하는 것으로 가정합니다.

[1단계] Stagehand를 통한 Start Application의 생성

작업을 수행할 적절한 디렉토리를 만든 후, 다음의 명령으로 간단한 console 어플리케이션의 템플리트가 만들어 지도록 합니다. 저의 경우는 dart4docker 라는 디렉토리에 다음 명령을 수행 하였습니다.

stagehand console-simple

[2단계] main.dart 프로그램의 변경

다음 단계는 bin 디렉토리 하단의 main.dart 프로그램을 Docker 상에서 container로 동작할 HTTP 서버 프로그램으로 변경하는 일 입니다. 이를 위해서, 작업 폴더를 Visual Code로 엽니다. 이번 글에서는 새로운 HTTP 서버를 만들기 보다는, 이미 우리가 tutorial을 진행하면서 만든 HTTP 서버 프로그램을 재사용 합니다.

앞서 27번 글에서 만든 darttutorial-27-02.dart 프로그램의 내용을 복사하여, main.dart의 내용을 덮어 쓰도록 합니다.

이 프로그램은 Docker container 환경에서 그대로 사용할 수 없습니다. 이유는 main()의 HOST 값 설정이 InternetAddress.loopbackIPv4로 되어 있는데, 이는 같은 컴퓨터 안에서의 접속만 허용함으로, Docker container의 경우는 OS레벨의 가상화를 지원하는 일종의 논리적인 별도의 컴퓨터에서 동작하므로, 이 값을 InternetAddress.anyIPv4로 변경하여, 외부에서의 접속을 허가하도록 수정합니다.

[3단계] Dockerfile 생성

Dockerfile은 container image를 생성하기 위한 화일로, Docker를 다뤄본 사람이라면 당연하게 알고 있는 화일 입니다. 작업 폴더의 루트 위치에 Dockerfile을 생성합니다.

[4단계] google/dart 도커 이미지의 이해

Dockerfile의 내용을 작성하는 단계에서, Google이 제공하는 dart 이미지를 이해할 필요가 있습니다. Docker Hub에 등록(https://hub.docker.com/r/google/dart)된 이 이미지는 Dart 언어로 만들어진 어플리케이션을 Docker 상에서 개발하기 위한 베이스 이미지 입니다. 앞서 우리가 사용한 dart-runtime 이미지의 베이스 이미지 이며, Google이 만들고 배포한 이미지 입니다.

[5단계 Dockerfile 작성

개발자가 직접 Dockerfile의 내용을 상세하게 작성해야 합니다. Dokcer Hub의 이미지 설명 내용에 Dockerfile의 Sample이 있으며, 이를 토대로 우리가 만드는 프로그램의 Dockerfile을 다음과 같이 작성하였습니다.

FROM google/dart

WORKDIR /app

ADD pubspec.* /app/
RUN pub get
ADD . /app
RUN pub get --offline

CMD []
ENTRYPOINT ["/usr/bin/dart", "/app/bin/main.dart"]

[6단계] Container Image의 빌드

Docker container image의 build는 일반적인 절차대로 수행하면 됩니다. 다음은 이를 수행하는 명령을 예시로 적었습니다.

docker build –tag dartserver:1.0 .

Docker를 사용해 본 경험이 있는 경우 바로 이해 가능하겠지만, dartserver 라는 이름의 이미지로 버전을 1.0으로 주는 형태로 태그를 만들었습니다.

[7단계] Container Image의 실행

이제 Docker를 통해서 image를 실행할 단계 입니다. 실행은 일반적인 container의 실행과 다르지 않습니다. 다음의 명령은 이의 예시 입니다.

docker run –name mydartserver -d -p 4041:4040 dartserver:1.0

dartserver:1.0 이미지에서 실행하는 컨테이너의 이름은 mydartserver로 했으며, 통신 포트 매핑을 localhost:4041이 container의 4040에 대응 하도록 하였습니다.

[8단계] Container 동작 확인

27번 글의 실행처럼 Web 브라우저를 통한 접속도 정상적으로 동작하며, Docker를 다룬다면 보다 친숙한 다음의 명령으로 정상 동작을 확인 합니다.

curl localhost:4041

결과는 27번 글에서와 동일하게 아래와 같은 문구가 출력될 것 입니다 (시간 정보는 실행에 따라 다름).

2020-05-09 05:09:32.141864: Hello World!

마무리

Google이 Dart 언어로 만든 프로그램을 Docker 위에서 구동할 수 있는 두개의 베이스 이미지를 제공하는 덕분에 Dart 언어로 만든 서버 프로그램의 컨테이너 기반 구동이 매우 용이하게 되었습니다.

HTTP 프로토콜을 사용하는 서버 프로그램이라면 dart-runtime 베이스 이미지를 권장하며, 포트 번호에 제약 등이 싫은 경우는 dart 베이스 이미지를 사용하는 것이 적합해 보입니다. 이 글을 작성하는 시점에도, 이러한 사항을 반영하는지 dart 베이스 이미지를 다운로드한 건수가 dart-runtime 베이스 이미지를 다운로드한 건수 대비 2배 정도인 것을 확인 할 수 있었습니다. 하지만 dart 베이스 이미지를 사용하는 경우는, Dockerfile 등을 작성하는 등에서 직접 작성해야 하는 불편함이 일부 존재 합니다.

그리고 본 글에서는 Stagehand를 기반으로 template를 생성하고, 이를 토대로 프로젝트를 개발하였습니다. 하지만, 직접 만든 화일들 만으로 Dart 어플리케이션을 만드는 것도 언제든지 가능합니다. 이런 경우는 Dockerfile에서 yaml 화일 및 pub 기반 패키지 제어에 대해서 손수 직접 작성해 주면 되므로, 일부 번거러울 뿐 문제는 없으니 참조하기 바랍니다.

Creative Commons License (CC BY-NC-ND)