JavaRush /Java Blog /Random-KO /애플리케이션 배포를 구현합니다 - "A부터 Z까지 Java 프로젝트"
Roman Beekeeper
레벨 35

애플리케이션 배포를 구현합니다 - "A부터 Z까지 Java 프로젝트"

Random-KO 그룹에 게시되었습니다
안녕하세요 여러분. 우리는 프로젝트 작성에 관한 일련의 기사를 계속합니다. “A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 1

가지를 분류하라

중요한 점은 저장소의 브랜치와 순서를 잃지 않기 위해 STEP_{number} 접두사를 추가하여 이름을 바꾸기로 결정했습니다 . 예를 들어, 기본 분기 외에 세 개의 분기가 있습니다.
  • JRTB-0
  • JRTB-2
  • JRTB-3
어느 것이 그 다음에 가야하는지 즉시 이해하지 못할 것입니다. 따라서 이름을 다음과 같이 바꾸겠습니다.
  • STEP_1_JRTB-0 - 첫 번째 단계
  • STEP_2_JRTB-2 - 두 번째 단계
  • STEP_3_JRTB-3 - 세 번째 단계
다음 기사에서도 마찬가지입니다. 브랜치 이름을 바꾸려면 저장소 페이지 로 이동하여 브랜치 상자를 찾아 따라가십시오. “A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 2각 브랜치 아래에서 연필을 클릭하고 브랜치 이름을 바꾸십시오. “A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 3결과적으로 다음과 같은 결과를 얻습니다. 그런데 내 텔레그램 채널을“A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 4 구독한 모든 사람이 찾았습니다. 즉시 지점 이름을 바꿨습니다.

도커에 대해 조금

도커란 무엇입니까? 간단히 말해서 애플리케이션을 빠르고 안전하게 배포(배포)하고 해당 애플리케이션에만 필요한 폐쇄형 인프라를 생성할 수 있는 도구입니다. 아직은 어렵다, 이해한다. 일반적으로 Docker는 빠르고 효율적으로 작업할 수 있는 개발 플랫폼으로 이해될 수 있습니다. Docker는 서버에서 실행되는 프로그램으로 이해될 수 있습니다. 이 프로그램에는 애플리케이션과 함께 컨테이너를 저장하는 기능이 있습니다. 컨테이너란 무엇입니까? 이는 필요한 모든 것을 추가할 수 있는 별도의 인프라입니다. 예를 들어, Java 애플리케이션의 경우 애플리케이션을 실행하려면 JRE가 필요하고 컨테이너에는 이를 포함하며 다른 소프트웨어가 필요합니다. 이를 추가할 수 있습니다. 아니면 Linux와 Tomcat 서블릿 컨테이너가 필요할 수도 있습니다. 이것도 가능합니다. 컨테이너는 이미지를 기반으로 생성됩니다. 즉, Docker 컨테이너를 생성하는 데 필요한 모든 것이 기록되는 특정 템플릿입니다. 이 이미지를 만드는 방법은 무엇입니까? 우리의 경우 컨테이너에 무엇이 있어야 하는지 설명하는 Dockerfile을 프로젝트 루트에 생성해야 합니다. 우리는 봇의 토큰을 어디에도 노출시키고 싶지 않기 때문에 애플리케이션을 배포할 때마다 이를 전달해야 합니다. 이 주제에 대한 자세한 내용은 여기여기에서 읽을 수 있습니다 .

JRTB-13을 쓴다

우리는 애플리케이션을 서버에 빠르고 쉽게 배포하는 프로세스를 설정해야 합니다. 즉, 24시간 연중무휴로 작동하는 기계입니다. Docker를 기본으로 삼아 보겠습니다. 그러나 우리 목록에는 이 기능을 추가하는 작업이 없습니다. 왠지 만들면서 놓쳤네요. 문제 없습니다. 지금 만들어 보겠습니다. GitHub의 이슈 생성 탭 으로 이동하여 기능 요청을 선택합니다. “A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 5작업에 대한 설명, 승인 기준을 추가하고 이 이슈가 속한 프로젝트를 설정하고 새 이슈를 생성할 수 있습니다. 이제 작업이 승인되었음을 “A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 6표시합니다. 작업의 경우 작업 상태를 To do on In Progress(진행 중)에서 변경하세요. 이것은 어려운 기사가 ​​될 것입니다. 문제가 있으면 댓글로 적어주세요. 최선을 다해 모니터링하고 답변해드리겠습니다. 작은 고객지원이 되겠습니다 :D“A부터 Z까지 Java 프로젝트”: 애플리케이션 배포 구현 - 7

Dockerfile 만들기

