Docker compose로 Spring, Mysql 배포환경 구성하기

한결·2023년 7월 19일
1

Docker

목록 보기
3/3

개요

프로젝트에서 도커 이미지를 바탕으로 CI/CD 파이프라인 구축할 것
따라서 일단 로컬에서 Spring boot 프로젝트 생성, Dockerfile작성, Docker compose.yml 작성 mysql 연동 후 테스트할 것

  1. Spring boot project
  2. Dockerfile 작성
  3. 해당 도커파일로 docker hub에 올리기
  4. docker-compose.yml 작성
  5. 테스트

1. Spring boot Project

일단 테스트용으로 간단한 rest controller만 만들어두자

https://start.spring.io/ 에서 프로잭트 생성
일단 추후 사용할 Dependencies까지 생각해서 추가

  • Lombok
  • Spring Web
  • Spring Security
  • OAuth2 Client
  • OAuth2 Resource Server
  • MySQL Driver
  • Spring Data JPA

디렉토리 구조

  • UserController
package com.kyunwang.project.controller;

import com.kyunwang.project.model.User;
import com.kyunwang.project.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    // 모든 유저 조회
    @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> user = userRepository.findAll();
        return new ResponseEntity<List<User>>(user, HttpStatus.OK);
    }

    @PostMapping("/user")
    public User create(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping("/user/{id}")
    public Optional read(@PathVariable Long id) {
        Optional<User> userOptional = userRepository.findById(id);

        return userOptional;
    }
}

테스트용이니 코드는 현재 중요한게 아니니 나머지는 생략

2. Dockerfile 작성

FROM adoptopenjdk:11-jdk-hotspot AS TEMP_BUILD_IMAGE
ENV APP_HOME=/app
WORKDIR $APP_HOME
COPY . ./
RUN ./gradlew build -x test --stacktrace

FROM adoptopenjdk:11-jdk-hotspot
ENV ARTIFACT_NAME=test-0.0.1-SNAPSHOT.jar
ENV APP_HOME=/app
WORKDIR $APP_HOME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
EXPOSE 8080
CMD ["java", "-jar", "test-0.0.1-SNAPSHOT.jar"]
  • 빌드 후 jar파일 수행

3. docker hub에 이미지 푸쉬

docker build -t [username]/[image name]:tag
docker tag [username]/[image name]:tag [username]/[image name]:latest
  • 빌드할때 tag 버전명, latest 2개 담
  • push할 때 --all-tags 로 모든 태그 push

4. docker-compose.yml작성

version: '3'

services:
  database:
    container_name: mysql_db
    image: mysql
    environment:
      MYSQL_DATABASE: users_db
      MYSQL_ROOT_HOST: '%'
      MYSQL_ROOT_PASSWORD: 1234
    ports:
      - "3306:3306"
    command: ["--character-set-server=utf8mb4","--collation-server=utf8mb4_unicode_ci"]

    networks:
      - my_network

  application:
    container_name: docker-compose-test
    restart: on-failure
    image: hangyeoleom/user:latest
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://database:3306/users_db?useSSL=false&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_USERNAME: "root"
      SPRING_DATASOURCE_PASSWORD: "1234"
    depends_on:
      - database
    networks:
      - my_network

networks:
  my_network:
  • Spring과 MySQL 연동
  • Spring image는 Docker hub에 있는거 끌어다 씀

docker compose up

docker-compose.yml 있는 곳에서
docker compose up

성공

Postman으로 테스트


성공

결론

이제 docker로 mysql연동함
근데 container 특성상 container 껏다 키면 데이터 사라짐
-> 해결방법 찾아보니
-> Volume 사용방법과 bind mount 방법 2가지가 있음
-> volume방식은 docker에서 제공하는 서비스 따라서 보안도 비교적 좋은 하지만 개발해야하는 환경 특성상 프로젝트 개발 중 잦은 코드 수정, 데이터 변경 등이 있으므로 개발 환경에서는 일단 bind mount 방법으로 유지해야할 것 같음

앞으로 계획
Github action을 통해 AWS ECR에 image 업로드 자동화할 것
AWS Code Deploy로 AWS EC2에 ECR에 업로드된 이미지를 바탕으로 자동 배포 할것

0개의 댓글

관련 채용 정보