구성도

 

[DNS의 활용]

Spring은 Datasource를 연결할 때 DB의 IP를 알 수 없어서 환경변수를 이용한다고 함.

환경변수는 말그대로 변수이므로 S_D_URL = 10.10.1.1로 들어가면 그것을 Spring이 참조하게 된다. 그 과정에서 DNS 레지스트리가 필요한 거라고 하심.

 

리버스 프록시 (Nginx)를 따로 둘것이다.

리버스 프록시는 모든 사용자 요청을 받아서 HTTP Header, HTTP Body 등을 받아서 처리한다.

리버스 프록시는 URL을 분석하여 / 로 요청오면 React로 보내주고, /api 로 요청이 들어오면 거부(Block) 하도록 구현할 것이다. 외부에서는 /api 를 사용하지 못하도록 하기 위함이다.

리버스 프록시는 /api로 요청이 오면 모두 block할 예정이지만 예외사항으로 React에서 들어오는 /api 요청은 Backend로 연결 시켜 주는 역할 까지 겸한다.

 

 

React에서는 /api/product 로 하는데 Spring에는 @RequestMapping이 /product 처럼 만들 예정이라서 /api/product로 오면 redirect하여 /api를 삭제하고 /product로 가도록 구현할 것이다. (왜 굳이 이렇게 하는지는 아직 모르겠다..)

[실습목표]

Spring과 React를 연결하기 

 

[React 코딩하기 및 Cors 해결하기]

실습목표 성취를 위해 React 코딩이 조금 필요하다.

25강에서 만들었던 my-app으로 서버와 통신하는 것이 끝이다.

 

App.js

import './App.css';
import Card from "./components/Card";
import {useEffect, useState} from "react";

function App() {
  const [products, setProducts] = useState([]);

  async function onLoad(){
      //let response = await fetch('http://localhost:8080/products');
      let response = await fetch('http://192.168.0.3:8080/products');
      let responseBody = response.json();
      console.log("onLoad",responseBody);
      setProducts(responseBody);
  }

  //해당 페이지가 열릴 때 한번 실행된다.
  //두 번째 인수는 어떤 값이 변경될 떄 다시 그릴거야?
  useEffect(() => {
      onLoad();
  }, []);

  return (
    <>
      <h1>상품목록 페이지</h1>
      <hr/>
      <div>
          {
              products.map((product)=> <Card id={product.id} product={product}/>)
          }
      </div>
    </>
  );
}

export default App;

 

Card.js

import React from 'react';
import '../App.css'

const Card = ({product}) => {
    return (
        <div className='product-card'>
            {product.id} : {product.name}, {product.price}원
        </div>
    );
};

export default Card;

 

 

일단 윈도우에서 코딩을 했다. IDE가 로컬컴퓨터에 있어서.. 코딩된 폴더 자체를 H2로 옮기는 작업을 해줘야한다..

React 코딩 완료 후 잘 되는지 확인하기 위해 npm start를 하고 브라우저창을 켰는데 작업 결과가 제대로 나오지 않는다.

네트워크 탭을 열어보니 cross-origin 에러가 나온다.

localhost:3000 -> 192.168.0.3으로 요청하는걸 열어줘야한다.

 

// 스프링 서버 전역적으로 CORS 설정
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*") // 허용할 출처
                .allowedMethods("GET", "POST") // 허용할 HTTP method
                .allowCredentials(true) // 쿠키 인증 요청 허용
                .maxAge(3000); // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
    }
}

전에 받아놨던 강의교재(?) SpringBoot프로젝트인 product 에 저렇게 코딩 해두고 H2서버에 있던 product를 지운 다음 윈도우에서 코딩한 product를 통째로 옮겨주었다.

 

1. ~ex09 / product 디렉토리 삭제 및 윈도우에서 코딩한 것 옮겨주기.

2. 코드를 변경하였기 때문에 기존에 올라가 있던 서버를 내린다.

docker compose down

 

2. SpringBoot & MySQL 컨테이너 재실행

docker compose up -d --build

이미지까지 재생성하기 위해 --build 옵션을 사용하자.

 

재실행이 완료되면 이렇게 React가 SpringBoot와 통신하여 데이터를 제대로 가져오는 것을 볼 수 있다.

 

[이전 강의에서 실습했던 내용 덮어쓰기]