도커파일이란 무엇입니까? Docker의 경우 이는 Docker 컨테이너용 이미지를 생성하는 방법에 대한 스크립트(단계별 지침)입니다. 애플리케이션이 작동하려면 JDK 버전 11이 필요합니다. 즉, JDK 11 도커 이미지를 찾아 이미지에 추가해야 합니다. 이는 메모리에 종속성을 추가하는 방법과 유사합니다. Docker에는 이러한 목적으로 DockerHub 가 있습니다 . 이미지를 로컬로 다운로드하려면 해당 위치에 등록해야 합니다. 등록 후 JDK11을 찾으러 갑시다. 내가 찾은 것에서 이것은 컨테이너인 acceptopenjdk/openjdk11 입니다 . 이 컨테이너에 대한 설명에는 dockerfile에 필요한 내용이 포함되어 있습니다.
FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
jar 파일을 가져오는 폴더를 수정해 보겠습니다. mvn package maven 작업을 실행한 후 대상 폴더에 있습니다. 이 모든 작업을 수행하기 전에 업데이트된 기본 브랜치를 기반으로 작업을 위한 새 브랜치인 STEP_4_JRTB-13 을 만듭니다 . 이제 일할 수 있습니다. 프로젝트 루트에서 Dockerfile 확장자가 없는 파일을 만들고 내부에 다음을 추가합니다.
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
첫 번째 줄은 이미지의 기반이 되는 것입니다(adoptopenjdk/openjdk11). 두 번째 줄은 대상 폴더에 있는 JAR_FILE이라는 이미지에 인수를 추가하는 것입니다. 또한 현재 폴더는 Dockerfile의 위치에 따라 결정됩니다. 세 번째 줄 - 프로젝트의 jar를 docker 이미지에 복사합니다. 마지막 줄에는 기본적으로 터미널의 명령으로 생성된 배열이 포함되어 있으며 공백으로 구분되어 있습니다. 즉, 결국 다음이 실행됩니다: “java -jar /app.jar” 봇 토큰을 비밀로 유지하려면 컨테이너를 시작할 때 봇 이름과 해당 토큰이라는 두 가지 변수를 전달해야 합니다. 이를 위해 변수를 사용하여 프로젝트를 시작하는 쿼리를 작성하겠습니다. 어떻게 해야 할까요? Google에서 검색해야 합니다. 다음은 일반적인 설명이 포함된 첫 번째 링크 입니다. 우리는 무엇을 하고 싶은가? 우리가 정의한 application.properties 파일에는 두 개의 변수가 있습니다.
  • 봇.사용자 이름
  • 봇.토큰
나는 도커 컨테이너를 실행하고 아무도 이 값을 볼 수 없도록 매번 거기에 내 값을 전달하고 싶습니다. SpringBoot에서는 jar 프로젝트가 시작될 때 설정된 환경 변수가 application.properties 파일의 환경 변수보다 우선한다는 것을 알고 있습니다. 요청에 변수를 전달하려면 -D{변수 이름}=”{변수 값}” 구성을 추가해야 합니다 . 우리는 중괄호를 추가하지 않습니다. ;) 미리 정의된 값(봇의 이름과 토큰)을 사용하여 애플리케이션을 시작하는 요청을 받게 됩니다: java -jar -Dbot.username=”test.javarush.community_bot” -Dbot. token=”dfgkdjfglkdjfglkdjfgk” *.jar 이제 이러한 변수를 도커 컨테이너 내부에 전달해야 합니다. 이것은 환경 변수입니다. 앞으로는 데이터베이스가 애플리케이션에 문제 없이 원활하게 작동하도록 하기 위해 docker-compose를 사용할 것입니다. 이는 작업, 시작, 컨테이너 간의 종속성을 구성할 수 있는 별도의 도구입니다. 즉, 하나의 인프라의 컨테이너를 관리하기 위해 Docker 위에 추가되는 기능입니다. 또한 docker-compose를 실행하기 전에 서버에서 모든 코드 변경 사항을 가져와서 애플리케이션을 빌드하고 이전 버전을 중지했는지 확인해야 합니다. 이를 위해 bash 스크립트를 사용합니다. 와... 다 어려운 것 같군요. 저도 동의합니다. 그러나 애플리케이션 배포 설정 작업은 항상 지루하고 복잡한 프로세스입니다. 따라서 우리는 꽤 좋은 계획을 가지고 있습니다.
  1. Bash 스크립트를 실행해 보겠습니다.
  2. Bash 스크립트는 docker-compose를 실행합니다.
  3. Docker-compose는 애플리케이션과 함께 Docker 컨테이너를 시작합니다.
  4. Docker 컨테이너는 애플리케이션을 실행합니다.
