ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Docker custom Image의 동작방식(소스코드에 변경사항이 있을 경우)
    Infra/컨테이너 2022. 8. 21. 10:54

    Container에서 실행하는 Application의 코드의 변경사항이 있을때

    const express = require("express");
    const bodyParser = require("body-parser");
    
    const app = express();
    
    let userGoal = "Learn Docker!";
    
    app.use(
      bodyParser.urlencoded({
        extended: false,
      })
    );
    
    app.use(express.static("public"));
    
    app.get("/", (req, res) => {
      res.send(`
        <html>
          <head>
            <link rel="stylesheet" href="styles.css">
          </head>
          <body>
            <section>
              <h2>My Course Goal</h2>
              <h3>${userGoal}</h3>
            </section>
            <form action="/store-goal" method="POST">
              <div class="form-control">
                <label>Course Goal</label>
                <input type="text" name="goal">
              </div>
              <button>Set Course Goal</button>
            </form>
          </body>
        </html>
      `);
    });
    
    app.post("/store-goal", (req, res) => {
      const enteredGoal = req.body.goal;
      console.log(enteredGoal);
      userGoal = enteredGoal;
      res.redirect("/");
    });
    
    app.listen(8080);
     <section>
          //<h2>My Course Goal</h2>
          <h2>My Course Goal!</h2>
          <h3>${userGoal}</h3>
     </section>​

    노드 Application 에서 코드를 변경하고 싶다고 가정하자 아래와 같이 <h2>의 tag의 문구를 변경하고 싶다고 가정하면 이것은 실행 중인 어플리케이션에 반영되어야 하는 HTML 코드에 대한 아주 작은 변경사항이다.

     

    Container 재실행

    docker run -p 7000:8080 f3e9418ecd233eb3c3ddaf5587da819587fa8771b0d377867e75e4caff46c940

    터미널에 위와 같은 명령어를 다시 실행하여 custom image를 기반으로 Container를 실행하면 노드 Application이 다시 실행된다.

     

     <section>
          //<h2>My Course Goal</h2>
          <h2>My Course Goal!</h2>
          <h3>${userGoal}</h3>
     </section>​

    하지만 브라우저를 통해 URL locahost:7000에 접속해도 <h2> tag에 대한 변동 사항은 적용되지 않았다. 이전 Container를 stop한 후에 Container를 다시 실행하기도 했는데 변경사항이 반영되지 않은 이유는 무엇일까?

     

    Image의 동작 방식

    이 이유를 알기위해서는 Image가 작동하는 방식을 이해해야한다. 위의 html은 노드 Application에 일부분인 소스코드이다. 우리는 그 코드로 무엇을 하고있을까?

     

    FROM node
    
    WORKDIR /app
    
    COPY . /app
    
    RUN npm install
    
    EXPOSE 8080
    
    CMD node server.js

    다시 Dockerfile을 보면, 도커에게 local 환경에 존재하는 코드를 담고 있는 파일들과 폴더들을 Docker Container의 파일 시스템에 app 폴더에 복사하도록(COPY) 지시한다.

     

    여기서 중요한 일을 한가지 하는데 소스코드(파일과 폴더드를 통해) Image에 복사하고, 그 복사한 시점에서 소스코드의 스냅샷을 만든다. 

     

     server.js파일에서 <h2> tag를 변경하는 것 과 같이 스냅샷이 이미 만들어진 이후에 해당 file에 소스 코드를 편집하면 그 변경사항은 Image 소스코드에 반영되지 않는다.

     

    업데이트된 소스 코드를 실행한 Conatainer에 반영하고 싶으면 수정된 소스코드를 바탕으로 Image를 다시 build해야한다. 이것은 매우 주요한 포인트이다. 코드를 변경할 때마다 Image를 다시 작성해야 하는 것이 이상하고 번거로울 수 있다. 하지만 이 문제를 해결 할 좋은 대안이 존재한다. 하지만 지금은 여기서 시사하는 바의 핵심을 이해하는 것이 중요하다.

     

    Image는 기본적으로 잠겨있다 즉 일단 build되면 끝이라는 것이다. Image의 모든 것이 읽기 전용이며 과거에 어떤 특정 순간에 소스코드를 COPY했기 때문에 단순히 loca컴퓨터에서 복사당한 원본 코드를 업데이트하여 이미 build되 Image의 코드를 편집할 수는 없다.

     

    Image에 COPY되 코드는 local의 원본 코드와 연동이 되지 않는다. Image build가 끝나고 나서 원본코드에는 얼마든지 수정 사항이 있을 수 있다. 심지어 원본 코드가 삭제 될 수도 있지만. 이미 build된 이미지는 이것에 영향을 받지 않는다.

     

    정리하자면 소스코드에 변경사항을 실행할 Container에 반영하고 싶다면 수정된 소스코드를 기반으로 터미널에서 명령어 docker build . 를 다시 실행하여 또 다른 custom image를 만들어야 한다.

     

    이제 새로 만들어진 custom image를 사용해서 Container를 실행하고 브라우저를 통해 localhodt:7000에 접속하면

    <2h> tag의 변경사항이 반영된 것을 확인 할 수 있다.

     

    정리

    Dockerfile의 명령어들은 custom image를 buil하기 위해 실행되고, 그 후에는 잠겨서 완료된다. 그리고 그 이후에는 custom image build에 사용된 원본 소스코드를 변경해도 image에는 아무런 영향을 끼치지 않는다.

    'Infra > 컨테이너' 카테고리의 다른 글

    Docker Image와 Comtainer 관리  (0) 2022.08.22
    Docker Layer를 기반으로 하는 아키텍쳐 Image  (0) 2022.08.21
    Docker Custom Image  (0) 2022.08.20
    Docker Finding/Creating Images 2  (0) 2022.08.20
    Docker Finding/Creating Images 1  (0) 2022.08.19

    댓글

Designed by Tistory.