이전강의에서 실습했던 my-react-app-auto-build 를 모두 삭제하고, 지금 Spring과 통신할 수 있는 코드들을 다시 덮어 씌운 후 docker build를 해본 결과 아주 잘 작동한다!

저렇게 5개의 파일들을 ex09/my-react-app-auto-build 에 복사한 후 이전강의 에서 만들었던 Dockerfile을 이용해서

docker build -t react-app ./ 

docker run ~  

한 결과 제대로 작동하는 것을 확인했다.

 

 

강의를 쭉 들으면 강사님도 cors 에러를 겪는 것이 나오고 cosr에 대해 설명해주신다.

교차출처 방지 에러는 서로 도메인(포트가 달라도 도메인이 다른것이라네?)이 다른 요청에 대해서 서버 측에서 보안을 위해 요청하는 것을 거부하는 것을 의미한다고 하심.

cross origin : 서로 도메인이 다른 것.

 

강사님은 메서드에 어노테이션을 붙여서 해결하심.

 

다음 강의에서는 굳이 cors 설정을 안해도 되도록 리버스 프록시 라는 것을 사용해본다고 하심.

[실습목표]

이번 강의는 이전강의와 같이 React를 Nginx에서 실행하도록하는 목표를 공유하고있다.

차이점은 이전강의에서는 직접 build해줬지만 이번 강의에서는 build조차 자동으로 되도록 하고자 한다.

(이러한 차이점으로 인해 내 로컬에 nodeJs 환경이 없어도 도커로 빌드까지해서 실행까지 될수 있는 환경이 구축된다.)

 

[실습 전 준비사항]

이번 강의 실습을 위해 window에서 코딩한 my-app 프로젝트(react)를 docker가 있는 H2 서버로 옮겨주도록하자.

이전 강의와 구별되도록 ex09 / my-react-app-auto-build 라는 디렉토리를 만들어서 옮겨주었다.

(node_moudules는 COPY를 하지 않는다. npm install을 할 때 package.json을 참조하여 필요한 라이브러리들이 node_modules에 자동으로 생기기 때문.)

ex09 / my-react-app-auto-build 로 복사한 react프로젝트

총 5개의 파일만 H2 서버로 옮겨주었다.

 

[Dockerfile 작성하기]

FROM node:alpine as build
WORKDIR /app
COPY package.json /app
RUN npm install --silent
COPY . /app
RUN npm run build

FROM nginx
#--from=build는 위에있는 FROM으로 부터 이미지가 구워지는데 그 결과로 나온 것을 의미한다.
# 위에서 나온 결과물인 /app/build 를 /usr/share/nginx/html로 복사하라는 의미이다.
COPY --from=build /app/build /usr/share/nginx/html
ENTRYPOINT ["nginx","-g","daemon off;"]

 

설명을 덧붙이자면

위의 FROM은 npm run build를 해서 build폴더에 build된 파일들을 생성하기 위함이고, 

아래의 FROM부터는 이전 실습내용과 같이 build된 폴더를 서비스할 nginx를 위한 코드들이다.

  COPY package.json /app      #node_modules를 만들기 위해 먼저 복사
 RUN npm install --silent  #이때 node_modules가 생긴다., --silent는 터미널 출력을 최소화하는 명령어이다.
#src, public 등의 파일을 /app으로 복사한다. (이미 있는 package.json, node_moduels는 덮어쓰기 하지 않아서 복사가 되지 않는다.)
COPY . /app
RUN npm run build   #해당 명령어까지 실행시키면 build파일이 생긴다.

 

신기한 것은 하나의 Dockerfile안에 2개의 FROM을 사용해서 컨테이너를 2개 만드는 것과 비슷한 효과를 낼 수 있다는 점인데... 인터넷 검색을 해보니 멀티 스테이지 빌드라고 한다.

 

※ 멀티 스테이지 빌드 

컨테이너 이미지를 만들면서 빌드 등에는 필요하지만, 최종 컨테이너 이미지에는 필요 없는 환경을 제거할 수 있도록 단계를 나누어 이미지를 만드는 방법

 

멀티스테이지 빌드를 사용하면 빌드에는 필요하지만 최종 배포시에는 필요없는 파일들은 모두 삭제된 상태로 컨테이너가 실행되므로 좀 더 가벼운 실행환경을 만들 수 있다는 장점이 있다.

 

