[docker-compose.yml 를 이용해 빌드 후 Docker 컨테이너로 배포]

  1. Spring Boot 프로젝트 빌드

    // 터미널에서 해당 프로젝트 위치로 이동
    ./gradlew build
    // gradlew 는 윈도우용.
    
  2. Vue 프로젝트 빌드

    // 터미널에서 해당 프로젝트 위치로 이동
    npm run build
    
  3. 필요한 API 별로 Dockerfile 작성

    # 예시 1
    FROM openjdk:17-jdk-slim
    
    WORKDIR /app
    
    ENTRYPOINT ["java", "-jar", "app.jar"]
    
    # 예시 2
    FROM nginx:stable
    
    COPY ./nginx.conf /etc/nginx/nginx.conf
    # 로컬 경로  Docker 컨테이너 내 리눅스 경로
    
    CMD ["nginx", "-g", "daemon off;"]
    
    # .conf 예시
    events{}
    http {
    
        include /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        upstream was {
            server backend:8080;
        }
    
        server {
            listen 80;
            location /api/ {
                proxy_pass <http://was/>;
            }
    
            location / {
                root /usr/share/nginx/html;
                index index.html;
                try_files $uri /index.html;
            }
    
            location /ws {
                proxy_pass <http://was/ws>;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
            }
        }
    
    }
    
    

    <aside> 📖

    [/docker-entrypoint-initdb.d/]

    FROM mariadb:11.4
    
    COPY ./sql /docker-entrypoint-initdb.d/
    

    </aside>

  4. nginx.conf 설정

    events{}
    http {
    
        include /etc/nginx/mime.types; // 데이터 형식 확인
        default_type  application/octet-stream;
    
        upstream was {
            server backend:8080;
        }
    
        server {
            listen 80; // 80 포트로 클라이언트 접속
            
            location /api/ { // /api 형식으로 들어오는 url을 받아, api를 삭제.
                proxy_pass <http://was/>; // upstream 에 설정한 was 로 넘겨준다.
            }
    
            location / { // / 형식으로 들어오는 url을 받는다.
                root /usr/share/nginx/html; // 해당 폴더에 있는 Vue 컴포넌트들이 기준
                index index.html; // 없으면 index.html 만 반환
                try_files $uri /index.html; 
                // 있으면 해당 uri 에 맞는 컴포넌트를 index.html에 붙여 보낸다.
                // SPA
            }
    
            location /ws { // /ws 형식으로 들어오는 url을 받아, 그대로 넘겨준다.
                proxy_pass <http://was/ws>; // upstream 에 설정한 was 로 넘겨준다.
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                // Http는 기본적으로 단방향 연결이므로, 웹소켓 사용을 위해서 양방향 연결로 upgrade 수행
            }
        }
    
    }
    
  5. docker-compose.yml 작성

    # 예시
    version: "3"
    services:
    
    	#서비스명
      mariadb:
        build:
          context: ./mariadb
        environment:
          MARIADB_ROOT_PASSWORD: ${mariaPassword}
          # 외부에서 주입
          MARIADB_DATABASE: ${mariaDatabase}
          # 외부에서 값 주입
        volumes:
          - ./mariadb/data:/var/lib/mysql
    	
    	#서비스명
      redis:
        build:
          context: ./redis
    	
    	#서비스명
      backend:
        build:
          context: ./server
        environment:
          SPRING_DATA_REDIS_HOST: redis
          # 위쪽에 정의한 서비스 redis를 의미
          SPRING_DATA_REDIS_PASSWORD: 1004
          SPRING_DATASOURCE_URL: jdbc:mariadb://mariadb:3306/slgi_emr_db?useSSL=false
          SPRING_DATASOURCE_USER: root
          SPRING_DATASOURCE_PASSWORD: 1004
          # 직접 값 작성
        volumes:
          - ./server/build/libs/server-0.0.1-SNAPSHOT.jar:/app/app.jar
        depends_on:
          - redis
          - mariadb
    	
    	#서비스명
      frontend:
        build:
          context: ./frontend
        ports:
          - "80:80"
        depends_on:
          - backend
        volumes:
          - ./frontend/dist:/usr/share/nginx/html
    
    

    <aside> 📖

    [volume]

    컨테이너가 생성 또는 삭제되어도 유지되는 데이터 저장소(디렉토리) → 컨테이너 데이터는 휘발성이 강하기 때문에, 삭제 또는 재시작시 데이터가 사라진다.

    방법 설명 장점 단점
    Volume Docker가 관리하는 저장소 관리 편리, 백업 용이, 성능 우수 호스트 디렉토리 직접 접근 어려움
    Bind Mount 호스트의 디렉토리를 명시적으로 지정 유연성 있음, 개발환경에 적합 경로가 하드코딩됨, 이식성 낮음
    tmpfs 휘발성 메모리 저장소 (리눅스 메모리 사용) 빠름, 민감 데이터 일시 저장 휘발성, 영속성 없음
    </aside>

    <aside> 📖

    [depend_on]

    컨테이너 간 의존관계 명시 → 특정 컨테이너가 다른 컨테이너 시작 이후 동작하도록 순서 지정에 사용

  6. dockerignore 작성

  7. https 설정

  8. Git Action

[mime.types 문제]

[Docker Compose 리팩토링]