이제 두 변수(봇 이름과 해당 토큰)가 지점 1에서 지점 4로 이동하는지 확인해야 합니다. 그리고 이 두 변수는 Java 애플리케이션을 시작할 때 사용됩니다. 끝에서 처음으로 가자. 우리는 jarnik을 시작하기 위해 어떤 명령을 실행해야 하는지 이미 알고 있습니다. 따라서 두 개의 변수를 수락하고 요청에 전달하는 방법을 학습하도록 Dockerfile을 구성합니다. 이를 위해 Dockerfile을 다음 형식으로 줄여보겠습니다.
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}", "-jar", "/app.jar"]
두 줄을 추가하고 ENTRYPOINT를 업데이트한 것을 볼 수 있습니다. 윤곽:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
인코더 파일 내부에 변수를 선언합니다. 기본적으로 값이 지정되어 있습니다. 이 dockerfile에서 이미지를 생성할 때 해당 이름을 가진 환경 변수가 전달되면 값이 달라집니다. 그리고 ENTRYPOINT에는 이러한 환경 변수를 읽는 몇 가지 요소를 더 추가했습니다.
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
여기서는 ${} 구문을 사용하여 줄 내부에서 BOT_NAME 및 BOT_TOKEN의 값이 전달되는 것을 볼 수 있습니다. 다음으로 이러한 변수를 docker-compose에 수신하고 전달하는 방법을 가르쳐야 합니다.

docker-compose.yml 생성

YAML 형식에 대해 별도로 읽는 것이 좋을 것입니다. 그렇지 않으면 기사가 이미 비약적으로 성장하고 있습니다. 우리에게 이는 .properties 유형의 변수에 대한 또 다른 설명일 뿐입니다. 속성에서만 점으로 작성되지만 YAML에서는 좀 더 아름답게 작성됩니다. 예를 들면 이렇게 됩니다. .properties의 두 변수: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin 그러나 .yaml(.yml과 동일)에서는 다음과 같습니다.
javarush:
	telegram:
		bot:
		  name: ivan
		  token: pupkin
두 번째 옵션은 더 아름답고 이해하기 쉽습니다. 공백은 위에 표시된 대로 정확하게 입력되어야 합니다. application.properties와 application.yml을 어떻게든 번역해 보겠습니다. 먼저 그것을 만들어야합니다. 프로젝트 루트에서 docker-compose.yml 파일을 만들고 거기에 다음을 작성합니다.
version: '3.1'

services:
 jrtb:
   build:
     context: .
   environment:
     - BOT_NAME=${BOT_NAME}
     - BOT_TOKEN=${BOT_TOKEN}
   restart: always
첫 번째 줄은 docker-compose 버전입니다. services: 이 뒤에 나오는 모든 줄(이동될 예정)은 우리가 구성하고 있는 서비스를 나타냅니다. 지금까지 우리는 jrtb 라는 Java 애플리케이션 하나만 가지고 있습니다 . 그리고 이미 그 아래에 모든 설정이 있을 것입니다. 예를 들어 빌드: 컨텍스트: . docker-compose.yml과 동일한 디렉터리에서 Dockerfile을 찾을 것이라고 말합니다. 그러나 Environment: 섹션은 필요한 환경 변수를 Dockerfile에 전달하는 일을 담당합니다. 우리에게 꼭 필요한 것. 따라서 아래에 변수를 전달합니다. Docker-compose는 서버 운영 환경 변수에서 이를 찾습니다. Bash 스크립트에 추가해 보겠습니다.

Bash 스크립트 만들기

마지막 단계는 bash 스크립트를 만드는 것입니다. 프로젝트 루트에 start.sh라는 파일을 생성하고 거기에 다음을 작성합니다.
#!/bin/bash

# Pull new changes
git pull

# Prepare Jar
mvn clean
mvn package

# Ensure, that docker-compose stopped
docker-compose stop

# Add environment variables
export BOT_NAME=$1
export BOT_TOKEN=$2

# Start new deployment
docker-compose up --build -d
첫 번째 줄은 모든 bash 스크립트에 필요합니다. 첫 번째 줄이 없으면 작동하지 않습니다. 그런 다음 실행해야 하는 터미널의 명령 집합입니다. 명확하게 설명할 수 있도록 각 명령에 주석을 추가했습니다. 제가 설명하고 싶은 유일한 것은 $1과 $2의 의미입니다. 이는 bash 스크립트가 시작될 때 전달되는 두 가지 변수입니다. 내보내기 명령을 사용하면 서버 변수에 추가되고 docker-compose에서 읽혀집니다. 이것은 Windows에서는 작동하지 않을 수도 있지만 Ubuntu에서는 작동하지만 확실하지 않습니다. 이제 작업을 중지하는 stop.sh 스크립트를 추가해야 합니다. 여기에는 여러 줄이 포함됩니다.
#!/bin/bash