[Docker 빌드 및 실행하기]

#빌드하기
docker build -t react-app-auto-build ./

#확인하기
docker images

#실행하기
docker run -d -p 9011:80 react-app-auto-build

 

끝!

※ React는 윈도우에서 코딩하고 Docker는 H2서버(우분투)에 있기 때문에 강의와 좀 다르게 실습했다.

[학습목표]

React를 Nginx에서 서비스 되도록 하기

 

 

실습 디렉토리 : ex09 / my-react-app

 

1. React 앱 Build 하기 (Window)

25강에서 실습했던React앱에서 npm run build를 통해  build파일들을 만들어야한다.

#25강에서 실습한 윈도우에 있는 react 실습 폴더(my-app)로 이동한다.
#윈도우 터미널에 실습 폴더로 이동한 후 build 실행.
npm run build

 

build란? 간단히 말하면 배포할 코드들을 만드는 것.

빌드 폴더에 프로덕션용 앱을 빌드합니다.
프로덕션 모드에서 React를 올바르게 번들링하고 최상의 성능을 위해 빌드를 최적화합니다.

빌드가 축소되고 파일 이름에 해시가 포함됩니다.

 

npm run build를 실행하면 프로젝트 폴더에 build파일이 생긴다.

해당 폴더의 내용들을 docker가 설치되어있는 H2 서버로 옮겨주도록 하자.

SFTP를 통해서 ex09 / my-react-app 으로 옮겨주었다.

 

2. Dockerfile 생성 (Ubuntu)

이전 13강, 28강 내용과 별반 다를것이 없다. Nginx를 실행하기 위한 Dockerfile을 만들어주면 된다.

FROM nginx

COPY build /usr/share/nginx/html

ENTRYPOINT ["nginx", "-g", "daemon off;"]

다만, copy하는 대상이 방금 window에서 옮겨준 build 폴더를 통째로 /uar/share/nginx/html로 옮겨주면 된다.

 

3. Docker build 및 실행하기

이전 강의 와 같이 docker build하고 실행해주자.

$docker build -t react-app ./
$docker run -d -p 9011:80 --name=react-app react-app

 

실행된 컨테이너에 접속해보면 전에 실습한 React앱이 잘 뜨는것을 볼 수 있다.

 

[실습목표]

React를 npm start로 실행하는 것은 NodeJs를 이용한 방법이고, 이번 강의에서는 해당 방법을 이용하지 않고, Nginx로 실행하는 방법을 알아보자.

 

React를 어렵게 생각하지 말고 JS로 화면을 그리는 라이브러리로 생각하자.

React -> build -> html로 만들고,

웹서버(Nginx)를 이용해서 해당 html을 전달하게 하는 것이 최종 목적이다.

 

 

[실습 하기 전]

예전 16강에서 ex03에 Dockerfile을 이용한 Nginx구축을 한 적이 있다. 해당 강의가 기억나지 않으면 한번 리마인드 하고 오자.

https://ilikecoding.tistory.com/98

 

도커 입문 16강 - docker file step4 - nginx 내부구성 알아보기

1. 실습준비그동안의 실습 내용들 모두 정리nginx, httpd 컨테이너, 이미지 모두 지운 다음 lecture/ex03디렉토리를 생성한다. 2. 파일 생성ex03 디렉토리 안에서 아래와 같이 디렉토리와 Dockerfile을 생성

ilikecoding.tistory.com

 

실습 디렉토리 : ~/ex09 (27강에서 이미 생성하였다.)

생성 디렉토리 : ex09$ mkdir -p nginx/webapp (nginx -> webapp 디렉토리를 생성해준다.)

 

1. index.html 생성 (ex09 -> nginx -> webapp)

> ~/ex09/nginx/webapp$ vi index.html

#vi 에디터에서 아래와 같이 작성 후 저장해준다.
<h1>My nginx</h1>

 

2. Dockerfile 생성 (ex09 -> nginx)

ex09/nginx$ touch Dockerfile

16강 때와 다르게 현재 시점에서 설정파일은 별로 중요하지 않다.

 

Dockerfile

FROM nginx
WORKDIR /usr/share/nginx/html
COPY webapp .

ENTRYPOINT ["nginx","-g", "daemon off;"]

 

3. Dockerfile 빌드 및 nginx 컨테이너 실행

docker build -t nginx-app ./

빌드하기

docker run -d -p 9011:80 --name=nginx-test nginx-test

이미지 실행하기

 

4. 접속해보기

[서버IP]:9011 로 접속해보면 설정한 index.html이 제대로 전달되는지 확인하면 된다.

 

설정한 index가 제대로 나오는 것을 확인할 수 있다.

27강은 그냥 기본적인 SpringBoot 앱을 만드는 과정이다. 굳이 따라하지 않아도 소스가 Git에 올라와있어서 나중에 필요할 때 clone만 받으면 될 것 같다.

 

https://github.com/codingspecialist/docker-product

 

GitHub - codingspecialist/docker-product

Contribute to codingspecialist/docker-product development by creating an account on GitHub.

github.com

 

 

도커로 Spring & MySQL 컨테이너를 만들어서 실행시켜보는 강의이다.

 

강의는 [도커 입문 23강 Spring& MySQL] 강의와 매우 비슷하게 진행되었다. 실제로도 23강에서 사용했던 Dockerfile, docker-compose.yml 파일을 재활용했다.

 

이전 25강은 React에 대해서 간단하게 배웠다면 이번에는 React와 연결전에 백엔드에 대해서 알려주는 느낌이랄까

 

[실습 전 준비]

실습 디렉토리 : ~/ex09

GIT HUB : https://github.com/codingspecialist/docker-study/tree/main

 

GitHub - codingspecialist/docker-study

Contribute to codingspecialist/docker-study development by creating an account on GitHub.

github.com

강사님의 git에서 모든 디렉토리를 다운로드 받아서 ex09를 보면된다.

product : Spring Boot 프로젝트(gradle)

db : Mysql 

 

[DB]

db 디렉토리에 있는 Dockerfile은 23강에서 실습했던 내용과 똑같다. 다만, init.sql에서 초기화하는 쿼리문이 살짝 달라졌지만 어렵지않다.

 

[Spring Boot]

Spring Boot는 product 디렉토리에 있는데, /product/src/main/resources/application.yml에서 profiles -> active를 prod로 변경해주면 된다. 사실 해당 작업은 안해도 무방한데, product의 Dockerfile에서 맨 마지막 ENTRYPOINT 부분에 -Dspring.profiles.active=prod를 추가할 것이기 때문에 안해도 상관은 없다.

 

그리고 /product/src/main/resources/application-prod.yml 에서 Datasource 연결 부분을 모두 환경변수로 잡는것 정도?

spring:
  datasource:
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
    driver-class-name: ${SPRING_DATASOURCE_DRIVER}

 

product안에 있는 Dockerfile도 23강에서 했던 내용과 비슷하다.

 

[docker-compose.yml]

SpringBoot 컨테이너와 mysql컨테이너를 묶어서 실행시키 위한 docker-compose.yml을 작성했는데 이것 또한... 23강에서 사용한 것을 복사/붙여넣기 하면 된다.

단, 변경해야할 것들이 몇 가지 있는데... build > context를 db, product로 각각 맞게 변경해주어야 한다. 그리고 db는 volumes도 ./db로 변경해줘야 한다. (이는 필수는 아님..)

 

이렇게 해서 docker compose up -d --build 를 하면 컨테이너들이 실행된다.

[서버주소]:8080/products 로 접속해서 제대로 나오는지 확인 하면 끝!

 

프로젝트 설명

사용자 -> nginx -> (리버스 프록시) -> React -> Spring -> DB

React -> Spring으로 갈 때 포트가 달라서 Cross Origin이 나타날 텐데 Nginx 설정으로 무마시킬수 있다고 하심.

 

다음 강의에선 React로 간단히 FE 구축 그 다음 React와 Spring연동, Nginx로 React 연결 등을 차례 차례 진도 나간 후 맨 마지막에 전체를 docker compose로 구워버리는 실습을 진행한다고 하심.

학습목표

Spring Boot + MySQL 을 결합해서 실행시키는 것이 목표임.

(이때는 SpringBoot에 Mysql의 URL, ID, PW, PORT 정보가 필요하다.)

 

도커의 특성 리마인드 & 내부 네트워크의 장점

도커의 특성으로 JDK와 MySQL이 로컬에 설치되어있지 않아도 해당 Image를 다운로드 받아서 실행시켜버리면 되니까 매우 편리하다.

또한 도커 내부 네트워크를 만들어서 SpringBoot와 MySQL을 묶어놓으면 두 개의 독립적인 컨테이너는 서로 통신이 가능하게 된다.

외부 Volume을 만들어서 MySQL에 연결하여 MySQL Container와 독립적으로 작동하도록 해놓는 것도 잊지말자.

 

 

학습 준비

실습 디렉토리 : ex08

스프링 부트 GIT : git clone https://github.com/codingspecialist/docker-test-server.git

※ 우분투에서 처음 git clone을 했다면 로그인하라고 뜨는데 github id는 그대로 쓰고, pw는 personal token을 발급받아서 복사해주면 된다.

(settings > (사이드 메뉴의 맨마지막) Developer Settings > Personal access toekns)

 

1. docker-test-server  (Spring Boot)

 

[SpringBoot Server Dockerfile 작성] ( ~ex08/docker-test-server 디렉토리에 작성)

FROM openjdk:11-jdk-slim

WORKDIR /app

# COPY만 docker-compose 파일의 위치를 기반으로 작동함
# docker-test-server내부에 있는 모든 파일을 WORKDIR인 /app으로 COPY를 한다는 의미이다.
COPY . .

# RUN은 현재 파일의 위치를 기반으로 작동함
RUN chmod +x ./gradlew
RUN ./gradlew clean build

# build.gradle에 어떤 설정을 하면 .jar파일이 1개가 만들어진다. (원래는 2개만들어짐)
# 만들어진 jar파일의 이름을 app.jar 로 변경한다는 의미이다. (실행하기 편하게)
#ARG JAR_FILE=build/libs/*.jar
#COPY ${JAR_FILE} app.jar

# 로컬에 빌드된게 아니라 컨테이너 내부에서 빌드된거니까 위에있는 COPY를 쓰면 안되고 RUN으로 실행시켜
야한다.
ENV JAR_PATH=/app/build/libs
RUN mv ${JAR_PATH}/*.jar /app/app.jar

ENTRYPOINT ["java", "-jar","-Dspring.profiles.active=prod","app.jar"]

주석처리된 내용 중에 #build.gradle에 어떤 설정을하면 .jar파일이 1개만 만들어진다는 내용이 있는데

git clone받은 파일 중 build.gradle 내용 맨 마지막 내용을 보면

jar {
        enabled = false
}

이러한 내용이 있다. 해당 내용이 "프로젝트명-버전-plain.jar" 파일을 생성하지 않고 즉시 실행가능한 executable.jar파일("프로젝트명-버전.jar")만 생성 하게 하는 옵션이다. 해당 옵션을 사용하지 않으면 plain.jar, executable.jar 두개의 파일이 생성된다.

관련링크 : https://dev-j.tistory.com/22

 

Plain jar vs Executable jar(feat. plain jar 생성 방지)

스프링 부트 gradle 플러그인 2.5 버전부터 gradle 빌드 시 JAR 파일이 2개 생성된다. 별도의 설정을 하지 않았을 때 하나는 "프로젝트 이름-버전.jar", 다른 하나는 "프로젝트 이름-버전-plain.jar"이라는

dev-j.tistory.com

 

2. docker-test-db (MySQL)

아래의 내용들은 ~ex08/docker-tset-db 디렉토리에 작성 해야한다.

 

[init.sql 작성] 

init.sql은 Docker Container가 실행될 때 자동으로 해당 SQL을 실행시켜 DB 초기화를 진행시키기 위한 파일이다. (컨테이너를 내렸다가 다시 올려도 실행되는지는 확인해봐야함!)

CREATE TABLE user_tb(
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO user_tb (name) VALUES ('John');
INSERT INTO user_tb (name) VALUES ('Jane');

 

[MySQL Dockerfile 작성] 

FROM mysql:8.0

#docker-entrypoint-initdb.d로 복사 해준 sql은 자동으로 실행된다. (문서에 나와있다고함)
COPY init.sql /docker-entrypoint-initdb.d

ENV MYSQL_ROOT_PASSWORD=root1234
ENV MYSQL_DATABASE=metadb
ENV MYSQL_HOST=%

CMD ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]

 

 

3. docker-compose.yml 작성

docker-compose.yml파일은 ~ex08/docker-compose.yml 에 작성해주면 된다.

version: '3'

services:
  db:
    build:
      #context = Dockerfile의 위치-이걸 안잡아주면 COPY할 때 init.sql위치를 ex08(docker-compose.yml이 있는 곳)으로 봐버리는 문제가 생긴다.
      context: ./docker-test-db 
      dockerfile: Dockerfile
    ports:
      - 3306:3306
    volumes:
      - ./docker-test-db/store:/var/lib/mysql
    networks:
      - network

  server:
    build:
      context: ./docker-test-server
      dockerfile: Dockerfile
    restart: always
    ports:
      - 8080:8080
    depends_on:
      - db #db가 먼저 구축되고 나서 다 되면 server를 실행시키는 것을 의미한다.
    environment: #해당 값들은 application-prod.yml에서 ${SPRING_DATASOURCE_URL} 에서 사용한다.
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/metadb?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_DRIVER: com.mysql.cj.jdbc.Driver
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: root1234
    networks: #동일 네트워크로 잡아주어야 datasource url에서 jdbc:mysql://db 로 쓸수있는 것이다. ip 로 안쓰고..
      - network

networks:
  network:

db쪽에서 init.sql 을 실행시킬 때 강사님은 Dockerfile에서 "/docker-entrypoint-initdb.d" 경로로 COPY를 하였지만 다른 분은 docker-compose.yml에서

volumes:

  - "./init/:/docker-entrypoint-initdb.d/" 

이런식으로 하신분들도 있다.

 

4. 컨테이너 실행

docker compose up -d --build

docker compose up -d --build 를 해주면 다시 이미지까지 빌드된다. 

 

실습 디렉토리 : ex07/composetest

튜토리얼 사이트 : https://docs.docker.com/compose/gettingstarted/

 

Docker Compose Quickstart

Check out this tutorial on how to use Docker Compose from defining application dependencies to experimenting with commands.

docs.docker.com

3단계 까지만 진행했음.

 

1. 프로젝트에 대한 디렉토리를 만듭니다.

$ mkdir composetest
$ cd composetest

 

2. app.py프로젝트 디렉토리에 라는 파일을 만들고 다음 코드를 붙여넣습니다.

vi app.py

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

 

3. 프로젝트 디렉토리에 requirements.txt  파일을 만들고 다음 코드를 붙여넣습니다.

vi requirements.txt

flask
redis

 

 

4. 코드를 생성하여 Dockerfile다음 코드를 붙여넣으세요.

# syntax=docker/dockerfile:1
FROM python:3.10-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run", "--debug"]

 

이는 Docker에게 다음을 알려줍니다.

  • Python 3.10 이미지로 시작하여 이미지를 빌드합니다.
  • 작업 디렉토리를 .으로 설정합니다 /code.
  • 명령 에 사용되는 환경 변수를 설정합니다 flask.
  • gcc 및 기타 종속성 설치
  • requirements.txtPython 종속성을 복사 하고 설치합니다.
  • 컨테이너가 포트 5000에서 수신 중임을 설명하는 메타데이터를 이미지에 추가합니다.
  • .프로젝트의 현재 디렉토리를 .이미지의 작업 디렉토리로 복사합니다.
  • 컨테이너의 기본 명령을 .으로 설정합니다 flask run --debug.

 

5. docker-compose.yml 정의

services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"
  • 이 web서비스는 현재 디렉토리에 있는 Dockerfile이 빌드된 이미지를 사용합니다 
  • 그런 다음 컨테이너와 호스트 머신을 노출된 포트인 에 바인딩합니다. (8000(HOST) --> 5000(Container)) 5000포트는 flask의 기본 포트임.

6. 컨테이너 실행

docker compose up -d

 

H2 server에 접속해보면 잘 작동하는 것을 볼 수 있다.

redis에 잘 연결되어있으면 새로고침 할 때 마다 카운트가 올라감.

 

H2 server에 올라간 container flask에 접속한 화면

 

compose watch 부분은 강의 때 안 다뤄서 하지않았음. 필요하면 개인적으로 공부해야할듯!

+ Recent posts