๐งฉ SpringBoot
โ๏ธ SpringBoot jar ํ์ผ ์์ฑํ๊ธฐ
๐ง jar file์ด ๋ญ์ฃ ?
Java ARchive Files
๋ฅผ ์๋ฏธํ๋ฉฐ, ์ผ์ข ์ ์๋ฐ ํ๋ก์ ํธ ์์ถ ํ์ผ์ ๋ปํ๊ธฐ ๋๋ฌธ์, zip๊ณผ ์ ์ฌํ๋ค๊ณ ์ดํดํ์๋ฉด ์ข์ต๋๋ค..jar
์ ํ์ฅ์๋ฅผ ๊ฐ์ง ํ์ผ์ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ์ค์ํ ์ปดํ์ผ๋.class
ํ์ผ์ ๊ฐ์ง๊ณ ์๊ฒ ๋ฉ๋๋ค.- ์ฐ๋ฆฌ๊ฐ ์คํ๋ง๋ถํธ๋ก ๊ฐ๋ฐ์ ํ๊ฒ ๋๋ฉด,
build.gradle
๋ฑ์ ํ์ผ์ ์ฌ๋ฌ๊ฐ์ง ์์กด์ฑ์ ์ค์ ํ๊ฒ ๋ฉ๋๋ค.- ์ด๋ jar ํ์ผ ๋ด๋ถ์ ์ด ์์กด์ฑ์ ๋ชจ๋ ํฌํจ์ํค๊ธฐ ๋๋ฌธ์ ์ฝ๊ฒ ๋ฐฐํฌ์ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ ๋๋ค.
- ์ถ์ฒ : [java] jar ํ์ผ์ด๋?
1. IntelliJ์ ์ค๋ฅธ์ชฝ ๋ > gradle > bulid ํด๋ ์ ๊ทผ
2. BootJar ๋๋ธ ํด๋ฆญ์ผ๋ก jar ํ์ผ ์์ฑ
3. Project > {ํ๋ก์ ํธ ์ต์์ ํด๋} > bulid > libs ํด๋ ๋ด๋ถ์ jar ํ์ผ์ ์์ฑ๋์๋์ง ํ์ธ
๐ ๋ง์ฝ jar ํ์ผ์ด
....jar
์ ํจ๊ป...plain.jar
๊ฐ ์ ์ฅ๋์์ ๊ฒฝ์ฐ์๋ ๋น๋ ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์ด์!
- ํด๊ฒฐ ๋ฐฉ๋ฒ : ์ฐ์ ์์ฑํ jar ํ์ผ 2๊ฐ๋ฅผ ์ญ์ ํ๊ณ ,
build.gradle
์ ๋ค์์ ํฌํจํด์ค๋ค์ ๋ค์ jar ํ์ผ์ ๋ง๋ค์ด์ฃผ๊ธฐ- ์ถ์ฒ : Plain jar vs Executable jar(feat. plain jar ์์ฑ ๋ฐฉ์ง)
...
jar {
enabled = false
}
...
{ํจํค์ง๋ช
}-0.0.1-SNAPSHOT.jar
ํํ์ jar ํ์ผ์ ์์ฑํ ์ ์์ต๋๋ค.๐ณ Docker
โ๏ธ Mac์ Docker ์ค์นํ๊ธฐ
1. Docker ํํ์ด์ง์์ dmg ๋ค์ด๋ก๋
Docker Desktop Mac With Apple sillicon
ํด๋ฆญํด ๋ค์ด๋ก๋ ํ์ต๋๋ค.2. ๋ค์ด๋ฐ์ dmg ์ด์ด์ Applications์ ์ถ๊ฐํ๊ธฐ
3. Terminal์์ Docker ๋ฒ์ ํ์ธ
docker -v
๐๏ธ Dockerfile
- Dockerfile์ ํตํด์ jar ํ์ผ์ ์ฌ๋ฆฌ๊ณ ์คํํ ์์
IntelliJ > {ํ๋ก์ ํธ ์ต์์ ํด๋}
์ Dockerfile
๋ง๋ค๊ธฐ
๋ค์ ๋ด์ฉ ์์ฑํ๊ณ ์ ์ฅํ๊ธฐ
๋ค์ ๋ด์ฉ์ ๊ฐ์ธ ์ค์ ์ด๋ฏ๋ก 4๋ฒ์ผ๋ก ๋์ด๊ฐ์ฃผ์ธ์!
(3. ํ๊ฒฝ๋ณ์ ํธ์งํ๊ธฐ)
- jar ํ์ผ์ด ํ๊ฒฝ๋ณ์๋ฅผ ์ฝ์ด๋ค์ด์ง ๋ชปํ๋ ๋ฌธ์
error: unable to access jarfile /build/libs/parking-0.0.1-snapshot.jar
-> ํด๊ฒฐ ๋ฐฉ๋ฒ : ๋ชจ๋ ํ๊ฒฝ๋ณ์๋ฅผ ํ๋์ฝ๋ฉํจ.
Docker์ฉ ParkingServer ํ๊ฒฝ๋ณ์ ํธ์ง(๋น๊ณต๊ฐ)
โ๏ธ BootJar ํ๋ฒ ๋ ๋๋ธํด๋ฆญํด์ ๋น๋ํด์ฃผ๊ธฐ
IntellJ์ ํฐ๋ฏธ๋์์ ๋ค์ ์คํ
๋์ปค๋ฅผ ๋น๋(์ด๋ฏธ์ง ์์ฑ)
docker build -t hayannn/parking_server:1 ./
๋์ปค ์ปจํ
์ด๋ ์คํ
docker run -it -p8080:8080 hayannn/parking_server:1
์ด๋ฏธ์ง ํ์ธ
์ปจํ
์ด๋ ํ์ธ
๋น๋ ์ฑ๊ณต!
ํฌ๋กฌ์์ ํ์ธ(ํ์ํ ๊ฒฝ์ฐ)
-> ์ ๋ฆฌ๋ค์ด๋ ํ
๋จ ํ์ธ!
docker-compose.yml
version: '3'
services:
web:
container_name: web
image: {docker username}/{docker ์ด๋ฏธ์ง ์ด๋ฆ}
expose:
- "8080"
ports:
- "3000:8080"
ํ์ฌ ์ ํฌ๋ 3000๋ฒ ํฌํธ๋ฅผ ํตํด ์ธ๋ถ์์ ์๋ฒ API์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ expose ์ค์ ์ ํด์ฃผ์์ต๋๋ค.
์ฐธ๊ณ ๋ ํผ๋ฐ์ค : ์ฝ๋ Push๋ก ๋ฐฐํฌ๊น์ง! Spring Boot + Github Actions + Docker
๊ทธ ๋ค์ Github Actions๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์๋ก์ด ํจํค์ง๋ฅผ ๋ง๋ค์ด์ฃผ์ด์ผ ํฉ๋๋ค.
์ธํ
๋ฆฌ์ ์ด์์ ๋ฃจํธ ํด๋์ .github ํด๋๋ฅผ ๋ง๋ค๊ณ , ๊ทธ ์์ workflows ํด๋๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
๊ทธ ๋ค์ ~~~.yml ํ์ผ์ ๋ง๋ค์ด์ค ๋ค์, ๋ค์ ๋ด์ฉ์ ์์ฑํฉ๋๋ค.
์์ง commit ํ์ง ๋ง์ธ์!
์์) deploy.yml
name: CD with Gradle
on:
push:
branches: [ "์ฌ์ฉํ๊ณ ์ ํ๋ ๋ธ๋์น ์ด๋ฆ" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: "adopt"
- name: Make application.yml
run: |
cd ./src/main/resources
touch ./application.yml
echo "${{ secrets.PROPERTIES }}" > ./application.yml
shell: bash
- name: Build with Gradle
run: |
chmod +x ./gradlew
./gradlew clean build -x test
- name: Docker build & push to docker repo
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -f Dockerfile -t ${{ secrets.DOCKER_REPO }} .
docker push ${{ secrets.DOCKER_REPO }}
- name: Deploy to server
uses: appleboy/ssh-action@master
id: deploy
with:
host: ${{ secrets.HOST }}
username: ec2-user
key: ${{ secrets.KEY }}
envs: GITHUB_SHA
script: |
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKER_REPO }}
docker-compose up -d
docker image prune -f
ํ๊ฒฝ๋ณ์๋ก ์ง์ ํ ๊ฐ๋ค์ ๋ค์ด๋ ํ
ํด์ฃผ๊ธฐ ์ํด ๊นํ๋ธ ๋ ํฌ์งํฐ๋ฆฌ > settings > Security > Actions
์์ ๊ฐ ๊ฐ์ ๋ฃ์ด์ค๋๋ค.
DOCKER_PASSWORD : ๋์ปค ๋ก๊ทธ์ธ ์ ๋น๋ฐ๋ฒํธ
DOCKER_REPO : ๋์ปค์ ๋ ํฌ์งํฐ๋ฆฌ ์ด๋ฆ
DOCKER_USERNAME : ๋์ปค ๋ก๊ทธ์ธ ์ ์ด๋ฆ ๋๋ ์ด๋ฉ์ผ
HOST : AWS EC2 IP
KEY : AWS EC2 ์์ฑ ์ ์ฌ์ฉํ pem ํค
(pem ํค๋ฅผ ๋ฉ๋ชจ์ฅ ๋ฑ์ผ๋ก ์ด์ด ๋ด์ฉ์ ๋ชจ๋ ๋ณต์ฌ-๋ถ์ฌ๋ฃ๊ธฐ ํด์ฃผ์ด์ผ ํจ)
์ด์ ์์ ์์ฑํ ~~~.yml๋ฅผ commit&push ํด์ค๋๋ค.
on:
push:
branches: [ "์ฌ์ฉํ๊ณ ์ ํ๋ ๋ธ๋์น ์ด๋ฆ" ]
๋ค์๊ณผ ๊ฐ์ด ์ค์ ํด์ฃผ์๊ธฐ ๋๋ฌธ์, push ์์ Github Actions์์ ๊ฐ์งํ๊ณ ๋ฐฐํฌ๋ฅผ ์งํํ๊ฒ ๋ฉ๋๋ค!
๊นํ๋ธ ๋ ํฌ์งํฐ๋ฆฌ > Actions > All workflows
์์ ์ํ๋ ์ปค๋ฐ ๊ธฐ๋ก์ ํด๋ฆญํด ํ์ธํฉ๋๋ค.์์ธํ ๋ด์ฉ์ ์๋์ 2๊ฐ์ง ํธ๋ฌ๋ธ์ํ ์ผ๋ก ์๊ฐํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ ์ฒซ๋ฒ์งธ ํธ๋ฌ๋ธ ์ํ
- ERROR: invalid tag "***/์ด๋ฏธ์ง์ด๋ฆ:ํ๊ทธ": invalid reference format
-> Docker์ ๋ก๊ทธ์ธ์ ์ฑ๊ณต์ ์ผ๋ก ๋์์ง๋ง, ์ค์ image:ํ๊ทธ๋ฅผ ํ์ธํ์ง ๋ชปํ๋ ๊ฒ์ผ๋ก ๋ณด๊ณ ํด๊ฒฐ์ ์ ์ฐพ์๋ณด์์ต๋๋ค.
์ด์ ์ deploy.yml ํ์ผ ์ผ๋ถ
- name: Docker build & push to docker repo
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -f Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/์ด๋ฏธ์ง์ด๋ฆ:ํ๊ทธ .
docker push ${{ secrets.DOCKER_USERNAME }}/์ด๋ฏธ์ง์ด๋ฆ:ํ๊ทธ
...
script: |
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/์ด๋ฏธ์ง์ด๋ฆ:ํ๊ทธ
docker-compose up -d
docker image prune -f
๐ํด๊ฒฐ
/์ด๋ฏธ์ง์ด๋ฆ:ํ๊ทธ
๋ถ๋ถ์ ๋ณด๋ฉด, ํ์ฌ ์ ํฌ๊ฐ ๋ถ๋ฌ์ค๊ณ ์ ํ๋ docker image์์ ๋งค์นญ์ด ์๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒ์ผ๋ก ํ๋จํ์ต๋๋ค.
๋ํ, ๊ทธ ์์ ${{ secrets.DOCKER_USERNAME }}
์ ${{ secrets.DOCKER_REPO }}
๋ก ์์ ํด์ฃผ์์ต๋๋ค.
๋ณ๊ฒฝ ํ deploy.yml
- name: Docker build & push to docker repo
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -f Dockerfile -t ${{ secrets.DOCKER_REPO }} .
docker push ${{ secrets.DOCKER_REPO }}
- name: Deploy to server
uses: appleboy/ssh-action@master
id: deploy
with:
host: ${{ secrets.HOST }}
username: ec2-user
key: ${{ secrets.KEY }}
envs: GITHUB_SHA
script: |
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKER_REPO }}
docker-compose up -d
docker image prune -f
๐ ๋๋ฒ์งธ ํธ๋ฌ๋ธ ์ํ
- ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
์ด์ ์ฑ๊ณต์ ์ผ๋ก Docker๋ฅผ ๋ถ๋ฌ์ค์ง๋ง, ์ด๋ฒ์๋ ์๋ฒ ์ ๋ณด๋ฅผ ๋ถ๋ฌ์ค๋๋ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค๐
์ด ๋ถ๋ถ์ ํด๊ฒฐ์ ์์ฃผ ๊ฐ๋จํ๋๋ฐ์!
์ ํฌ๋ ํ์ฌ ์
๋ฌด๋ฅผ ์ํด ๋ถ์ฌ๋ฐ์ EC2 ์๋ฒ์์ ์์
์ ํด์ผ ํ๋๋ฐ, ์ด EC2 ์๋ฒ๊ฐ Ubuntu๊ฐ ์๋ Amazon Linux 2์์ต๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ค์ ํ๋ฒ deploy.yml ํ์ผ์์ ์์ ์ด ํ์ํ์ต๋๋ค..!!
๋ณ๊ฒฝ ์ด์ deploy.yml ์ค ์๋ฒ์ ์ฐ๊ฒฐํ๋ "Deploy to server" ๋ถ๋ถ
- name: Deploy to server
uses: appleboy/ssh-action@master
id: deploy
with:
host: ${{ secrets.HOST }}
username: ubuntu
key: ${{ secrets.KEY }}
envs: GITHUB_SHA
script: |
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKER_REPO }}
docker-compose up -d
docker image prune -f
๋ณ๊ฒฝ ์ด์ ์ yml์ ๋ณด๋ฉด, ๋ค์๊ณผ ๊ฐ์ด username์ด ubuntu๋ก ๋์ด์๋ ๊ฒ์ ํ์ธํ์ค ์ ์์ต๋๋ค.
์ด๊ฒ์ด ๋ฌธ์ ๊ฐ ๋๋ ์ด์ ๋ ubuntu๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์๋ฒ์ ๋ฌ๋ฆฌ amazon linux 2๋ ๊ธฐ๋ณธ ์ ์ ์ด๋ฆ์ด ec2-user
์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ฐ๋ผ์, yml์ ํตํด AWS EC2 ์๋ฒ๊ฐ ์ฌ์ฉ์๋ฅผ ์ธ์ํ๊ธฐ ์ํด ์ด ๋ถ๋ถ์ ec2-user๋ก ๋ฐ๊ฟ์ฃผ์ด์ผ ํฉ๋๋ค!
์๋ฒ์ ๋ฐ๋ฅธ ์ ์ ์ ๋ํดํธ ์ด๋ฆ ์ฐพ๊ธฐ
๋ณ๊ฒฝ ํ
- name: Deploy to server
uses: appleboy/ssh-action@master
id: deploy
with:
host: ${{ secrets.HOST }}
username: ec2-user
key: ${{ secrets.KEY }}
envs: GITHUB_SHA
script: |
sudo docker rm -f $(docker ps -qa)
sudo docker pull ${{ secrets.DOCKER_REPO }}
docker-compose up -d
docker image prune -f
์ ์งํ๋์์ต๋๋ค!
์ค์ ๋ก ๋ถ์ฌ๋ฐ์ ip๋ฅผ ํตํด ์ ์ํด๋ดค์ต๋๋ค.
์ฑ๊ณต์ ์ผ๋ก ์ ๋ค์ด๊ฐ์ง๋ค์!
Github Actions๋ฅผ ํตํ ๋ฐฐํฌ๊ฐ ๋์๋์ง ํ์ธ
ip๋ฅผ ํตํ API ์ ์
ํ์ฌ ํ๋ก์ ํธ๋ ์นด์นด์ค ์์
๋ก๊ทธ์ธ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, ์นด์นด์ค ์์
๋ก๊ทธ์ธ์ด ์ ์งํ๋๋์ง ํ
์คํธํด๋ณด์์ต๋๋ค.
ํฌ๋กฌ ์ฐฝ์์ {ip์ฃผ์}/kakao/login ์
๋ ฅ
ํฌํธ 3000๋ฒ์ ์ด์ด์ฃผ์ง ์์ ๋ฌธ์ ๊ฐ ์๊ฒผ๊ณ , AWS EC2์์ ํฌํธ ์ ๊ทผ์ ํ์ฉํด์ค ๋ค์ ๋ค์ ์๋ํ๋ ์ ์ด๋ ธ์ต๋๋ค.
์ ์ฉ ์ด์
3000 ํฌํธ ์ ์ฉ ํ
๋ก๊ทธ์ธ์ ์ํ ํ๋ฉด ์ถ๋ ฅ ์๋ฃ!
์ค์ ๋ฐ์ดํฐ๊ฐ ๋ณด์ด๋ API ์ ๊ทผ ์, ์๋ฌ์์ด ๋ฐ์ดํฐ๊ฐ ๋ณด์ฌ์ง๋ ๊ฒ์ ํ์ธ!
(๋ด์ฉ ๋ชจ๋๋ฅผ ๋ณด์ฌ๋๋ฆด ์ ์๋ ์ ์ํด ๋ถํ๋๋ ค์!)
์ฐธ๊ณ ํ ๋ ํผ๋ฐ์ค
๐ ์ฝ๋ Push๋ก ๋ฐฐํฌ๊น์ง! Spring Boot + Github Actions + Docker
๐ [ํ๋ก ํธ ์๋ฒ ๋ฐฐํฌ] ์ฌ์ดํธ ์ฐ๊ฒฐ ๊ฑฐ๋ถ
๐ ๋ฆฌ๋ ์ค ํฌํธ ์ํ ํ์ธ ๋ฐ ์ด๊ธฐ