# Ensure, that docker-compose stopped
docker-compose stop

# Ensure, that the old application won't be deployed again.
mvn clean
여기서는 docker-compose를 중지하고 마지막 빌드 이후 계속 남아 있던 jarnik 프로젝트를 정리합니다. 우리는 프로젝트가 정확하게 재구축되도록 하기 위해 이렇게 합니다. 선례가 있었기 때문에 추가합니다.) 결과적으로 4개의 새 파일이 생성됩니다.
  • Dockerfile - 애플리케이션의 이미지를 생성하기 위한 파일입니다.
  • docker-compose.yml - 컨테이너를 시작하는 방법에 대한 설정이 포함된 파일입니다.
  • start.sh - 애플리케이션 배포를 위한 bash 스크립트.
  • stop.sh는 애플리케이션을 중지하는 bash 스크립트입니다.
또한 애플리케이션 버전을 0.2.0-SNAPSHOT에서 0.3.0-SNAPSHOT으로 업데이트할 예정입니다. RELEASE_NOTES에 새 버전에 대한 설명을 추가하고 거기에 있던 내용을 약간 리팩터링해 보겠습니다.
# 릴리스 노트 ## 0.3.0-SNAPSHOT * JRTB-13: 프로젝트에 배포 프로세스 추가 ## 0.2.0-SNAPSHOT * JRTB-3: 텔레그램 봇 명령 처리를 위한 명령 패턴 구현 ## 0.1.0-SNAPSHOT * JRTB -2: 스텁 텔레그램 봇 추가 * JRTB-0: SpringBoot 스켈레톤 프로젝트 추가
그리고 README에 애플리케이션을 배포하는 방법을 설명하는 새로운 단락을 추가합니다.
## 배포 가능한 한 쉬운 배포 프로세스: 필수 소프트웨어: - bash 스크립트 실행을 위한 터미널 - docker - 애플리케이션 배포를 위한 docker-compose, 필요한 분기로 전환 및 bash 스크립트 실행: $ bash start.sh ${bot_username} ${bot_token } 그게 다야.
물론 모든 내용은 영어로 작성되어 있습니다. 평소와 같이 새로 생성된 브랜치 STEP_4_JRTB-13에서 JRTB-13이라는 이름의 새 커밋을 생성합니다. docker를 통해 배포 프로세스를 구현 하고 푸시합니다. 이전 기사에서 이미 설명한 내용에 대해 자세히 설명하지 않습니다. 같은 일을 반복하는 것은 의미가 없습니다. 게다가 그것을 알아 내고 스스로 해본 사람들은 질문이 없을 것입니다. 지금은 새 브랜치를 생성하는 방법, 커밋을 생성하는 방법, 커밋을 저장소에 푸시하는 방법에 대해 이야기하고 있습니다.

결론

오늘 나는 신중하게 고려하고 추가 독서를 통해 확장해야 할 새로운 정보를 많이 보여 주었습니다. 가장 중요한 점은 ONE(!!!) 명령의 도움으로 애플리케이션을 배포하는 데 필요한 모든 작업이 완료된다는 것입니다. 이건 너무 멋있어서 말도 못 할 것 같아요. 예, 변수를 올바르게 전달하는 방법을 이해하기 위해 Docker 문서에서 상당한 시간을 소비해야 했습니다. 이제부터 텔레그램 봇은 항상 최신 버전 의 메인 브랜치에서 작동합니다. 텔레그램 봇에 연결합니다. 오늘은 읽기에 좋은 자료에 대한 링크가 없을 것입니다. 책임은 귀하에게 있습니다. 정보를 검색하는 방법을 배워야합니다. 내 텔레그램 채널을 구독한 모든 사람은 봇 배포에 대해 거의 즉시 알게 되었습니다. 친구 여러분, 프로젝트가 마음에 드시나요? 그에게 별을 줘 ! 이렇게 하면 더 많은 인기를 얻게 될 것이고 더 많은 사람들이 그것에 대해 배우고 배울 수 있게 될 것입니다. 평소와 마찬가지로 GitHub에 등록하고 내 계정을 팔로우하여 이 시리즈와 내가 그곳에서 작업하는 다른 프로젝트를 팔로우하는 것이 좋습니다. 이제 데이터베이스를 연결할 준비가 되었습니다. 다음 기사는 더 길어질 것이며 여기서는 데이터베이스 작업에 필요한 모든 작업을 수행할 것입니다. 모든 설명은 JRTB-1 에 있습니다 .

시리즈의 모든 자료 목록은 이 기사의 시작 부분에 있습니다.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION