[코드숨] 8강 더 나아가기

June·2021년 10월 5일
0

코드숨

목록 보기
8/8

학습 목표

배포 준비

API 문서 만들기

우리가 만든 API를 다른 사람들이 쓸 수 있도록 문서를 제공해야 합니다. REST Docs를 사용해서 API 문서를 만들어 주세요.

Docker image 만들기

우리가 만든 애플리케이션을 실제로 쓸 수 있도록 하려면 배포를 해야합니다. 배포를 하기 위해 Dockerfile 을 만들어 Docker image를 만들고 Docker Hub에 업로드 해주세요.

문서화

Javadoc

Javadoc이란 주석으로 작성된 코드 문서를 HTML 문서로 만들어주는 도구입니다.

문서 만들기

gradlew javadoc

생성된 문서는 build파일에 포함되어 있습니다. app/build/docs/javadoc/index.html을 브라우저에서 열면 문서를 확인할 수 있습니다.

혹시 javadoc을 한글로 작성하면 인코딩 문제가 발생할 수 있다.
해결 블로그

Tools -> Generate Javadoc 가서

Locale에 **ko_KR**
other에 **-encoding UTF-8 -charset UTF-8 -docencoding UTF-8**

주면 된다.

Asciidoctor

AsciiDoc은 Markdown처럼 마크업 문서입니다. Asciidoctor는 이 문서를 처리하여 웹에서 볼 수 있는 HTML5파일로 만들어줍니다.

REST Docs

REST Docs는 우리가 만든 API 문서를 쉽게 만들수 있도록 도와주는 도구입니다. 무엇인지

Javadoc 작성하기

ProductService

@Service
@Transactional
public class ProductService {
    private final ProductRepository productRepository;
    private final Mapper mapper;

    public ProductService(ProductRepository productRepository, Mapper dozerMapper) {
        this.productRepository = productRepository;
        this.mapper = dozerMapper;
    }

    /**
     * Returns all products in this application.
     * @return all products.
     */
    public List<Product> getProducts() {
        return productRepository.findAll();
    }

    /**
     * Returns the product with given ID.
     * @param id is the identifier of the product.
     * @return the product with given ID.
     * @throws ProductNotFoundException in case any product doesn't exist with the given ID.
     */
    public Product getProduct(Long id) {
        return findProduct(id);
    }

    ...
}

IntelliJ 터미널에서 gradlew javadoc이라 치고 build에 javadoc 폴더가 생긴다. 거기 index.html을 보면된다.

/**
 * Service for products
 *
 * @Author Ashal aka JOKER (ahastudio@gmail.com)
 */
@Service
@Transactional
public class ProductService {
    ...

클래스에도 이런식으로 적어줄 수 있다.

REST DOC

plugins {
	...
    
    // Asciidoctor
    id 'org.asciidoctor.convert' version '2.4.0'
}

dependencies {
    ...

    // Spring REST Docs
    asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor'
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
}

ProductControllerTest

@AutoConfigureRestDocs
@WebMvcTest(ProductController.class)
class ProductControllerTest {
    ...

