빗썸 테크 아카데미/TIL

2일차

민철킹 2021. 8. 20. 00:36

2일차 강의의 앞부분이 짤려있어서 중간부터 들어야하는 상황이다.

 

오프라인에 비해 온라인을 신경써주지 못하는 것 같아 좀 그렇긴 하지만 별 수 없지뭐..

 

앞부분은 Docker Hub에 push하는 과정을 수업한 것 같음? 아마?


Dockerfile 작성

Dockerfile은 각 줄이 명령어와 인자로 이뤄지며 명령어는 모두 대문자로 써주는 것이 관례라고 한다.

수업에서 만든 Dockerfile에서 사용된 명령어들을 살펴보자.

 

 

FROM

하나의 Docker 이미지는 base 이미지부터 시작해서 기존 이미지위에 새로운 이미지를 중첩해서 여러 단계의 이미지 layer를 쌓아가며 만들어진다.

 

base 이미지를 지정해주는 것이 바로 FROM 명령어이다.

# 우분투 최신 버전 사용
FROM ubuntu:latest

# node.js 12버전 사용
FROM node:12

# java 8 버전 사용(alpine:리눅스 기반)
FROM openjdk:8-jdk-alpine

 

LABEL

LABEL 명령어는 이미지의 버전 정보, 작성자, 코멘트와 같은 상세정보를 작성하는 명령어이다.

LABEL title="webserver"
LABEL version="2.0"
LABEL maintainer="minchul"

 

VOLUME

VOLUME 명령어는 컨테이너 안에 데이터를 보존하기 위해 사용하는 명령어이다. 컨테이너가 삭제되면 데이터가 모두 날라가기 때문에 이 명령어를 사용하게된다.

VOLUME /tmp

컨테이너 /tmp 폴더의 파일이 호스트OS의 /var/lib/docker/volumes/~~~(해쉬값)/tmp에 저장된다.

 

ARG

ARG 명령문은 이름에서 느껴지듯이 인자를 정의해주는 명령어이다.

ARG JAR_FILE=./build/libs/*.jar
ADD ${JAR_FILE} app.jar

아래의 ${JAR_FILE}에 ARG 명령어의 JAR_FILE이 들어간다.

 

ADD

ADD 명령어는 파워풀한 COPY 명령어이다. 즉 위의 예시 코드에서 JAR_FILE로 설정한 경로에 app.jar를 복사하는 것이다.

 

EXPOSE

EXPOSE 명령어는 네트워크 상에서 컨테이너로 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정하기 위해 사용.

프로토콜의 기본값은 TCP이다.

EXPOSE 8080

호스트 컴퓨터에서 해당 포트로 바로 접근할 수 있는 것이 아님. 해당 컨테이너의 내부에서만 유효하다.호스트 컴퓨터로부터 해당 포트로의 접근을 허용하기 위해서는 "docker run -p" 옵션을 사용해야한다.

 

ENTRYPOINT

ENTRYPOINT 명령어는 이미지를 컨테이너로 띄울 때 항상 실행되어야하는 커맨드를 지정하는 명령어이다.

ENTRYPOINT ["python", "manage.py", "runserver"]

 

docker-compose.yml 작성

 

docker-compse는 각 서비스를 Compose 파일로 마이그레이션한다.

ports는 호스트의 port와 컨테이너의 port를 연결한다. 

depends_on은 서비스간의 종속성을 나타내는 것으로 위의 경우에는 mongo를 실행한 후에 app이 실행된다.

volumes는 Dockerfile에서와 동일하다.

 


작성한 두 파일을 사용해보자.

먼저 build를 새로 진행한다. "./gradlew clean build"를 입력해 이전 것을 지우고 새로 빌드를 하였다.

 

그후, "docker compose build"를 입력하여 docker compose를 빌드한다.

https://docs.docker.com/compose/reference/build/

 

docker-compose build

 

docs.docker.com

 

다음으로 "docker compose up"을 통해 컨테이너를 빌드, 생성, 시작, 연결한다.(빌드를 안하고 바로 up을 해도됨)

https://docs.docker.com/compose/reference/up/

 

docker-compose up

 

docs.docker.com

localhost:8080으로 접속해도 설정한대로 현재 시간이 출력된다.

 

즉, Docker를 통해 각 컨테이너(Spring과 MongoDB)가 동시에 실행되었다.

실행을 멈추고 "docker ps -a"로 모든 컨테이너 목록을 확인해보면 두개의 컨테이너가 생성된 것을 확인할 수 있다.

 

대충 어떤 느낌인지 알겠다. 도커써서 각 모듈로 쪼개어 하나의 시스템으로 돌릴 수 있는데 그럼 프론트 + 백 + DB 뿐만 아니라 백도 여러개의 모듈(컨테이너)로 쪼갤 수 있나? 

 


현재 4.4.3 버전의 MongoDB 이미지가 만들어져있다.

이걸 Docker Hub에 Repository를 생성하고 push해보자.

 

Docker Hub에 push가 완료된 것을 확인할 수 있다.

 


TDD

 

TDD의 중요성은 너무 익히 들어 알고 있다. TDD란 Test Driven Development, 테스트 주도 개발을 뜻한다.

 

반복 테스트를 이용한 소프트웨어 방법론으로 작은 규모의 단위 테스트를 작성하고 통과하는 코드를 추가하는 단계를 반복하여 구현한다. 단위 테스트의 단위는 일반적으로 class를 뜻한다. 한 클래스 단위의 테스트를 의미한다.

 

 


함수형 프로그래밍(lambda)

 

자바 8부터의 Modern Programming에 도입된 것에는 람다, 스트림이 존재한다.

 

자바 8의 가장 큰 특징은 람다를 이용한 함수형 프로그래밍을 지원한다는 것이다.

 

함수형 인터페이스란 오직 하나의 추상 메서드만을 가진 인터페이스를 의미한다. 이를 애노테이션을 붙혀 명시적으로 표시하고 두개 이상의 추상 메서드를 가진다면 컴파일 에러를 발생시킬 수 있다.

 

Imperative vs Declarative

명령형(Imperative)은 무언가를 작업하기 위한 방법을 정의하는 것을 뜻한다.

  • Java, C 등등

 

선언형(Declarative)는 무언가를 작업하기 위해 어떻게 진행할 것인지를 나열하는 것을 뜻한다.

  • Haskell, HTML, SQL 등등

 

두 코드는 동일한 결과를 출력하고 동일한 기능을 하는 코드이다. 하지만 하나는 우리가 흔히 사용하는 방법이고 하나는 함수형 프로그래밍을 사용한 방법이다.

 

함수형 프로그래밍에서 위와 같은 형태의 구조를 chain이라고한다.(계속 이어진다는 뜻)

람다를 사용한 테스트

또 다른 예제들이다.

 

 

 


Function은 1개의 파라미터를 받아 1개의 결과를 반환하는 functional interface이다.

Supplier는 값을 생성하기 위해 사용되는 것으로 매개값은 없고 리턴값은 있다. 대표적인 예시로 Stream의 generate메서드가 있다.

Consumer는 단일 파라미터를 받고 리턴값이 없는 단순히 소비만을 한다.

 

Consumer 예제

Consumer 인터페이스에 존재하는 accept 메서드를 사용하여 단순히 그 값을 출력하도록 하였다.(리턴x)

결과

 

Supplier 예제

 

Function 예제

결과

리스트의 담긴 문자열의 길이를 출력

반응형

'빗썸 테크 아카데미 > TIL' 카테고리의 다른 글

6일차  (0) 2021.08.27
5일차  (0) 2021.08.25
4일차  (0) 2021.08.24
3일차  (0) 2021.08.20
1일차  (2) 2021.08.19