    @Test
    void list() throws Exception {
        mockMvc.perform(get("/products")
                        .accept(MediaType.APPLICATION_JSON_VALUE)
        )
                ...
                .andDo(document("get-products"));
    }

@AutoConfigureRestDocs 애노테이션을 추가했다.

테스트 코드 끝에 .andDo(document("get-products"));를 적었다.

build -> docs -> generated snippets -> get-products 폴더가 생긴다.

src 폴더 아래 docs 폴더를 만들고, 그 아래에 asciidoc 폴더를 만들고 아래에 index.adoc을 만들고 작성해도 된다.
inclide::{snippets}/get-products/http-request.doc[]이런시긍로 하면 asciidoc을 불러올 수 있다.

REST Docs HTML로 만들기

build.gradle

asciidoctor {
    dependsOn(test)
}

asciidoctor가 실행되기 전에 항상 test가 먼저 실행되게 하는 것이다. test가 먼저 실행되어야하는 이유는 test의 결과를 바탕으로 작성하기 때문이다.

빌드

빌드

Gradle에 MariaDB 드라이버 설치하기

implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.2'

Docker

Container란 다른 환경에서도 항상 동일하게 실행되도록 애플리케이션 코드와 애플리케이션을 실행하는데 필요한 주변 환경들을 같이 패키징 하는 기술입니다. 애플리케이션을 실행하는데 필요한 모든 것이 같이 포함되어 있으므로 다른 실행 컨텍스트와 완전히 독립적으로 실행될 수 있습니다.

Docker로 MairaDB 실행시키기

docker run -d --name mariadb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root1234 -e MYSQL_DATABASE=test mariadb --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

Docker image 만들기

Dockerfile 만들기

Dockerfile은 이미지를 만들기 위해서 필요한 명령어들을 작성할 수 있는 파일입니다. Docker image를 만들기 위해 먼저 Dockerfile이라는 이름으로 확장자 없이 파일을 만든 후 다음을 입력합니다.

# 어떤 이미지로부터 만들지 선택합니다. 이 이미지는 우리 프로젝트를 빌드를 하기 위해서만 사용되는 이미지입니다. 빌드 하기 위해서 모든 파일을 컨테이너로 복사한 후 빌드를 실행합니다. 빌드를 하는 용도로만 사용되고 더 이상 사용되지 않습니다.
FROM openjdk:15.0.1 AS builder
# 현재 폴더에서 컨테이너의 현재 폴더로 복사합니다.
COPY . .
# 명령어를 실행합니다.
RUN ["./gradlew", "assemble"]

# 이 이미지가 우리가 실제로 실행시킬 이미지입니다. 마찬가지로 openjdk로 이미지를 사용합니다.
FROM openjdk:15.0.1
# 위의 빌드 이미지로부터 만들어진 jar 파일을 복사합니다.
COPY --from=builder /app/build/libs/app.jar .
# 서버를 실행시키는 명령어입니다.
CMD ["java", "-jar", "app.jar"]

스프링 8-3강 - 빌드하기

intelliJ 터미널

gradlew bootRun
gradlew assemble

다 모아서 하나의 jar 파일을 만들어준다. build -> libs -> app.jar 생성된다. 이거를 app.zip으로 이름 변경해서 확인해보면 그대로 다 있다.

java -jar app/build/libs/app.jar

하면 실행이된다.

최근에는 컨테이너 기술을 쓰는데, Docker가 대표적이다.

Docker 설치
https://www.docker.com/products/docker-desktop

인텔리제이 가서

docker ps

뭐가 떠있는지 찾을 수 있다.

docker pull ubuntu:18.04

뭐가 떠있는지 찾을 수 있다.

docker run -it ubuntu:18.04 bash

이제 우분투를 쓸 수 있다.

eixt을 하면 나오게 된다.

docker ps -a 

를 하면 여태까지 실행한 것이 다 나온다.

dockerhub에 가서 원하는 환경을 검색하면 된다.

docker pull openjdk:15

java 15 버전을 받아온다.

docker run -it --name api-server openjdk:15 bash

실행한다.

docker run -it --name api-server -v $(pwd)/app/build/libs:/home/api-server openjdk:11 bash

윈도우에서는 pwd가 없으니 cd ,를 하고 절대경로를 붙여넣자.

docker run -it --name api-server -v C:\Users\injoo\OneDrive\Desktop\codesoom_assignments\spring-week8-assignment-1/app/buil
d/libs:/home/api-server openjdk:11 bash

/home/api-server/로 이동하고 app.jar를 실행하면 된다.

http:localhost/8080 을 하면 떠있지 않다라고 하는데, 자기만의 공간이기 때문이다.

docker run -it --name api-server -v C:\Users\injoo\OneDrive\Desktop\codesoom_assignments\spring-week8-assignment-1/app/buil
d/libs:/home/api-server -p 8080:8080 openjdk:11 bash

포트 설정을 했다. 앞에 것이 내 컴퓨터 입장, 뒤에것이 컨테이너 입장이다.
8080:80 이면 로컬호스트 8080으로 접근 가능하다.

root@8c5f2642b2d5:/# java -jar /home/api-server/app.jar

terminal 하나 더 키고 테스트해보면 잘 나온다.

docker run -it --rm --name api-server -v C:\Users\injoo\OneDrive\Desktop\codesoom_assignments\spring-week8-assignment-1/app/buil
d/libs:/home/api-server -p 8080:8080 openjdk:11 bash -c "java -jar /home/api-server/app.jar"

rm 옵션을 넣어서 끝나고 닫게 했다.

뒤에 실행할 것을 한번에 넣어준다.

MariaDB를 사용해보자

https://github.com/ahastudio/til/blob/main/docker/mariadb.md

docker run -d --name mariadb \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=password \
  -e MYSQL_DATABASE=test \
  mariadb \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci

docker logs -f mariadb

docker stop mariadb
docker rm mariadb

d 옵션은 백그라운드로 띄우는 것이다.

application.yml

spring:
  datasource:
    #url: jdbc:h2:~/data/demo
    url: jdbc:mariadb://localhost:3306/test
    username: root
    password: password
  jpa:
    hibernate:
      ddl-auto: update

jwt:
  secret: "12345678901234567890123456789010"

build.gradle

    // Spring Data JPA
	...
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.7.2'

v 옵션을 주면 꺼도 날아가지 않고 영속성을 유지할 수 있다.

spring:
  datasource:
    #url: jdbc:h2:~/data/demo
    url: jdbc:mariadb://localhost:3306/test
    username: root
    password: password
  jpa:
    hibernate:
      ddl-auto: update

jwt:
  secret: "12345678901234567890123456789010"

---
# "mariadb" Profile을 쓸 때...
spring:
  profiles: mariadb
  datasource:
    url: jdbc:mariadb://localhost:3306/test
    username: root
    password: password

edit configuration 가서

환경 변수를 넣어주자

set SPRING_PROFILES_ACTIVE=mariadb java -jar app/build/libs/app.jar

한꺼번에 넣어줄 수도 있다.

docker run -it --rm --name api-server -v C:\Users\injoo\OneDrive\Desktop\codesoom_assignments\spring-week8-assignment-1/app/buil
d/libs:/home/api-server -p 8080:8080 -e SPRING_PROFILES_ACTIVE=mariadb openjdk:11 bash -c "java -jar /home/api-server/app.jar"

하지만 같은 네트워크가 아니라고 오류가 뜬다. 설정을 localhost로 했는데, localhost가 아니다.

...

---
# "mariadb" Profile을 쓸 때...
spring:
  profiles: mariadb
  datasource:
    url: jdbc:mariadb://mariadb:3306/test
    username: root
    password: password

localhost:3306 대신 mariadb:3306을 넣었다.

docker network create codesoom

name mariadb --network codesoom -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=test mariadb --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

docker run -it --rm --name api-server -v C:\Users\injoo\OneDrive\Desktop\codesoom_assignments\spring-week8-assignment-1/app/build/libs:/home/api-server -p 8080:8080 -e SPRING_PROFILES_ACTIVE=mariadb --network codesoom openjdk:11 bash -c "java -jar /home/api-server/app.jar"

0개의 댓글