<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>오딩이</title>
    <link>https://odingcoding.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 7 Jul 2026 17:26:46 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>오딩이</managingEditor>
    <image>
      <title>오딩이</title>
      <url>https://tistory1.daumcdn.net/tistory/5303064/attach/b13f396d859543efb0ff67a6f28445eb</url>
      <link>https://odingcoding.tistory.com</link>
    </image>
    <item>
      <title>[BE] @Controller와 @RestController의 차이</title>
      <link>https://odingcoding.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지원중인 프로젝트들을 보면,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사의 중대하고 막대한 프로젝트들은 당연히 BE/FE 나누어 개발을 하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아주 소소한, 조마난 플젝들은 굳이 BE/FE를 나누지 않고 여전히 JSP, Timeleaf등을 많이 사용하고 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 백 코드를 @RestController를 써야할지, @Controller를 써야할지 여쭤보시는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 어디에 뭘 어떻게 쓴다만 알지 내부 구조를 자세하기 알진 못해서 알아봄&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;@Controller vs @RestController, 상황별 선택 가이드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 두 응답의 목적은?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- @Controller (View 기반) : 전통적인 Spring MVC의 컨트롤러. 주로 View(화면)을 반환하기 위해 사용한다. 메서드가 String을 반환하면 View Resolver가 해당 이름의 뷰 파일(JSP, HTML 등)을 찾아 렌더링한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- @RestController (Data 기반): @Controller에 @ResponseBody가 결합된 형태. View를 찾지 않고, 반환하는 객체(DTO, Map 등)을 JSON이나 XML같은 데이터 형식으로 직접 응답 본문에 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. FE 기술별 최적의 조합&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Case A : JSP나 Thymeleaf를 사용하는 경우 (Server-Side Rendering)&lt;/span&gt;&lt;br /&gt;이 방식은 서버에서 이미 HTML을 다 만들어서 보내주는 방식임.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;권장 선택 : @Controller&lt;/li&gt;
&lt;li&gt;이유 : 컨트롤러에서 데이터를 Model 객체에 담아 뷰 템플릿으로 전달해야 하기 때문임&lt;/li&gt;
&lt;li&gt;주의사항 : 만약 JSP화면 안에서 특정 부분만 비동기(Ajax)로 데이터를 가져오고 싶다면, 해당 메서드에만 @ResponseBody를 붙이거나 별도의 @RestController를 만들어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1773060321029&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Controller
public class ViewController {
    @GetMapping(&quot;/home&quot;)
    public String homePage() {
        return &quot;home&quot;; // home.jsp 파일을 찾아가라는 뜻!
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Case B : React, Vue, Angular를 사용하는 경우 (Client-Side Rendering)&lt;/span&gt;&lt;br /&gt;서버는 데이터만 던져주고, 화면은 브라우저(프론트엔드)가 그리는 방식
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;권장 선택 : @RestController&lt;/li&gt;
&lt;li&gt;이유 : 현대적인 웹 아키텍처에서는 서버와 클라이언트를 완전히 분리함. 서버는 순수하게 비즈니스 로직과 데이터(JSON) 제공에만 집중하는 REST API 서버 역할을 수행해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1773060351636&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@RestController
@RequestMapping(&quot;/api/users&quot;)
public class UserApiController {
    @GetMapping(&quot;/{id}&quot;)
    public UserDto getUserInfo(@PathVariable String id) {
        return userService.findById(id); // { &quot;name&quot;: &quot;Hyerin&quot;, &quot;role&quot;: &quot;Dev&quot; } 같은 데이터만 감!
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 유연성을 고려해야 함&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 트렌드는 화면 제어와 데이터 제공을 철저히 분리하는 것임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 프로젝트 초기라 JSP를 쓰고 있더라도, 나중에 모바일 앱이나 React로 확장할 계획이 있다면 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;처음부터 API 전용 컨트롤러(@RestController)와 화면 전용 컨트롤러(@Controller)를 패키지 단계부터 분리&lt;/span&gt;해 두는 것이 유지보수에 훨씬 유리함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, @RestController를 사용하면 공통 응답 객체(Common Response)를 만들어 에러 코드나 메시지 형식을 표준화하기가 매우 수월해짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;@Controller 구조도&lt;/h3&gt;
&lt;pre id=&quot;code_1773061216229&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[ Client ] ──(1) Request──▶ [ Dispatcher Servlet ]
                                   │
      ┌────────────────────────────┴────────────────────────────┐
      │ (2) Handler Mapping 조회                                 │ (3) Controller 결정
      ▼                                                         ▼
[ Handler Mapping ]                                     [ Handler Adapter ]
                                                                │
      ┌─────────────────────────────────────────────────────────┴────────────────┐
      │ (4) 비즈니스 로직 실행                                                    │ (5) View Name 반환
      ▼                                                                          ▼
[ @Controller ] ──▶ [ Service ] ──▶ [ DB ]                      [ Dispatcher Servlet ]
                                                                         │
      ┌──────────────────────────────────────────────────────────────────┴───────┐
      │ (6) 화면 탐색 요청                                                        │ (7) 실제 View 파일 반환
      ▼                                                                          ▼
[ View Resolver ]                                                      [ View (JSP/HTML) ]
                                                                         │
[ Client ] ◀──(8) Response (HTML 완성본) ──────────────────────────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;@RestController 구조도&lt;/h3&gt;
&lt;pre id=&quot;code_1773061342574&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[ Client ] ──(1) Request──▶ [ Dispatcher Servlet ]
                                   │
      ┌────────────────────────────┴────────────────────────────┐
      │ (2) Handler Mapping 조회                                 │ (3) Controller 결정
      ▼                                                         ▼
[ Handler Mapping ]                                     [ Handler Adapter ]
                                                                │
      ┌─────────────────────────────────────────────────────────┴────────────────┐
      │ (4) 비즈니스 로직 실행                                                    │ (5) 객체(DTO) 반환
      ▼                                                                          ▼
[ @RestController ] ──▶ [ Service ] ──▶ [ DB ]                  [ Dispatcher Servlet ]
                                                                         │
      ┌──────────────────────────────────────────────────────────────────┴───────┐
      │   핵심: ViewResolver 대신 가동                                           │ (7) 변환 데이터 수신
      ▼                                                                          ▼
[ HttpMessageConverter ] ──(6) JSON으로 직렬화 (Serialization) ─────────────▶ [ Dispatcher Servlet ]
                                                                         │
[ Client ] ◀──(8) Response (JSON Data) ───────────────────────────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;JSP와 @RestController의 협업: 비동기 데이터 업데이트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JQuery의 Ajax 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 화면은 @Controller가 열어주고, 데이터는 @RestController가 배달한다는 분업 특징이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 백엔드 구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 화면을 보여주는 컨트롤러와 데이터를 처리하는 API 컨트롤러를 나눔&lt;/p&gt;
&lt;pre id=&quot;code_1773061803720&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 화면담당 (ViewController.java)

@Controller
public class ViewController {
    @GetMapping(&quot;/user-page&quot;)
    public String userPage() {
        return &quot;userView&quot;; // userView.jsp를 호출하여 전체 화면을 그림
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1773061824768&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 데이터 담당 (UserApiController.java)

@RestController
@RequestMapping(&quot;/api/v1&quot;)
public class UserApiController {
    @GetMapping(&quot;/users/{id}&quot;)
    public UserDto getUserInfo(@PathVariable String id) {
        // 비즈니스 로직 실행 후 객체 반환 (자동으로 JSON 변환됨)
        return new UserDto(id, &quot;Hyerin&quot;, &quot;Software Developer&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 프론트엔드 구성 (userView.jsp)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSP 안에서 버튼을 클릭했을 때, 페이지 새로고침 없이 서버에서 데이터만 쏙 가져오는 Ajax 코드&lt;/p&gt;
&lt;pre id=&quot;code_1773061864248&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h2&amp;gt;사용자 정보 조회&amp;lt;/h2&amp;gt;
    &amp;lt;input type=&quot;text&quot; id=&quot;userId&quot; placeholder=&quot;아이디 입력&quot;&amp;gt;
    &amp;lt;button id=&quot;fetchBtn&quot;&amp;gt;정보 가져오기&amp;lt;/button&amp;gt;

    &amp;lt;div id=&quot;resultArea&quot; style=&quot;margin-top: 20px; border: 1px solid #ccc;&quot;&amp;gt;
        &amp;lt;p&amp;gt;이름: &amp;lt;span id=&quot;userName&quot;&amp;gt;-&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;직무: &amp;lt;span id=&quot;userRole&quot;&amp;gt;-&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;script&amp;gt;
        $('#fetchBtn').click(function() {
            const id = $('#userId').val();

            // @RestController로 데이터 요청
            $.ajax({
                url: '/api/v1/users/' + id,
                type: 'GET',
                success: function(data) {
                    // 데이터만 받아서 특정 부분만 업데이트!
                    $('#userName').text(data.name);
                    $('#userRole').text(data.role);
                },
                error: function() {
                    alert('사용자를 찾을 수 없습니다.');
                }
            });
        });
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/BackEnd</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/67</guid>
      <comments>https://odingcoding.tistory.com/67#entry67comment</comments>
      <pubDate>Mon, 9 Mar 2026 22:16:53 +0900</pubDate>
    </item>
    <item>
      <title>[BE] Java 8에서 21로</title>
      <link>https://odingcoding.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 올 해 프로젝트로 Java 8버전에서 21로 올리는 프로젝트가 뜬다고 한다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Java8을 아직도 쓰는것도 놀라운데 이 프로젝트에 참여할 수도 있다는게 놀라움&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Java 8에서 21로 : 현대적 자바로의 대도약&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. Virtual Threads: 동시성 프로그래밍의 혁명 (Java 21)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가장 파급력이 큰 변화다. 기존 자바의 스레드(PlatformThread)는 OS 스레드와 1:1로 매핑되어 생성 비용이 비싸고 개수도 제한적이었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Java 8 : 요청 하나 당 스레드 하나를 할당하다보니, I/O 작업(DB 조회, API호출) 시 스레드가 차단되어 자원이 낭비되었음. 이를 해결하려면 복잡한 비동기 프로그래밍(WebFlux 등)이 강제되었다.&lt;/li&gt;
&lt;li&gt;Java 21 : 수백만 개의 Virtual Thread를 생성할 수 있다. I/O 차단이 발생하면 JVM이 해당 가상 스레드를 대기 상태로 돌리고, 실제 OS 스레드에서는 다른 가상 스레드를 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[코드 예시 : 가상 스레드 생성]&lt;/p&gt;
&lt;pre id=&quot;code_1770362965621&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 방식 : 플랫폼 스레드 생성 (제한적)
Thread.ofPlatform().start(() -&amp;gt; System.out.println(&quot;Platform Thread&quot;));

// Java 21 방식 : 가상 스레드 생성 (수백만 개 가능)
Thread.ofVirtual().start(() -&amp;gt; {
  System.out.println(&quot;Virtual Thread 시작&quot;);
});

// 스레드 풀 없이도 처리량이 폭발적으로 증가함
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
  IntStream.range(0, 10_000).forEach(i -&amp;gt; {
    executor.submit(() -&amp;gt; {
      Thread.sleep(Duration.ofSeconds(1));  // I/O 시뮬레이션
      return i;
    });
  });
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Record &amp;amp; Pattern Matching : 간결하고 안전한 코드 (Java 14~21)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java8에서는 데이터 객체(DTO)를 하나 만들려면 수십 줄의 Boilerplate 코드가 필요했다. 이제는 '언어 차원'에서 이를 해결한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Record: 불변 데이터를 저장하기 위한 특별한 클래스.&lt;br /&gt;필드, 생성자, getter, equals, hashCode, toString을 컴파일러가 자동으로 생성함.&lt;/li&gt;
&lt;li&gt;Pattern Matching: instanceof로 타입을 확인한 뒤 강제 형변환(Casting)을 하던 번거로움이 사라짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[코드 예시: Before vs After]&lt;/p&gt;
&lt;pre id=&quot;code_1770366788700&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Java 8 방식 (Lombok 의존 또는 수기작성)
public class User {
  private final String name;
  private final int age;
}

// Java 21 방식 (Record + Pattern Maching)
// 단 한 줄로 데이터 객체 정의
public record User(String name, int age) {}

public void process(Object obj) {
  // 1. Pattern Matching for instanceof: 타입 체크와 변수 선언을 동시에
  if (obj instanceof User user) {
    System.out.println(&quot;이름: &quot;+user.name());  //user로 바로 접근
  }
  
  // 2. Switch Pattern Matching: switch문에서 복잡한 조건 처리
  String result = switch (obj) {
    case User u &amp;amp;&amp;amp; u.age() &amp;gt; 18 -&amp;gt; &quot;성인 유저: &quot;+u.name();
    case User u -&amp;gt; &quot;미성년 유저&quot;;
    case String s -&amp;gt; &quot;문자열 데이터: &quot;+s;
    default -&amp;gt; &quot;알 수 없는 타입&quot;;
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Text Blocks: 가독성의 비약적 향상 (Java 15)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON이나 SQL을 자바 코드에 작성할 때 더 이상 문자열 더하기(+)와 탈출 문자(\n, \&quot;)로 고통받지 않아도 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[코드 예시: JSON 쿼리]&lt;/p&gt;
&lt;pre id=&quot;code_1770366890472&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Java 8: 읽기 힘들고 수정하기 어려움
String json8 = &quot;{\n&quot; +
               &quot;  \&quot;name\&quot;: \&quot;Gemini\&quot;,\n&quot; +
               &quot;  \&quot;version\&quot;: \&quot;21\&quot;\n&quot; +
               &quot;}&quot;;

// Java 21: 실제 데이터 모습 그대로 작성
String json21 = &quot;&quot;&quot;
    {
      &quot;name&quot;: &quot;Gemini&quot;,
      &quot;version&quot;: &quot;21&quot;
    }
    &quot;&quot;&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 실무 대응 전략&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Jakarta EE 전환 : Spring Boot 3.0(Java 17+)부터는 javax.* 패키지를 더 이상 지원하지 않는다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;javax.persistence.* -&amp;gt; jakarta.persistence.*&lt;/li&gt;
&lt;li&gt;javax.servlet.* -&amp;gt; jakarta.servlet.*&lt;/li&gt;
&lt;li&gt;단순 텍스트 치환이 아닌, 설정 파일 이슈가 있으므로 검토 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;G1 GC 최적화 : Java 8의 기본 GC인 Parallel GC는 처리량 중심이다. Java 21의 기본 G1 GC는 응답 시간 조절에 최적화 되어있음. 메모리 설정(-Xms, -Xmx)외에도 GC옵션이 많이 변했으므로 부하 테스트가 필수다&lt;/li&gt;
&lt;li&gt;의존성(Library)의 호환성 :&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Lombok: 최소 1.18.30 이상 권장&lt;/li&gt;
&lt;li&gt;QueryDSL: 5.0 이상 필수 및 jakarta 패키지 설정 확인.&lt;/li&gt;
&lt;li&gt;Hibernate: 6.x 버전으로 업그레이드 되면서 Dialect 설정 방식이 변함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Spring Boot 3.2+ 필수 : Java 21의 가상 스레드를 온전히 지원하려면 최소 Spring Boot 3.2이상을 써야함&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;설정 한 줄로 성능 최적화: 가상 스레드를 사용하기 위해 복잡한 빈 설정 대신, application.yml에 설정 한 줄만 추가하면 톰캣이 가상 스레드 기반으로 동작함&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1770630405938&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  threads:
    virtual:
      enabled: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GraalVM Native Image 지원: SpringBoot 3부터는 JVM 없이 실행 가능한 네이티브 이미지를 공식 지원한다. 시작 속도가 0.1초대로 줄어들어 Serverless(AWS Lamda 등) 환경에서 Java8 대비 압도적인 우위를 점한다.&lt;/li&gt;
&lt;li&gt;Gradle 버전 업그레이드: Java21을 지원하려면 Gradle 8.5 이상이 필수임 (현재 7.6.4)&lt;br /&gt;Java 8시절의 compile, testCompile같은 문법은 이미 제거되었으므로 implementation, api로 완전히 전환해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 이 외 기타&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Sequenced Collections (Java 21):&lt;br /&gt;List, Set의 마지막 요소를 가져오기 위해 list.get(list.size() - 1) 대신 list.getFirst(), list.getLast() 사용 가능&lt;/li&gt;
&lt;li&gt;collect(Collectors.toList()) -&amp;gt; .toList()&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/BackEnd</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/66</guid>
      <comments>https://odingcoding.tistory.com/66#entry66comment</comments>
      <pubDate>Mon, 9 Feb 2026 18:54:11 +0900</pubDate>
    </item>
    <item>
      <title>[BE] 스프링 IoC와 DI | 스프링 생명주기 | @Autowired와 getBean()</title>
      <link>https://odingcoding.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;면접 준비할 때 미리 준비 안 해가면 항상 질문 나오는 스프링 IoC와 DI&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 프레임워크팀에서 백엔드 개발을 하면서 항상 고려해야 하는 개념이지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접에서 물어보면 이게 그렇게 답변하기가 힘들드라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외우는 방식 말고 이해할 수 있게 작성하는 글&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️ Spring의 IoC와 DI 개념&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 프레임워크를 지탱하는 가장 거대한 뿌리, IoC(Inversion of Control)와 DI(Dependency Injection)에 대해 알아본다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 개념들을 제대로 이해하면 &quot;왜 스프링을 써야 하는가?&quot;에 대한 답을 찾을 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;IoC&lt;/b&gt; (Inversion of Control, 제어의 역전)&lt;/span&gt; : 내가 직접 관리하던걸 프레임워크가 대신 관리해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;DI&lt;/b&gt; (Dependency Injection, 의존성 주입) &lt;/span&gt;: 필요한 부품을 내가 만들지 않고 외부에서 넣어줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일상 비유로 보는 IoC와 DI&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 상황1) 내가 직접 요리하기 (기존방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 배가 고픈 당신은 파스타를 만들기로 한다. 마트에 가서 면과 소스를 직접 고르고, 냄비를 꺼내 물을 끓인다. 모든 재료의 선택과 조리 과정의 주도권은 당신(개발자)에게 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 상황2) 레스토랑에서 주문하기 (IoC/DI방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 당신은 레스토랑에 앉아 &quot;파스타 하나 주세요&quot;라고 주문한다. 주방장(Spring Container)이 알아서 좋은 면과 소스를 골라 요리한 뒤 당신의 테이블에 내어준다. 당신은 재료가 어디서 왔는지 신경 쓸 필요 없이, 만들어진 파스타를 먹기만 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;IoC (Inversion of Control, 제어의 역전)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IoC는 말 그대로 프로그램의 제어 흐름을 개발자가 직접 관리하는 것이 아니라, &lt;b&gt;외부(프레임워크)에 맡기는 것&lt;/b&gt;을 의미한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 : 개발자가 New Service()를 호출하여 객체를 직접 생성하고 관리함&lt;/li&gt;
&lt;li&gt;IoC : 객체의 생성부터 생명주기 관리까지 모두 Spring Container가 담당함&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;핵심 오브젝트 : Bean과 컨테이너&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Bean : 단순한 객체가 아님. 스프링이 직접 생성하고, 의존관계를 설정하며, 주입까지 담당하는 애플리케이션의 최소 단위&lt;/li&gt;
&lt;li&gt;ApplicationContext : '빈 공장(BeanFactory)'의 확장판으로, 스프링에서 IoC를 담당하는 핵심 컨테이너. 어떤 객체를 생성하고 연결할지 결정하는 '지휘자'의 역할을 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;DI (Dependency Injection, 의존성 주입)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IoC가 '제어권을 넘기는 현상'이라면, &lt;b&gt;DI는 그 현상을 구현하는 실제 기법이다.&lt;/b&gt; 클래스 사이의 의존 관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 어떻게 활용될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 권장되는 방식은 생성자 주입(Constructor Injection)이다.&lt;/p&gt;
&lt;pre id=&quot;code_1768056026291&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Service
public class OrderService {
  private final DiscountPolicy discountPolicy;
  
  // 생성자를 통해 외부(스프링)에서 의존성을 주입해줌
  @Autowired
  public OrderService(DiscountPolicy discoutPolicy) {
    this.discountPolicy = discountPolicy;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;getBean()과 IoC 오브젝트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 컨테이너가 관리하는 객체를 사용하고 싶을 때 개발자는 ApplicationContext에서 객체를 꺼내온다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getBean() : 컨테이너에서 관리 중인 특정 빈을 이름이나 타입으로 찾아오는 메서드&lt;/li&gt;
&lt;li&gt;하지만 실제 개발 시에는 @Autowired를 통해 자동으로 주입받으므로, getBean()을 직접 호출하는 경우는 드물다&lt;br /&gt;(&amp;rarr; 안정성을 생각하면 getBean() 방식이 더 좋은 거 아닌가 ???? )&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;Spring의 생명주기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링의 생명주기는 IoC컨테이너라는 주방에서 재료(Bean)가 준비되고, 요리되어 손님에게 나가고, 나중에 뒷정리되는 전체 과정이라고 이해한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 new로 직접 객체를 만들면 생성과 동시에 끝이지만, 스프링이 관리하면 &quot;태어나서 죽을 때까지&quot; 정해진 절차를 따르게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 [생성 &amp;rarr; 설정 &amp;rarr; 사용 &amp;rarr; 소멸]의 단계를 밟는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① &lt;b&gt;스프링 컨테이너 생성&lt;/b&gt; : ApplicationContext가 만들어진다.&lt;br /&gt;② &lt;b&gt;스프링 빈 생성&lt;/b&gt; : 설정 정보를 보고 클래스의 인스턴스를 생성한다 (생성자 주입은 이 단계에서 발생)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ &lt;b&gt;의존관계 주입&lt;/b&gt; : @Autowired 같은 의존성들을 연결해준다. (수정자/필드 주입)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;④ &lt;b&gt;초기화 콜백&lt;/b&gt; : 빈이 준비되었음을 알리고 필요한 설정을 마친다. (&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;@PostConstruct&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⑤ &lt;b&gt;사용&lt;/b&gt; : 애플리케이션에서 빈을 가져와 로직을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⑥ &lt;b&gt;소멸 전 콜백&lt;/b&gt; : 컨테이너가 종료되기 직전, 자원을 반납하는 등 정리 작업을 한다. (&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;@PreDestroy&lt;/span&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⑦ &lt;b&gt;스프링 종료&lt;/b&gt; : 빈과 컨테이너가 소멸한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 단순히 객체가 &lt;b&gt;생성&lt;/b&gt;되는 것과 서비스가 &lt;b&gt;준비되는&lt;/b&gt; 것은 다르다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기화(Initialize) : 데이터베이스 커넥션 풀을 미리 연결해 두거나, 외부 서버와 소켓을 열어두는 등 무거운 작업은 객체 생성이 끝난 후 의존관계가 다 맺어진 뒤에 수행해야 안전하다.&lt;/li&gt;
&lt;li&gt;소멸(Destroy) : 애플리케이션이 꺼질 때 열려있던 파일이나 DB 연결을 안전하게 닫아줘야 데이터 손실을 막을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 과거 복잡한 인터페이스를 직접 구현하는 대신, @PostContruct @PreDestroy 어노테이션으로 끝낸다&lt;/p&gt;
&lt;pre id=&quot;code_1768057922162&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class NetworkClient {
  
  private String url;
  
  public NetworkClient() {
    System.out.println(&quot;1. 생성자 호출: 아직 URL이 없음&quot;);
  }
  
  public void setUrl(String url) {
    this.url = url;
  }
  
  // 초기화 콜백 : 의존관계 주입이 모두 끝난 뒤 호출함
  @PostConstruct
  public void init() {
    System.out.println(&quot;2. 초기화: &quot;+url+&quot; 서버에 연결을 시도&quot;);
  }
  
  // 소멸 전 콜백 : 컨테이너가 종료되기 직전에 호출됨
  @PreDestroy
  public void close() {
    System.out.println(&quot;3. 소멸 : 서버 연결을 안전하게 종료&quot;);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드를 통해 알 수 있는 IoC와 DI&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 왜 @PostConstruct가 IoC의 증거인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IoC의 핵심은 &quot;내가 호출하는 게 아니라, 프레임워크가 나를 호출하는 것&quot;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반적인 자바 코드 : 내가 new로 객체를 만들고, 바로 다음 줄에 myObject.init()을 직접 호출해야 한다. 호출 시점을 내가 결정해야 함&lt;/li&gt;
&lt;li&gt;스프링의 @PostConstruct : 개발자는 &quot;이 메서드는 준비가 끝나면 실행해 줘&quot;라고 표시(Annotation)만 해둔다. 실제 호출을 스프링 컨테이너가 적절한 시점(의존성 주입이 완료된 직후)에 알아서 실행한다.&lt;br /&gt;&lt;br /&gt;즉, 실행 순서에 대한 제어권이 스프링에게 넘어갔기 때문에 전형적인 IoC의 모습인 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) DI(의존성 주입)과의 관계는?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@PostConstruct가 의미 있는 이유는 바로 DI 때문이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체가 막 생성된 시점(new 직후)에는 아직 의존성(@Autowired로 붙인 객체들)이 주입되지 않았을 수 있다.&lt;/li&gt;
&lt;li&gt;만약 주입되지도 않은 객체를 사용해 초기화 로직을 실행하면 NullPointerException이 발생하겠지?&lt;/li&gt;
&lt;li&gt;스프링은 DI를 완벽하게 끝마친 직후에 @PostConstruct가 붙은 메서드를 실행해 준다&lt;br /&gt;&lt;br /&gt;&quot;필요한 모든 재료(DI)를 다 갖다 줄 테니, 이제 요리(초기화)를 시작해&quot;라고 스프링이 신호를 주는 셈이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;IoC와 DI의 장단점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① 결합도 감소 : 객체 간의 결합도가 낮아져 한 클래스를 수정해도 다른 클래스에 미치는 영향이 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② 유연성 및 확장성 : 코드 수정 없이 설정만으로 구현체를 갈아 끼울 수 있다 (ex. DB 변경)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;③ 테스트 용이성 : 가짜 객체(Mock)를 주입하기 쉬워 단위 테스트가 수월해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;① 복잡도 증가 : 작은 프로젝트에서는 오히려 구조가 복잡해 보일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;② 런타임 에러 : 의존성 주입이 잘못된 경우 컴파일 시점이 아닌 실행 시점에 에러가 날 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IoC와 DI는 결국 &quot;나 대신 누군가 객체를 관리하게 함으로써, 개발자는 비즈니스 로직에만 집중하겠다&quot;는 목적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IoC는 전략(목적)이고, DI는 그 전략을 수행하는 방법(수단)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✔️&lt;span&gt;&amp;nbsp;&lt;/span&gt;Ps. @Autowired 방식과 getBean()의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 실패시점의 차이 (Fail-Fast 원칙)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Autowired (사전주입) : 애플리케이션이 서버가 뜰 때(기동 시점) 모든 부품을 조립해본다. 이 때 부품이 없으면 서버가 아예 안뜬다.&lt;/li&gt;
&lt;li&gt;getBean() (지연조회) : 서버는 잘 뜨지만, 사용자가 특정 기능을 클릭해서 실제 로직이 돌아가는 시점(런타임)에 갑자기 에러가 나며 서비스가 멈춘다.&lt;br /&gt;&lt;br /&gt;&amp;rarr;  결론 : 새벽 3시에 사용자가 결제 버튼을 눌렀을 때 서버가 터지는 것보다, 개발자가 배포하는 순간 &quot;부품이 없어서 배포 안됨&quot;이라고 알려주는 것이 훨씬 안전한 설계이지 않을까? 이를 Fail-Fast(빨리 실패하기) 전략이라고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 객체지향 설계와 침투적 코드&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;침투적 코드 : getBean()을 쓰려면 코드 안에 ApplicationContext라는 스프링의 핵심 클래스가 직접 등장해야 한다. 내 비즈니스 로직이 스프링이라는 프레임워크에 너무 깊게 의존하게 됨&lt;/li&gt;
&lt;li&gt;비침투적 코드 (POJO) : @Autowired나 생성자 주입을 쓰면, 내 코드는 스프링 없어도 그냥 자바 객체로 동작할 수 있다. 스프링은 단지 밖에서 부품을 넣어줄 뿐이니까&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 의존성 시각화와 누락 방지&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Autowired를 사용하면 클래스 상단이나 생성자만 봐도 &quot;아, 이 클래스는 A와 B가 있어야 돌아가는구나&quot;를 한 눈에 알 수 있다.&lt;/li&gt;
&lt;li&gt;getBean()을 코드 곳곳에 숨겨두면, 어떤 의존성이 필요한지 파악하기 어렵고, 실수로 빈 설정을 누락할 확률이 높아진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 그냥 딱봐도 @Autowired방식이 더 안정적인 것 같은데 ,, 진짜 속도 하나때문에 getBean() 방식을 선택한건진 의문이다&lt;br /&gt;쫌 더 알아봤더니 내가 &quot;프레임워크&quot; 개발을 하는 특수한 상황이라 getBean()을 사용했던걸지도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;프레임워크 팀이 getBean()을 선택한 합리적인 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 선택적 의존성 (Optional Dependency)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임워크는 수많은 기능을 제공하지만, 각 업무팀은 그 중 일부만 사용할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Autowired : 서비스가 뜰 때 모든 빈을 조립하려 하므로, 업무팀이 특정 기능을 안써서 관련 라이브러리를 빼버리면 서버 기동시 에러가 난다.&lt;/li&gt;
&lt;li&gt;getBean() : 실제 그 기능을 호출할 때만 빈을 찾는다. 업무팀이 해당 기능을 안쓴다면, 관련 빈이 컨테이너에 없어도 서버는 아무 문제 없이 잘 뜬다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 순환 참조(Circular Dependency) 예방&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대규모 프레임워크는 기능이 워낙 방대해서 A 기능이 B를 참조하고, B가 다시 A를 참조하는 '순환 참조' 구조가 발생하기 쉽다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Autowired는 서버가 뜰 때 조립을 시도하므로 순환 참조가 있으면 기동 자체가 안된다.&lt;/li&gt;
&lt;li&gt;getBean()은 호출 시점에 빈을 찾으므로, 조립 시점의 순환 참조 문제를 회피할 수 있어 거대 프레임워크의 복잡한 구조를 관리하기에 유리하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 동적 빈 결정 (Dynamic Strategy)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임워크는 상황에 따라 실행 시점에 어떤 구현체를 쓸지 결정해야 할 때가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 설정 파일 값에 따라 A_SESSION_WAS를 쓸지, B_SESSION_REDIS를 쓸지 분기해야 한다면, 코드가 실행되는 도중에 getBean(beanName)을 호출하는 방식이 훨씬 직관적이고 강력하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/BackEnd</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/65</guid>
      <comments>https://odingcoding.tistory.com/65#entry65comment</comments>
      <pubDate>Sun, 11 Jan 2026 00:30:13 +0900</pubDate>
    </item>
    <item>
      <title>[BE] 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 Ch03</title>
      <link>https://odingcoding.tistory.com/64</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;주니어백엔드개발자표지.jpg&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs9H1E/dJMcagcNjuS/BcwUfWuTlymlzaJdXj1U3k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs9H1E/dJMcagcNjuS/BcwUfWuTlymlzaJdXj1U3k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs9H1E/dJMcagcNjuS/BcwUfWuTlymlzaJdXj1U3k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs9H1E%2FdJMcagcNjuS%2FBcwUfWuTlymlzaJdXj1U3k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;395&quot; data-filename=&quot;주니어백엔드개발자표지.jpg&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;Chapter3. 성능을 좌우하는 DB 설계와 쿼리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;조회 트래픽을 고려한 인덱스 설계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;풀 스캔이 발생하지 않도록 하려면 조회 패턴을 기준으로 인덱스를 설계해야 한다.&lt;/li&gt;
&lt;li&gt;엘라스틱서치 같은 검색 엔진을 사용하면 DB를 사용하지 않고 검색 기능을 구현할 수 있다.&lt;/li&gt;
&lt;li&gt;인덱스는 단일 인덱스로도 사용 가능하고 필요하다면 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;복합 인덱스&lt;/span&gt;도 가능하다.&lt;br /&gt;ex) 단일인덱스 : userId만 인덱스로 사용&lt;br /&gt;ex) 복합인덱스 : (userId, activityDate)를 인덱스로 사용&lt;/li&gt;
&lt;li&gt;인덱스를 생성할 때는 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;선택도&lt;/span&gt;가 높은 칼럼을 골라야 한다.&lt;br /&gt;ps) 선택도? 인덱스에서 특정 칼럼의 고유한 값 비율 (선택도&amp;uarr; = 해당 칼럼에 고유한 값이 많음)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;커버링 인덱스&lt;/span&gt; : 특정 쿼리를 실행하는 데 필요한 칼럼을 모두 포함하는 인덱스&lt;br /&gt;ex) 아래 쿼리는 실제 데이터에 접근하지 않음.&lt;br /&gt;select activityDate, activityType&lt;br /&gt;from activityLog&lt;br /&gt;where activityDate = '2024-07-31' and activityType='VISIT';&lt;/li&gt;
&lt;li&gt;효과가 적은 인덱스를 추가하면 오히려 성능이 나빠질 수 있다.&lt;br /&gt;인덱스는 조회 속도를 빠르게 해 주지만 데이터 추가, 변경, 삭제 시에는 인덱스 관리에 따른 비용(시간이) 추가되기 때문이다.&lt;br /&gt;인덱스가 많아질수록 메모리와 디스크 사용량도 함께 증가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;몇 가지 조회 성능 개선 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 미리 집계하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;count나 sum과 같은 집계 쿼리를 조회 시점에 실행하면 성능 문제가 발생한다 (like 서브쿼리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 집계 데이터는 미리 계산해서 별도 칼럼에 저장해서 성능을 개선할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 페이지기준 목록조회 대신 ID기준 목록조회 방식 사용하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 10개 데이터를 읽어옴 -&amp;gt; 다음 10개 데이터를 읽을 때는 앞서 읽어온 마지막 id를 사용해서 조회&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 조회 범위를 시간 기준으로 제한하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 뉴스 기사 목록 / 회원의 주문내역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 데이터만 조회하는 것도 방법이다. 고객은 최근 결과에만 관심이 있지 과거 결과는 관심이 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB는 성능을 높이기 위해 메모리 캐시를 사용하여 다음 동일한 요청이 들어올 때 빠르게 응답할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 최신 데이터가 많이 조회되기 때문에 캐시에 최신 데이터가 적재될 확률이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 전체 개수 세지 않기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;count(*)와 같은 경우, 조건에 해당하는 모든 데이터를 탐색해야 하기 때문에 실행 시간이 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커버링 인덱스를 사용하더라도 전체 인덱스를 스캔해야 하며, 커버링 인덱스가 아닌 경우에는 실제 데이터를 전부 읽어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 오래된 데이터 삭제 및 분리 보관하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 개수를 일정수준으로 유지하려면 과거 데이터를 삭제해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 로그인 시도 내역 &amp;larr; 최신3개월치만 DB에 남겨두고 나머지는 별도 서버에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. DB 장비 확장하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드를 사용하거나, 더 빠른 CPU, 더 많은 CPU를 사용하여 메모리를 증설하여 DB 성능을 확장할 수 있다(=수직확장)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. 별도 캐시 서버 구성하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB를 확장하는 것보다 Redis와 같은 캐시서버를 구성하는 것이 DB수직확장보다 상대적으로 부담이 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;알아두면 좋을 몇 가지 주의 사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 쿼리 타임아웃&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리 타임아웃을 설정해서 해당 요청이 에러라도 종료처리 될 수 있게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 블로그 글을 조회하는 기능은 타임아웃을 짧게 설정해도 되지만, 상품 결제 기능은 처리 중 타임아웃으로 에러가 발생하면 후속 처리와 데이터 정합성이 복잡해질 수 있기 때문에 기능의 특성에 따라 다르게 설정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 상태 변경 기능은 복제DB에서 조회하지 않기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 주DB-복제DB는 순간적으로 데이터가 일치하지 않을 수 있기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 트랜잭션 문제가 발생할 수 있다. (얘도 어차피 이유는 데이터 불일치)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 회원가입, 변경, 등록, 삭제와 같이 INSERT, UPDATE, DELETE쿼리를 실행하는 기능에서 변경 대상 데이터를 조회해야 한다면, 복제DB가 아닌 INSERT, UPDATE, DELETE 쿼리를 실행하는 주 DB에서 SELECT 쿼리를 실행하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 배치 쿼리 실행 시간 증가&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배치에서 사용하는 쿼리의 실행 시간을 지속적으로 추적해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리 실행 시간이 갑자기 큰 폭으로 증가했는지 감지했다면 해결방법은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 가장 빠른 해결책 DB장비의 사양을 높임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 커버링 인덱스 활용&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;rarr; 데이터를 직접 읽지 않고 인덱스만 스캔해 집계를 수행하기 때문에, 처리 속도는 빨라지고 DB가 사용하는 메모리도 줄어든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 데이터를 일정 크기로 나눠 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 타입이 다른 칼럼 조인 주의&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;칼럼의 타입이 서로 다르면, 두 칼럼의 값을 비교하는 과정에서 DB는 타입 변환을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 데이터를 스캔하지 않고 인덱스만 스캔하는 경우에도, 데이터가 많다면 변환 작업으로 인해 쿼리 실행시간이 길어질 수밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(※ 문자열 타입을 비교할 때는 칼럼의 캐릭터셋이 같은지 확인해야 한다. 캐릭터셋이 다르면 그 자체로도 변환이 발생할 수 있기 때문이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 테이블 변경은 신중하게&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB의 테이블 변경 방식으로 인해 테이블에 컬럼을 추가하거나 하는 변경 시에는 매우매우매우 주의해야한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) MySQL의 테이블 변경 방식 : 새 테이블 생성 &amp;rarr; 원본 테이블의 데이터 복사 &amp;rarr; 복사가 완료되면 새 테이블로 대체&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 이렇게 테이블이 변경되는 시간 동안 DML작업이 중단됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. DB 최대 연결 개수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API서버 4대(커넥션풀 30 * 4 = 120) / DB 최대 연결 개수 100개 &amp;rarr; DB의 최대 연결 개수를 늘려주면 문제 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ DB서버의 CPU사용률이 70%를 넘어가면 절대 연결 개수를 늘리지 말 것! DB부하 증가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실패와 트랜잭션 고려하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 트랜잭션을 고려하지 않은 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계약데이터 존재하는지 확인(SELECT) &amp;rarr; 없으면 계약 (INSERT) &amp;rarr; userState 상태값 변경 (UPDATE)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 update에 문제가 생기면 이미 insert 된 상황으로 정합성이 맞지 않음. 다시 계약하려 해도 이미 있는 계약이라 안된다고 뜰 거임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회원가입 &amp;rarr; 메일발송 실패&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 경우에는 회원가입까지만 트랜잭션으로 묶고 메일은 따로 에러핸들링 처리해서&lt;br /&gt;메일발송 실패했다고 회원가입 안되게 하는 참사는 막자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;풀스캔 하지마라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;테이블 구조 함부로 바꾸지마라 다친다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;적절한 인덱스 사용해서 효율화시켜라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;트랜잭션을 잘 사용해라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/BackEnd</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/64</guid>
      <comments>https://odingcoding.tistory.com/64#entry64comment</comments>
      <pubDate>Fri, 12 Dec 2025 15:46:51 +0900</pubDate>
    </item>
    <item>
      <title>[BE] 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 Ch01~02</title>
      <link>https://odingcoding.tistory.com/63</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;주니어백엔드개발자표지.jpg&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs9H1E/dJMcagcNjuS/BcwUfWuTlymlzaJdXj1U3k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs9H1E/dJMcagcNjuS/BcwUfWuTlymlzaJdXj1U3k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs9H1E/dJMcagcNjuS/BcwUfWuTlymlzaJdXj1U3k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs9H1E%2FdJMcagcNjuS%2FBcwUfWuTlymlzaJdXj1U3k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;308&quot; height=&quot;395&quot; data-filename=&quot;주니어백엔드개발자표지.jpg&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Chapter 01. 들어가며&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 코딩을 할 수 있게 된 것일 뿐&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1챕터는 사실 에필로그 같은 느낌이라 크게 요약할 내용은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 개발자로 취업해서 일한 3년 동안 자주 겪은 문제들이 나와있어서 뜨끔했다. 지금 당장 필요한 에러들만 해결하는거 ,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별 내용은 없지만 에필로그를 보고 느낀건, 이 책 나한테 진짜 도움 많이 될 것 같다는 생각을 했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백앤드를 개발해도 애매하게 알면서 개발하는 사람들. 자바만 대충 알고 스프링부트만 얼버무리는 사람들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꾸준하게 화이팅~ 회사원 말고 개발자가 되장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Chapter 02. 느려진 서비스. 어디부터 봐야 할까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 마주한 챕터부터 내가 궁금해서 알아보던 주제다. 대용량 트래픽! 대박&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  처리량과 응답 시간&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버의 성능을 판단하는 다양한 지표 중 가장 중요한 응답 시간과 처리량에 대해 알아본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 응답 시간&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응답 시간 ? 사용자의 요청을 처리하는 데 걸리는 시간&lt;/li&gt;
&lt;li&gt;하나의 API 요청을 처리하는 과정
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;API 요청(서버에 연결, 서버로 데이터 전송) &amp;rarr; SQL실행, 응답 생성 등(DB 왔다리갔다리) &amp;rarr; API 응답 (클라이언트로 데이터 전송)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;응답시간 측정 기준&lt;br /&gt;두 기준은 응답 데이터의 크기가 작으면 별로 차이 안나지만, 전송할 데이터가 크거나 네트워크 속도가 느리면 차이가 커질 수 있다.&lt;br /&gt;서버 성능을 올바르게 평가하려면 데이터 특성이나 네트워크 환경을 고려해 적절한 지표를 선택해야 한다.&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;TTFB(Time to First Byte)&lt;/span&gt; : 응답 데이터 중 첫 번째 바이트가 도착할 때까지 걸린 시간&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;TTLB(Time to Last Byte)&lt;/span&gt; : 응답 데이터의 마지막 바이트가 도착할 때까지 걸린 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버의 처리 시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로직 수행(if, for 등)&lt;/li&gt;
&lt;li&gt;DB 연동 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;nbsp; 얘네 둘이 제일 많이 차지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;외부 API 연동&amp;nbsp; &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;larr;&amp;nbsp; &amp;nbsp;둘만 해도 거의 80~95%까지 차지한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;응답 데이터 생성(전송)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 처리량&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;처리량 ? 단위 시간당 시스템이 처리하는 작업량&lt;/li&gt;
&lt;li&gt;처리량 측정 기준
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;TPS(transaction per second)&lt;/span&gt; : 초당 트랜잭션 수&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;RPS(request per second)&lt;/span&gt; : 초당 요청 수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TPS를 높일 수 있는 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버가 동시에 처리할 수 있는 요청 수를 늘려 대기 시간 줄이기&lt;/li&gt;
&lt;li&gt;처리 시간 자체를 줄여 대기 시간 줄이기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TPS를 확인하는 방법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모니터링 시스템 활용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스카우터, 핀포인트, 뉴렐릭, ...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  서버 성능 개선 기초&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 병목지점 및 수직/수평 확장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TPS를 높이려면 먼저 모니터링 도구(또는 로그)를 사용하여 성능 문제가 발생하는 지점을 찾아야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성능 문제를 일으키는 원인을 찾았다면, 급한 불을 끄는 방법 중 하나인 수직확장 / 서버를 늘리는 방법인 수평 확장을 고려한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;수직확장&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수직확장 ? CPU, 메모리, 디스크 등의 자원을 증가시켜서 급한 불을 끈다.&lt;/li&gt;
&lt;li&gt;더 빠른 CPU로 바꾸거나, CPU 코어수를 늘리기 / 메모리 확장 / 디스크를 HDD &amp;rarr; SDD&lt;/li&gt;
&lt;li&gt;수직확장은 즉각적인 효과를 바로 얻을 수 있지만 트래픽이 지속해서 증가하면 언젠가 결국 또다시 성능 문제가 발생한다.&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;비용이 많이 들기 때문에 매 번 수직확장을 반복할 수는 없다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;수평확장&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수평확장 ? 서버를 추가로 투입해 TPS를 높인다.&lt;/li&gt;
&lt;li&gt;그러나 무턱대고 서버를 추가하면 안된다.&lt;br /&gt;DB에서 성능 문제가 발생하는데 서버를 추가로 투입하면 부하가 더 커지고 성능 문제는 악화될 수 있다.&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&amp;rarr; DB나 외부 API에 성능 문제가 발생하지 않는 범위 내에서만 수평 확장을 해야 효과가 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. DB 커넥션풀&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;DB 커넥션 풀&lt;/span&gt;이란, &lt;br /&gt;서버와 DB사이에 네트워크 연결을 생성하고 종료하는 데에만 해도 시간이 오래 걸리니, DB에 연결된 커넥션을 미리 생성해서 보관하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션은 DB작업이 필요할 때 풀에서 커넥션을 가져와 사용하고, 작업이 끝나면 다시 풀에 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥션 풀을 사용하면 이미 연결된 커넥션을 재사용하기 때문에 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;응답 시간이 줄어드는 장점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ※ Springboot는 HikariCP, Go언어는 자체 DB 커넥션 풀을 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥션 풀의 설정값들 중 중요 3가지는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커넥션 풀 크기 (또는 최소 크기, 최대 크기)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커넥션 풀에 미리 생성해 둘 커넥션 개수를 지정하는 설정&lt;/li&gt;
&lt;li&gt;DB 상태를 고려하여 커넥션 풀의 최소/최대 크기를 조절한다. (ex. 은행은 낮 시간 / 게임은 저녁 시간에 트래픽이 높음을 참고)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;풀에 커넥션이 없을 때 커넥션을 구할 때까지 대기할 시간
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;풀에 사용할 수 있는 커넥션이 없을 때 커넥션을 얻기 위해 기다릴 수 있는 최대 시간을 의미&lt;br /&gt;(※ 지정된 대기 시간 안에 커넥션을 구하지 못하면 DB 연결 실패 에러가 발생)&lt;/li&gt;
&lt;li&gt;대기시간을 짧게 설정하여 에러를 빠르게 응답하는 것도 방법임.&lt;br /&gt;&amp;rarr; 대기 시간을 짧게 설정하면 서버 부하를 일정 수준으로 유지할 수 있으며 서버를 안정적으로 운영하는 데 도움이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;커넥션의 유지 시간 (최대 유휴 시간, 최대 유지 시간)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;커넥션이 사용되지 않는 시간이 길어지면 연결이 끊길 수 있다. 이러한 에러를 방지하기 위해 최대유휴시간, 최대유지시간을 제공한다.&lt;/li&gt;
&lt;li&gt;최대 유휴 시간 : 사용되지 않는 커넥션을 풀에 유지할 수 있는 최대 시간을 의미&lt;/li&gt;
&lt;li&gt;유효성 검사 : 커넥션이 정상적으로 사용할 수 있는 상태인지 여부를 확인&lt;/li&gt;
&lt;li&gt;최대 유지 시간 : 설정한 시간 동안만 커넥션이 유지된다. 설정 시간이 지나면 커넥션이 유효하더라도 커넥션을 닫고 풀에서 제거된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 서버 캐시&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 서버를 확장하지 않고도 응답 시간과 처리량을 개선하고 싶다면 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;캐시&lt;/span&gt; 사용을 고려할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시는 일종의 (key, value) 쌍을 저장하는 Map과 같은 형태의 데이터 저장소다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시에 데이터를 저장해두면 동일한 데이터를 요청할 때 DB가 아닌 캐시에서 데이터를 읽어와 응답시간을 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;캐시에서 키에 해당하는 값 조회&lt;/span&gt; &amp;rarr;&amp;nbsp;&lt;span style=&quot;background-color: #dddddd;&quot;&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (값 존재)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; &amp;nbsp;&amp;rarr; &lt;span style=&quot;background-color: #dddddd;&quot;&gt;값 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ↘︎ (값 없음) &amp;rarr; &lt;span style=&quot;background-color: #dddddd;&quot;&gt;DB에서 값 조회&lt;/span&gt; &amp;rarr; &lt;span style=&quot;background-color: #dddddd;&quot;&gt;(key, value)를 캐시에 저장&lt;/span&gt; ↗︎&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시의 적중률&lt;br /&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;적중률(hit rate) = 캐시에 존재한 건수/캐시에서 조회를 시도한 건수&lt;/span&gt;&lt;br /&gt;&amp;rarr; 적중률이 높을수록 DB와의 연동이 줄어들고 곧 응답 시간 감소, 처리량 증가, DB 부하 감소로 이어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시가 가득 찼을 때 삭제할 대상을 선택하는 규칙
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;LRU (Least Recently Used)&lt;/span&gt; : 가장 오래전에 사용된 데이터를 제거한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;LFU (Least Frequently Used)&lt;/span&gt; : 가장 적게 사용된 데이터를 제거한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #c0d1e7;&quot;&gt;FIFO (First In First Out)&lt;/span&gt; : 먼저 추가된 데이터를 먼저 삭제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 로컬 캐시와 리모트 캐시&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;로컬 캐시&lt;/span&gt; (In-memory Cache)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버프로세스와 동일한 메모리를 캐시 저장소로 사용.&lt;/li&gt;
&lt;li&gt;Caffeine(자바), go-cache(Go), node-cache(Node.js)&lt;/li&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속도가 빠르다&lt;/li&gt;
&lt;li&gt;별도의 외부 연동이 필요하지 않아 구조를 단순하게 유지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시에 저장할 수 있는 데이터 크기에 제한이 있다.&lt;/li&gt;
&lt;li&gt;서버 프로세스를 재시작하면 메모리에 존재하던 캐시 데이터가 모두 삭제된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐시에 보관할 데이터 규모가 작고 변경 빈도가 매우 낮다면 로컬 캐시로 충분 (ex. 홈 화면에 표시할 최신 공지글 목록)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;리모트 캐시&lt;/span&gt;&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;별도 프로세스를 캐시 저장소로 사용.&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 규모를 수평 확장할 수 있다.&lt;/li&gt;
&lt;li&gt;서버 프로세스가 재시작되더라도 저장되어있던 캐시 데이터는 그대로 유지된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속도가 느리다. &lt;br /&gt;(∵ 서버 프로세스 &amp;harr;︎ 캐시 프로세스 네트워크 통신)&lt;/li&gt;
&lt;li&gt;시스템 구조가 복잡해진다.&lt;br /&gt;(∵ 별도의 서버 장비와 프로세스가 필요하기 때문)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터 규모가 크다면 리모트 캐시 사용 (ex. 트래픽이 많은 대형 쇼핑 사이트의 개별 제품 정보)&lt;/li&gt;
&lt;li&gt;배포 빈도가 높은 서비스 (∵ 캐시를 유지할 수 있으니까)&lt;/li&gt;
&lt;li&gt;변경에 민감한 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐시 사전 적재
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트래픽이 순간적으로 급증하는 패턴을 보인다면 캐시에 데이터를 미리 저장하는 것을 고려&lt;/li&gt;
&lt;li&gt;ex. 요금 안내 푸시 알림을 배포하기 전, 미리 데이터를 캐시에 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캐시 무효화
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시에 보관된 데이터의 원본이 바뀌면, 캐시에 보관된 데이터도 함께 변경하거나 삭제되어야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 가비지 컬렉터와 메모리 사용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;가비지 컬렉터&lt;/span&gt;를 사용하는 언어는 사용이 끝난 객체를 힙 메모리에서 바로 삭제하지 않고 정해진 규칙에 따라 사용하지 않는 메모리를 찾아서 반환한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발자가 메모리를 직접 관리해야 하는 부담을 줄여준다.&lt;/li&gt;
&lt;li&gt;코드로 메모리를 관리할 수 없기 때문에 보안 이슈를 줄여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응답 시간에 영향을 줄 수 있다 (ex. Stop-The-World : GC가 실행되는 동안 실행이 멈추는 현상)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대량으로 객체가 생성되는 것도 메모리가 부족할 수 있기 때문에 조회 범위를 제한하거나 스트림을 활용하여 방지해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래처럼 스트림을 활용하면 파일 처리 과정에서 필요한 메모리 크기를 줄일 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1763109989802&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Stream 사용 X
byte[] bytes = Files.readAllBytes(Path.of(&quot;path&quot;)); //파일을 한 번에 메모리에 로딩
out.write(bytes)

// Stream 사용 O
InputStream is = Files.newInputStream(Path.of(&quot;path&quot;));
byte[] buffer = new byte[8192]; // 8KB 메모리
int read;
while ((read = is.read(buffer, 0, 8192)) &amp;gt;= 0 {
  out.write(buffer, 0, read);
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming/BackEnd</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/63</guid>
      <comments>https://odingcoding.tistory.com/63#entry63comment</comments>
      <pubDate>Fri, 14 Nov 2025 17:51:21 +0900</pubDate>
    </item>
    <item>
      <title>[Jenkins] Docker에 Jenkins설치 및 Pipeline</title>
      <link>https://odingcoding.tistory.com/62</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sqvvt/btsLbAPYxgL/f6YV7K1GIv5odQu8NV4H31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sqvvt/btsLbAPYxgL/f6YV7K1GIv5odQu8NV4H31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sqvvt/btsLbAPYxgL/f6YV7K1GIv5odQu8NV4H31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSqvvt%2FbtsLbAPYxgL%2Ff6YV7K1GIv5odQu8NV4H31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;411&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 설치한 Docker를 사용해서 Jenkins 컨테이너를 띄워볼것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 그 사이 내 컴퓨터는 윈도우에서 맥으로 바꼈다  꺄하ㅏ하&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;mac에서 docker설치는 거의 다운로드만 하면 될 정도로 간단하므로 자세히 다루진 않을 것이다 (캡쳐도 따기 전에 설치 다 해버림;)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  Jenkins?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins는 소프트웨어 개발에서 지속적 통합(CI)과 지속적 배포(CD)를 도와주는 오픈소스 자동화 서버이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;한 마디로 개발, 빌드, 테스트, 배포 과정을 자동화할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-04 오후 2.22.27.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KcVAF/btsLbuWo2Mw/ovgpwpIWopkfqeuhepbqpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KcVAF/btsLbuWo2Mw/ovgpwpIWopkfqeuhepbqpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KcVAF/btsLbuWo2Mw/ovgpwpIWopkfqeuhepbqpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKcVAF%2FbtsLbuWo2Mw%2FovgpwpIWopkfqeuhepbqpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;184&quot; data-filename=&quot;스크린샷 2024-12-04 오후 2.22.27.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;CI/CD의 개념이 낯설다면 이렇게 생각할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;코드를 변경한 후 매번 직접 테스트하고 빌드하고 서버에 올리다 보면, 시간도 오래 걸리고 사람이 하는 일이니 실수가 많아질 수밖에 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins는 이런 번거로운 작업을 자동으로 처리해주며, 덕분에 개발자들은 개발 본연의 업무에 집중할 수 있게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  Jenkins의 주요 특징&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;1. 플러그인 시스템&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins는 다양한 플러그인을 지원해서 거의 모든 환경에 맞게 커스터마이징 가능. Git, Docker, kubernetes, Slack 등 수백 가지 툴과 통합이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2. 웹 기반 UI&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins는 직관적인 웹 인터페이스를 제공해서 설정과 관리가 비교적 쉬움.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;3. 무료 오픈소스&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;많은 기업과 팀에서 부담 없이 도입할 수 있음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;⚙️ Jenkins 설치&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins를 설치하는 방법은 여러 가지가 있지만, 가장 기본적인 Docker를 이용한 설치 방법을 소개합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;1. Docker 설치되어있는지 확인&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733727892589&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker --version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-09 오후 4.04.31.png&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;39&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zIxMA/btsLcsp9WQk/kQXQbAwK6HNk9vUXywEZY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zIxMA/btsLcsp9WQk/kQXQbAwK6HNk9vUXywEZY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zIxMA/btsLcsp9WQk/kQXQbAwK6HNk9vUXywEZY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzIxMA%2FbtsLcsp9WQk%2FkQXQbAwK6HNk9vUXywEZY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;39&quot; data-filename=&quot;스크린샷 2024-12-09 오후 4.04.31.png&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;39&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2. Jenkins 실행&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733727960022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run -d -p 8082:8080 -p 50000:50000 --name jenkins jenkins/jenkins:lts&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.42.31.png&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cm8spl/btsLbTIv5Bt/9XIVcD8U9WzKgSsu3PuK61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cm8spl/btsLbTIv5Bt/9XIVcD8U9WzKgSsu3PuK61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cm8spl/btsLbTIv5Bt/9XIVcD8U9WzKgSsu3PuK61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcm8spl%2FbtsLbTIv5Bt%2F9XIVcD8U9WzKgSsu3PuK61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;587&quot; height=&quot;309&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.42.31.png&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;추후 nginx와 gitlab을 8080, 8081에 띄울 것이기 때문에 jenkins는 8082에 port를 사용했음.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;-d&lt;/span&gt; : 컨테이너를 백그라운드에서 실행&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;-p 8082:8080&lt;/span&gt; : 포트를 지정함. 호스트 포트 8082, 컨테이너 내부 포트 8080 사용. 이 매핑을 통해, 호스트 머신의 8082 포트를 컨테이너 내부의 8080 포트에 연결한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;-p 50000:50000&lt;/span&gt; : 또 다른 포트를 지정함. Jenkins는 분산 빌드(Distributed Build)를 지원하며, Jenkins Master와 Agent 노드 간의 통신에 50000 포트를 사용. 이 매핑을 통해 Jenkins Master와 Agent가 통신할 수 있도록 설정한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;--name jenkins&lt;/span&gt; : 컨테이너 이름은 'jenkins'로&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;jenkins/jenkins:lts&lt;/span&gt; : 사용할 이미지 (※ lts : Long-Term Support. 안정성과 장기 지원을 제공하는 Jenkins 버전)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;3. Jenkins 컨테이너 띄워졌는지 확인&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733905481911&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.42.59.png&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;57&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpbukm/btsLfHG99Lo/i3a4CvOcQ81s8Ve8UOIQN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpbukm/btsLfHG99Lo/i3a4CvOcQ81s8Ve8UOIQN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpbukm/btsLfHG99Lo/i3a4CvOcQ81s8Ve8UOIQN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbpbukm%2FbtsLfHG99Lo%2Fi3a4CvOcQ81s8Ve8UOIQN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1076&quot; height=&quot;57&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.42.59.png&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;57&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;4. 컨테이너 내부에 접속해서 jenkins 초기 비밀번호 복사&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733905532703&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker exec -it jenkins /bin/bash
cd /var/jenkins_home/secrets
cat initialAdminPassword&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.45.25.png&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nv6Ky/btsLf85lkIP/WxBg9SDUgpRmsyfUhIlsR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nv6Ky/btsLf85lkIP/WxBg9SDUgpRmsyfUhIlsR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nv6Ky/btsLf85lkIP/WxBg9SDUgpRmsyfUhIlsR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fnv6Ky%2FbtsLf85lkIP%2FWxBg9SDUgpRmsyfUhIlsR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;102&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.45.25.png&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;5. http://localhost:8082 접속 후 복사한 비밀번호 입력&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.45.58.png&quot; data-origin-width=&quot;1915&quot; data-origin-height=&quot;976&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lA3AX/btsLmiHUVCJ/4dsvy7iCosk1ulo1tGLIYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lA3AX/btsLmiHUVCJ/4dsvy7iCosk1ulo1tGLIYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lA3AX/btsLmiHUVCJ/4dsvy7iCosk1ulo1tGLIYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlA3AX%2FbtsLmiHUVCJ%2F4dsvy7iCosk1ulo1tGLIYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1915&quot; height=&quot;976&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.45.58.png&quot; data-origin-width=&quot;1915&quot; data-origin-height=&quot;976&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;6. 기본 plugin 설치 및 User 등록&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.46.24.png&quot; data-origin-width=&quot;1913&quot; data-origin-height=&quot;976&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFDTac/btsLmgpPvPC/3S94AlBRc0kLlAT1iOHbl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFDTac/btsLmgpPvPC/3S94AlBRc0kLlAT1iOHbl0/img.png&quot; data-alt=&quot;Plugin설치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFDTac/btsLmgpPvPC/3S94AlBRc0kLlAT1iOHbl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFDTac%2FbtsLmgpPvPC%2F3S94AlBRc0kLlAT1iOHbl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1913&quot; height=&quot;976&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.46.24.png&quot; data-origin-width=&quot;1913&quot; data-origin-height=&quot;976&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Plugin설치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.51.42.png&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;971&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMSKqL/btsLnedym79/25ZKA2W4NdpMIqZW4nkrjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMSKqL/btsLnedym79/25ZKA2W4NdpMIqZW4nkrjK/img.png&quot; data-alt=&quot;Admin User 등록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMSKqL/btsLnedym79/25ZKA2W4NdpMIqZW4nkrjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMSKqL%2FbtsLnedym79%2F25ZKA2W4NdpMIqZW4nkrjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1904&quot; height=&quot;971&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.51.42.png&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;971&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Admin User 등록&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.53.54.png&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;972&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIurre/btsLmrEFv6i/76Lw3kLXhWIAxO86bz6mB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIurre/btsLmrEFv6i/76Lw3kLXhWIAxO86bz6mB0/img.png&quot; data-alt=&quot;접근할 URL설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIurre/btsLmrEFv6i/76Lw3kLXhWIAxO86bz6mB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIurre%2FbtsLmrEFv6i%2F76Lw3kLXhWIAxO86bz6mB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1908&quot; height=&quot;972&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.53.54.png&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;972&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;접근할 URL설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.54.14.png&quot; data-origin-width=&quot;1909&quot; data-origin-height=&quot;972&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7PfK4/btsLlksVbcW/UztnQSg1ZswUiJuEokLVM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7PfK4/btsLlksVbcW/UztnQSg1ZswUiJuEokLVM1/img.png&quot; data-alt=&quot;준비갈완료!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7PfK4/btsLlksVbcW/UztnQSg1ZswUiJuEokLVM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7PfK4%2FbtsLlksVbcW%2FUztnQSg1ZswUiJuEokLVM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1909&quot; height=&quot;972&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.54.14.png&quot; data-origin-width=&quot;1909&quot; data-origin-height=&quot;972&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;준비갈완료!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;7. Jenkins 설치 완료&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.54.38.png&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;973&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnwa98/btsLlsEjkJB/vErJ8TKZMh2KIqOh07zZj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnwa98/btsLlsEjkJB/vErJ8TKZMh2KIqOh07zZj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnwa98/btsLlsEjkJB/vErJ8TKZMh2KIqOh07zZj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcnwa98%2FbtsLlsEjkJB%2FvErJ8TKZMh2KIqOh07zZj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1914&quot; height=&quot;973&quot; data-filename=&quot;스크린샷 2024-12-06 오후 2.54.38.png&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;973&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  Jenkins Trigger&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins에서 빌드를 트리거하는 방법은 여러 가지가 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;각 프로젝트의 요구사항에 따라 적합한 방식을 선택하여 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;1. 수동 트리거&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사용자가 Jenkins 웹 UI에서 직접 &quot;Build Now&quot; 버튼을 클릭하여 빌드를 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;설정 방법 :&amp;nbsp;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins에서 작업(Job)을 생성하거나 수정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;별도의 트리거 설정이 필요하지 않음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사용 예시 : 간단한 테스트나 개발 환경에서 자주 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2. 웹훅(Webhook) 기반 트리거&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;GitHub, GitLab, Bitbucket 등과 같은 소스 코드 관리 시스템(SCM)이 변경 사항을 감지하면 Jenkins에 요청을 보내 빌드를 시작.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;즉, &lt;b&gt;업데이트 생겼음!&lt;/b&gt; 이라고 jenkins에게 알려줌&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;설정 방법 :&amp;nbsp;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins에서 SCM Polling 또는 Webhook Trigger 플러그인을 활성화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;프로젝트 설정에서 Gitlab/GitHub Trigger를 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Git Repository에 웹훅 URL을 설정 : http://&amp;lt;JENKINS_URL&amp;gt;/github-webhook/ 또는 http://&amp;lt;JENKINS_URL&amp;gt;/gitlab-webhook/&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사용 예시 : 코드가 push 되거나 merge 될 때 자동으로 빌드 시작&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;3. SCM Polling&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins가 주기적으로 소스 코드 저장소를 확인하여 변경 사항이 있을 경우 빌드를 실행&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;즉, &lt;b&gt;업데이트 있어? 업데이트 있어? 업데이트 있어? 업데이트 있어? 업데이트 있어?&lt;/b&gt; 라고 jenkins에게 물어봄&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;설정 방법 :&amp;nbsp;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;작업(Job) 설정 화면에서 Build Triggers &amp;rarr; Poll SCM 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;폴링 주기를 크론 표현식으로 입력&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;ex) H/5 * * * *&amp;nbsp; #5분마다 체크&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사용 예시 : 웹훅 설정이 어려운 환경이나 프로젝트 초기에 커밋이 굉장히 자주 발생할 때&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;4. 기타&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 외에도 Cron Schedule을 이용한 트리거, 다른 작업으로부터 트리거, Jenkins REST API를 통한 트리거, Pipeline 내부에서 다른 작업을 트리거하는 등...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;상황에 따라 어떤 방식을 쓸 건지 잘 선택해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;⚒️ Jenkins Pipeline&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;eclarative_vs_scripted_pipeline_mobile.jpg&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b957N3/btsLnOlK3j1/83kN5twdmC7kl5aftMH5iK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b957N3/btsLnOlK3j1/83kN5twdmC7kl5aftMH5iK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b957N3/btsLnOlK3j1/83kN5twdmC7kl5aftMH5iK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb957N3%2FbtsLnOlK3j1%2F83kN5twdmC7kl5aftMH5iK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;344&quot; height=&quot;399&quot; data-filename=&quot;eclarative_vs_scripted_pipeline_mobile.jpg&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins Pipeline은 크게 두 가지 형태가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;1. &lt;b&gt;Declarative Pipeline&lt;/b&gt; : 작성이 쉽고 가독성이 좋아서 많이 사용됨&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2. &lt;b&gt;Scripted Pipeline&lt;/b&gt; : 러닝커브가 있지만 더 많은 기능을 제공함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 두 형태 중 조금 더 자주 쓰이는 건 Declarative Pipeline이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Declarative Pipeline은 4가지 주요 영역으로 나뉘고, groovy언어를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agent&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;stages&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;steps&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;post&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;✔︎&lt;b&gt; agent&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agnet는 단순히 Jenkins 작업을 실행할 프로세스다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;기본적으로 agent any가 제공되므로 별도로 agent 설정을 하지 않아도 작업이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;그런데 agent는 Jenkins 서버가 있는 머신에서만 동작하는 게 아님. SSH 같은 방식으로 원격에서도 동작하도록 설정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agent설정 시 label이라는 별칭도 줄 수 있으며, 아래처럼 'my-agent'로 특정 agent를 지정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734511592242&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;agent { label 'my-agent' }&lt;/code&gt;&lt;/pre&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 140px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;파라미터&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;설명&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;예시&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;any&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사용가능한 어떤 agent에서도 실행될 수 있음.&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agent any&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;none&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;파이프라인을 실행하는 동안 어떤 global agent도 할당되지 않음&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agent none&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;label&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;제공된 label을 이용해 파이프라인 실행&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agent {label 'example'}&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;node&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;label과 유사. 추가적인 옵션 추가 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;agent {node{label'example'}}&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;docker&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;도커 기반 파이프라인 제공&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.5193%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;dockerfile&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 49.1473%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;도커파일 기반 파이프라인 제공&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;✔︎ steps&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;steps는 실제 작업을 담고 있는 블록이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;steps 안의 명령 한 줄 한 줄이 step이라고 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;steps 안에서 script를 사용하려면 Scripted Pipeline 문법을 부분적으로 사용할 수 있다. (※ 그렇다고 scripted 문법을 지나치게 많이 사용하면 Declarative Pipeline의 장점인 가독성이 떨어질 수 있음 !!!)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734511931744&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;steps {
  echo 'Hello World'
  
  script {
    def browsers=['chrome', 'firefox']
    for (int i=0;i&amp;lt;browsers.size();++i){
      echo &quot;Testing the ${browsers[i]} browser&quot;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;✔︎ post&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;post는 후처리 작업을 위한 블록이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;post블록은 pipeline이나 stage레벨에 붙이고, 내부에는 post-condition 블록을 설정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;이 블록은 바로 위 작업의 결과에 따라 실행 여부를 결정함.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734932985749&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pipeline{
  agent any
  stages {
    stages('Example') {
      steps {
        echo 'Hello World'
      }
      post {
        success {
          echo 'success'  # 위 steps 전부 성공하면 실행
        }
        failure {
          error 'failure' # steps에서 하나라도 실패하면 실행
        }
      }
    }
  }
  post {
    always {
      echo 'I will always say Hello again!'  # stages 끝나고 반드시 실행
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;※ post-condition 블록❓&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;success : 작업이 모두 성공했을 때 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;failure : 작업 중 하나라도 실패하면 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;always : 작업 결과와 상관없이 항상 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;changed : 현재 빌드의 상태가 이번 빌드의 상태와 달라졌다면 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;unstable : 현재 빌드의 상태가 불안하다면 실행&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  Jenkins 활용 팁&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Slack 알림 연동&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Slack 플러그인을 설치하면 빌드 상태를 팀원에게 실시간 공유 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 얼마나 편한 세상인가 ,, (근데 우리 회사는 안 써서 연동 못해봄 ㅠ 언젠간 쓰겠지)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;병렬 빌드&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;여러 작업을 동시에 처리해야 한다면, 파이프라인에서 병렬 단계를 활용할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;다수의 프로젝트를 동시빌드할 때 아주아주아주 요긴하게 활용함. 빌드속도와 관련 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;보안 설정&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;Jenkins는 기본적으로 누구나 접근 가능한 상태로 실행되기 때문에 꼭 관리자 계정과 접근 권한을 설정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Programming/DevOps</category>
      <category>cicd</category>
      <category>DevOps</category>
      <category>docker</category>
      <category>Jenkins</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/62</guid>
      <comments>https://odingcoding.tistory.com/62#entry62comment</comments>
      <pubDate>Mon, 23 Dec 2024 15:00:26 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] 리눅스 환경에서 su와 sudo의 차이점</title>
      <link>https://odingcoding.tistory.com/61</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctGi5e/btsLdiol4WM/dQVziQj7Qm5VeGnDCfDyMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctGi5e/btsLdiol4WM/dQVziQj7Qm5VeGnDCfDyMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctGi5e/btsLdiol4WM/dQVziQj7Qm5VeGnDCfDyMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctGi5e%2FbtsLdiol4WM%2FdQVziQj7Qm5VeGnDCfDyMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;675&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;알고싶지 않았지만 알게된 ,, su와 sudo의 차이점&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Jenkins Agent의 계정을 다른 계정으로 변경하려고 작업을 했는데 문제가 생겼었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Jenkins 작업 뒤에 CP작업이 있다면 계정과 로그인간에 연결된 무언가가 있는지 확인하세요 다덜 (sudo로 작업해서 환경변수가 안바뀌는 참사 발생)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그래서 알아본 su 와 sudo의 차이점이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;아래 설명과 예시들은 변경해야 할 계정명을 'cicdagent'라고 했지만, 아마 가장 많이 쓰일 계정은 'root'일 것이다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;root도 동일하게 적용되지만, 꼭 root만 su/sudo를 사용하는게 아니라는걸 기억하기 위함임&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;  su&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;✔︎ su ?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;su : &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;substitute user&lt;/b&gt;&lt;/span&gt;의 약자. 사용자를 완전히 전환하여 해당 계정으로 로그인한 것 처럼 동작한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;su - cicdagent는 cicdagent계정으로 전환하며, 사용자의 환경 변수도 해당 계정의 초기 설정으로 로드된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;✔︎ 주요 특징&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;완전한 사용자 전환 : 현재 세션에서 cicdagent계정으로 전환&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;환경 변수 초기화 : - 옵션은 로그인 셸을 실행하며, 홈 디렉터리 및 PATH같은 환경변수를 새로 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;암호 요구 : cicdagent계정의 암호를 입력해야 전환이 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;✔︎ 사용 상황&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특정 사용자의 환경을 완전히 가져와야 할 때&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;cicdagent계정으로 실행해야 하는 스크립트나 명령어가 있을 때&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; &lt;/span&gt;&lt;/b&gt;&amp;nbsp;sudo&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;✔︎ sudo ?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;sudo : &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;superuser do&lt;/b&gt;&lt;/span&gt;의 약자. 현재 사용자의 권한으로 특정 명령어를 다른 사용자(cicdagent)의 권한으로 실행한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;-cicdagent는 -u cicdagent의 축약형으로, 명령어를 cicdagent사용자의 권한으로 실행한다는 의미이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;✔︎ 주요 특징&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;명령어 단위 실행 : 사용자를 전환하지 않고, 특정 명령어를 cicdagent권한으로 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;환경 변수 유지 : 기본적으로 현재 사용자의 환경 변수를 유지. (-i 옵션으로 초기화 가능)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;암호 요구 : sudo 권한이 설정된 계정의 암호를 입력해야 실행 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;✔︎ 사용 상황&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;cicdagent권한으로 특정 명령어만 실행해야 할 때&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;전체 세션 전환 없이 일회성 작업이 필요할 때&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  주요 차이점 비교&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 100px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 21.124%; text-align: left; height: 20px;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.6821%; text-align: left; height: 20px;&quot;&gt;&lt;b&gt;su - cicdagent&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.1938%; text-align: left; height: 20px;&quot;&gt;&lt;b&gt;sudo - cicdagent&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 21.124%; height: 20px;&quot;&gt;사용자 전환 방식&lt;/td&gt;
&lt;td style=&quot;width: 38.6821%; height: 20px;&quot;&gt;계정 전환 (새로운 셸 시작)&lt;/td&gt;
&lt;td style=&quot;width: 40.1938%; height: 20px;&quot;&gt;특정 명령어만 다른 사용자로 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 21.124%; height: 20px;&quot;&gt;환경 변수 초기화&lt;/td&gt;
&lt;td style=&quot;width: 38.6821%; height: 20px;&quot;&gt;초기화됨 (cicdagent의 환경 적용)&lt;/td&gt;
&lt;td style=&quot;width: 40.1938%; height: 20px;&quot;&gt;초기화되지 않음 (기본적으로 현재 환경 유지)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 21.124%; height: 20px;&quot;&gt;암호 요구&lt;/td&gt;
&lt;td style=&quot;width: 38.6821%; height: 20px;&quot;&gt;cicdagent의 암호&lt;/td&gt;
&lt;td style=&quot;width: 40.1938%; height: 20px;&quot;&gt;현재 사용자의 암호 (sudo 설정된 경우)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 21.124%; height: 20px;&quot;&gt;적합한 작업&lt;/td&gt;
&lt;td style=&quot;width: 38.6821%; height: 20px;&quot;&gt;장시간 cicdagent로 작업&lt;/td&gt;
&lt;td style=&quot;width: 40.1938%; height: 20px;&quot;&gt;단일 명령어를 cicdagent 권한으로 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;su [계정명]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 계정으로 전환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;su - [계정명]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 계정으로 전환 + 그 계정의 환경변수 적용&lt;/li&gt;
&lt;li&gt;장기 작업이 필요할 때 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;sudo [계정명]&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 계정에서 다른 계정의 권한만 빌림&lt;/li&gt;
&lt;li&gt;특정 단일 작업 및 임시작업이면 sudo - [계정명]이 효율적&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/DevOps</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/61</guid>
      <comments>https://odingcoding.tistory.com/61#entry61comment</comments>
      <pubDate>Wed, 11 Dec 2024 10:57:43 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] 도커 스토리지 마운트 &amp;amp; 도커 컴포즈</title>
      <link>https://odingcoding.tistory.com/60</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;docker_icon.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQtoJE/btsKspaMljS/JSlG5y5pI33DcusMkkkDEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQtoJE/btsKspaMljS/JSlG5y5pI33DcusMkkkDEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQtoJE/btsKspaMljS/JSlG5y5pI33DcusMkkkDEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQtoJE%2FbtsKspaMljS%2FJSlG5y5pI33DcusMkkkDEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;675&quot; data-filename=&quot;docker_icon.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  컨테이너와 호스트 사이에 파일 복사&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/h3&gt;
&lt;pre id=&quot;code_1730355850593&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### 기본적으로 docker cp 원본경로 복사할경로 ###

# 호스트 -&amp;gt; 컨테이너로 파일 복사
# docker cp 호스트_경로 컨테이너_이름:컨테이너_경로
docker cp C:\Users\woori\Documents\index.html exapache:/usr/local/apache2/htdocs/

# 컨테이너 -&amp;gt; 호스트로 파일 복사
# docker cp 컨테이너_이름:컨테이너_경로 호스트_경로
docker cp exapache:/usr/local/apache2/htdocs/index.html C:\Users\woori\Documents&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  스토리지 마운트&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 볼륨이란? 스토리지의 한 영역을 분할한 것. 즉, 하드디스크나 SSD를 분할한 하나의 영역임&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 마운트란? 연결하다 그 의미 그 자체&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 그럼 볼륨마운트란? 대상을 연결해 운영체제 또는 스프트웨어의 관리하에 두는 일.&lt;br /&gt;&amp;nbsp; &amp;nbsp; ex) USB랑 PC는 연결되어있지 않지만 USB를 PC에 꽂으면 연결되어 사용할 수 있는거랑 비슷함&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바인드 마운트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너와 파일을 연동하는 데 많이 사용됨. *LAMP 스택을 실무에 활용할 때 필수적임&lt;/li&gt;
&lt;li&gt;도커가 설치된 컴퓨터의 문서 폴더 등 도커엔진에서 관리하지&amp;nbsp; 않는 영역의 기존 디렉터리를 컨테이너에 마운트하는 방식이다.&lt;/li&gt;
&lt;li&gt;디렉터리가 아닌 파일 단위로도 마운트가 가능하다.&lt;/li&gt;
&lt;li&gt;자주 사용하는 파일을 두는 데 사용한다.&lt;/li&gt;
&lt;li&gt;기존과 동일한 방식으로 파일을 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;볼륨 마운트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도커 엔진이 관리하는 영역 내에 만들어진 볼륨을 컨테이너에 디스크 형태로 마운트한다.&lt;/li&gt;
&lt;li&gt;이름만으로 관리가 가능해서 다루기 쉽지만&lt;/li&gt;
&lt;li&gt;볼륨에 비해 직접 조작하기 어려움.&lt;/li&gt;
&lt;li&gt;임시목적으로 사용하거나 자주는 쓰지 않지만 지우면 안되는 파일들을 목적으로 많이 사용함&lt;/li&gt;
&lt;li&gt;운영체제 또는 환경에 따라 명령어가 달라지는 등의 의존성 문제가 일어나지 않는다.(ex. 윈도우-&amp;gt;macOS로 변경했을 때 경로 수정 안해도 됨)&lt;/li&gt;
&lt;li&gt;볼륨에 접근할 때 무조건 도커 컨테이너를 경유해야 한다. 백업의 절차도 매우 복잡함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tip. 볼륨에 직접 접근&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;color: #212529; text-align: start;&quot;&gt;리눅스에서는 볼륨은 /var/lib/docker/volumes/ 에 위치한다. 단,&amp;nbsp;&lt;/span&gt;&lt;b&gt;볼륨에 직접 접근하여 수정할 경우 볼륨 자체가 깨질 수 있다&lt;/b&gt;&lt;span style=&quot;color: #212529; text-align: start;&quot;&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;볼륨 마운트&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;바인드 마운트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;스토리지 영역&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;볼륨&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;디렉터리 또는 파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;물리적 위치&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;도커 엔진의 관리 영역&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;어디든지 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;마운트 절차&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;볼륨을 생성한 후 마운트&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;기존 파일 또는 폴더를 마운트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;내용 편집&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;도커 컨테이너를 통해서&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;일반적인 파일과 같이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;백업&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;절차가 복잡함&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;일반적인 파일과 같이&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;* LAMP스택 ? : 웹 개발에서 널리 사용되는 오픈소스소프트웨어 세트로, Linux(운영체제), Apache(웹서버), Mysql(데이터베이스 관리시스템), PHP(서버 사이드 스크립팅 언어)로 구성되어있음.&lt;/i&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Image 만들기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp; 방법1. commit 커맨드로 컨테이너를 이미지로 변환
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도커환경에서 사용하고있는 컨테이너를 commit 명령어를 사용해서 이미지로 변환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730361005897&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker commit 컨테이너_이름 새로운_이미지_이름&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방법2. Dockerfile 스크립트로 이미지 만들기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바인드 마운트 한 로컬 폴더에서 Dockerfile을 작성하고, docker환경에서 build한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1730361091301&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker build -t 생성할_이미지_이름 재료_폴더_경로

## 여기서 -t는 태그를 주는 옵션&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1730361138298&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Dockerfile 스크립트의 예시

FROM 이미지_이름
COPY 원본_경로 대상_경로
RUN 리눅스_명령어
...&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  도커 컴포즈&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ✔ 도커 컴포즈의 개념&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 시스템 구축과 관련된 명령어를 하나의 텍스트파일(YAML)에 기재해 명령어 한 번에 시스템 전체를 실행하고 종료, 폐기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 데이터베이스와 애플리케이션 컨테이너를 함께 시작하고 싶다거나, 환경을 대량으로 생성해야 할 때 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 산출물이 텍스트 파일 형태로 남는다 (관리에 유용함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 도커 컴포즈는 도커 엔진과는 별개로 따로 설치해야한다 (Windows, macOs는 아마 docker 다운로드하면서 같이 받아졌을거임. Linux만 별개 설치)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 도커 컴포즈를 사용하려면 docker-compose.yml 이름을 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - docker-componse.yml파일은 한 폴더에 하나만 있을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ✔ 도커 컴포즈 커맨드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;nbsp;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt; up command&amp;nbsp;&lt;/span&gt; : (≒ docker run) 이미지를 내려받고 컨테이너를 생성 및 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;nbsp;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt; down command&amp;nbsp;&lt;/span&gt; : (≒ docker rm) 컨테이너와 네트워크를 정지 및 삭제. 볼륨과 이미지는 삭제하지 않는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ✔ 도커 컴포즈 vs Dockerfile&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 도커 컴포즈 : 네트워크, 볼륨을 포함하여 컨테이너 run 명령어를 모아놓은 파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - Dockerfile : 네트워크나 볼륨은 포함하지 않고, 이미지를 만들기 위한 파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ✔ 도커 컴포즈 파일의 항목&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 223px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 20px;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 20px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;version&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;Docker Compose 파일의 버전을 정의합니다. 예: version: '3.8'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 16px;&quot;&gt;services&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 16px;&quot;&gt;어플리케이션의 각 서비스를 정의하는 섹션입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;image&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;사용할 Docker 이미지의 이름과 태그를 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;build&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;Dockerfile을 사용하여 이미지를 빌드하는 설정입니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;ports&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;컨테이너의 포트를 호스트와 매핑합니다. 예: &quot;호스트포트:컨테이너포트&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;volumes&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;호스트와 컨테이너 간의 데이터 공유를 위한 볼륨을 정의합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;environment&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;컨테이너에서 사용할 환경 변수를 설정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;depends_on&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;서비스 간의 의존성을 정의합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;networks&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;사용자 정의 네트워크를 설정하여 서비스 간의 통신을 관리합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;restart&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;컨테이너가 종료되었을 때 자동으로 재시작할 정책을 설정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;command&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;서비스 시작 시 실행할 명령어를 지정합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.4883%; height: 17px;&quot;&gt;healthcheck&lt;/td&gt;
&lt;td style=&quot;width: 81.5117%; height: 17px;&quot;&gt;컨테이너의 상태를 확인하기 위한 헬스 체크를 정의합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ✔ docker-compose.yml 파일 예시&lt;/p&gt;
&lt;pre id=&quot;code_1730436211828&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - &quot;80:80&quot;
    volumes:
      - ./data:/app/data
    environment:
      - NODE_ENV=production
    restart: always
    depends_on:
      - db

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ✔ 작성한 docker-compose.yml파일 실행&lt;/p&gt;
&lt;pre id=&quot;code_1730445865638&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker-compose -f 파일경로/docker-compose.yml up 옵션
docker-compose -f C:\Users\***\Documents\com_folder\docker-compose.yml up -d

# docker-compose -f 파일경로/docker-compose.yml down 옵션
docker-compose -f C:\Users\***\Documents\com_folder\docker-compose.yml down&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/DevOps</category>
      <category>Container</category>
      <category>docker</category>
      <category>docker-compose</category>
      <category>IMAGE</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/60</guid>
      <comments>https://odingcoding.tistory.com/60#entry60comment</comments>
      <pubDate>Fri, 1 Nov 2024 16:29:13 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] 도커 명령어 : 커맨드 및 옵션</title>
      <link>https://odingcoding.tistory.com/59</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;docker_icon.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rQsoI/btsKouccwkL/Kwhzp8HyfWmmCojKBako7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rQsoI/btsKouccwkL/Kwhzp8HyfWmmCojKBako7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rQsoI/btsKouccwkL/Kwhzp8HyfWmmCojKBako7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrQsoI%2FbtsKouccwkL%2FKwhzp8HyfWmmCojKBako7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;675&quot; data-filename=&quot;docker_icon.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;앞서, Docker 설치를 완료했다면 윈도우 환경에서는 CMD창을 켜서 도커 명령어를 입력할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;도커 명령어는 항상 docker ~ 로 시작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;docker~ 뒤에는 커맨드와 옵션이 따르며, 커맨드는 상위 커맨드와 하위 커맨드로 나눌 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  도커의 대표적인 명령어&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 273px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;docker 명령&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 23.2558%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;상위 커맨드&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.5814%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;하위 커맨드&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;옵션&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;비고&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 15px;&quot;&gt;
&lt;td style=&quot;width: 12.093%; height: 253px;&quot; rowspan=&quot;15&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;docker&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 23.2558%; height: 100px;&quot; rowspan=&quot;6&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;container&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.5814%; height: 15px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;start&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 15px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;-a, -i&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 15px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;실행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;stop&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;-t&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;정지&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;create&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;-a, -e, -i, -p, -v, ...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;run&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;-d, -e, -i, -t, -p, -v, ...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;create, start, pull 한 번에 수행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;exec&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;-e&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.2558%; height: 51px;&quot; rowspan=&quot;3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;image&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;pull&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;searce&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.2558%; height: 51px;&quot; rowspan=&quot;3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;volume&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;create&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;rm&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;삭제&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.2558%; height: 51px;&quot; rowspan=&quot;3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;network&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;create&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;rm&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.5814%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;...&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 13.2849%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  컨테이너 띄웠다 지우기 예제&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.698%; height: 443px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; docker run --name apa000ex1 -d httpd &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; apa000ex1 이름의 컨테이너를 백그라운드로 실행 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; Unable to find image 'httpd:latest' locally&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;... &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 44px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; docker ps &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; 실행 중인 컨테이너의 목록 확인 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 67px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 67px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; CONTAINER&amp;nbsp;ID&amp;nbsp;&amp;nbsp;&amp;nbsp;IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMMAND&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PORTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NAMES&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;9c21798676bd&amp;nbsp;&amp;nbsp;&amp;nbsp;httpd&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;httpd-foreground&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;About&amp;nbsp;a&amp;nbsp;minute&amp;nbsp;ago&amp;nbsp;&amp;nbsp;&amp;nbsp;Up&amp;nbsp;About&amp;nbsp;a&amp;nbsp;minute&amp;nbsp;&amp;nbsp;&amp;nbsp;80/tcp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;apa000ex1 &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 67px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; docker ps -a &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; 모든 컨테이너의 목록 확인 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 67px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 67px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; CONTAINER&amp;nbsp;ID&amp;nbsp;&amp;nbsp;&amp;nbsp;IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMMAND&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PORTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NAMES&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;9c21798676bd&amp;nbsp;&amp;nbsp;&amp;nbsp;httpd&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;httpd-foreground&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;About&amp;nbsp;a&amp;nbsp;minute&amp;nbsp;ago&amp;nbsp;&amp;nbsp;&amp;nbsp;Up&amp;nbsp;About&amp;nbsp;a&amp;nbsp;minute&amp;nbsp;&amp;nbsp;&amp;nbsp;80/tcp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;apa000ex1 &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 67px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;docker stop apa000ex1&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;컨테이너 종료&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;apa000ex1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;docker ps&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; 실행 중인 컨테이너의 목록 확인 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;CONTAINER&amp;nbsp;ID&amp;nbsp;&amp;nbsp;&amp;nbsp;IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMMAND&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PORTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NAMES&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;docker ps -a&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; 모든 컨테이너의 목록 확인 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;CONTAINER&amp;nbsp;ID&amp;nbsp;&amp;nbsp;&amp;nbsp;IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMMAND&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PORTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NAMES &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;9c21798676bd&amp;nbsp;&amp;nbsp;&amp;nbsp;httpd&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;httpd-foreground&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&amp;nbsp;minutes&amp;nbsp;ago&amp;nbsp;&amp;nbsp;&amp;nbsp;Exited&amp;nbsp;(0)&amp;nbsp;11&amp;nbsp;seconds&amp;nbsp;ago&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;apa000ex1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;docker rm apa000ex1&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;컨테이너 삭제&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;apa000ex1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;docker ps&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; 실행 중인 컨테이너의 목록 확인 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #f8fbfb; color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt; CONTAINER&amp;nbsp;ID&amp;nbsp;&amp;nbsp;&amp;nbsp;IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMMAND&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PORTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NAMES &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;docker ps -a&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt; 모든 컨테이너의 목록 확인 &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 73.1008%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #f8fbfb; color: #333333; text-align: start; font-family: 'Noto Sans Light';&quot;&gt; CONTAINER&amp;nbsp;ID&amp;nbsp;&amp;nbsp;&amp;nbsp;IMAGE&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;COMMAND&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PORTS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NAMES &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 19.4961%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  Apach 이미지 띄우기&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1730272179757&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run --name apa000ex2 -d -p 8080:80 httpd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- docker run : 도커 컨테이너를 생성하고 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- --name apa000ex2 : 컨테이너를 apa000ex2라는 이름으로&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- -d : 백그라운드에서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- -p 8080:80 : 호스트의 포트 8080을 컨테이너 포트 80으로 포워딩하여&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;- httpd : 아파치 이미지를 사용(버전 지정 안했으므로 최신버전)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;명령어 실행 후 http://localhost:8080/ 에 접속해보면 아파치가 띄워졌는지 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rhk84/btsKpOHmP40/tkZLYqTkWAf7aPOXvQmXAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rhk84/btsKpOHmP40/tkZLYqTkWAf7aPOXvQmXAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rhk84/btsKpOHmP40/tkZLYqTkWAf7aPOXvQmXAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frhk84%2FbtsKpOHmP40%2FtkZLYqTkWAf7aPOXvQmXAK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;208&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;호엥 신기하지만 이건 지이이인짜 기본중에 기본 너무 간단한걸 다뤄본거고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;앞으로 회사에서 도커를 다루면서 중요한걸 추가하면서 수정할 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;우선 오늘은 빵 먹을 수 있당(╹ڡ╹ )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;  정리 &lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;bull;&lt;b&gt;docker pull&lt;/b&gt; : 원격 repository에서 이미지를 로컬로 다운로드한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker run&lt;/b&gt; : 컨테이너를 생성하고 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker ps / docker ps -a&lt;/b&gt; : 현재 실행 중인 컨테이너/모든 컨테이너 목록을 보여준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker stop&lt;/b&gt; : 실행중인 컨테이너를 중지한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker rm&lt;/b&gt; : 중지된 컨테이너를 삭제한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker build&lt;/b&gt; : 지정된 디렉토리의 DockerFile을 기반으로 이미지를 생성한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker exec -it [컨테이너명] /bin/bash&lt;/b&gt; : 컨테이너 내부 디렉토리를 확인한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker inspect [컨테이너명]&lt;/b&gt; : 컨테이너 정보를 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker images&lt;/b&gt; : 이미지 목록을 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker rmi&lt;/b&gt; : 이미지를 삭제한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker network ls&lt;/b&gt; : 네트워크 목록을 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker network rm&lt;/b&gt; : 네트워크를 삭제한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker volume ls&lt;/b&gt; : 볼륨 목록을 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #333333; text-align: start;&quot;&gt;&amp;bull;&lt;b&gt;docker volume rm&lt;/b&gt; : 볼륨을 삭제한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/DevOps</category>
      <category>Apache</category>
      <category>Container</category>
      <category>docker</category>
      <category>IMAGE</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/59</guid>
      <comments>https://odingcoding.tistory.com/59#entry59comment</comments>
      <pubDate>Fri, 1 Nov 2024 16:27:47 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] 도커의 기본 개념과 장단점 &amp;amp; Windows 설치 방법(WSL 2)</title>
      <link>https://odingcoding.tistory.com/58</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;docker_icon.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rTwOp/btsKpgKdR66/o6qBUOfx2Jnd14LmU8DrI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rTwOp/btsKpgKdR66/o6qBUOfx2Jnd14LmU8DrI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rTwOp/btsKpgKdR66/o6qBUOfx2Jnd14LmU8DrI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrTwOp%2FbtsKpgKdR66%2Fo6qBUOfx2Jnd14LmU8DrI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;675&quot; data-filename=&quot;docker_icon.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  Docker의 기본 개념 이해&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ 컨테이너 (Container)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 애플리케이션을 독립적으로 실행할 수 있는 가벼운 환경&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 실제 사용하는 것 (≒ 빵)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;b&gt; ✔ 이미지 (Image)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 컨테이너의 실행 파일 및 종속성을 포함한 템플릿&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 간단히 설명하면 이미지는 컨테이너를 만드는 '빵틀'과 같다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 사용자는 빵틀이 아닌 빵틀로 만들어낸 빵을 원한다. 즉, 이미지 자체로는 큰 쓸모가 없으며 컨테이너를 만드는데 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ Docker Daemon&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - Docker의 백그라운드에서 실행되는 프로세스&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ Docker CLI&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 커맨드라인에서 Docker와 상호작용하기 위한 명령어 도구&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ Docker Hub&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - Docker 이미지의 공식 저장소&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ 마운트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 디스크를 연결해 데이터를 기록할 수 있도록 한 상태&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - &lt;b&gt;'볼륨을 마운트한다'&lt;/b&gt; : &lt;b&gt;호스트 시스템의 디렉토리나 파일을 도커 컨테이너에 연결&lt;/b&gt;하여, 컨테이너가 그 디렉토리나 파일에 접근하고 사용할 수 있게 만드는 것을 의미 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ 호스트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 도커가 설치된 물리적 서버&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ 볼륨 (Volume)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 컨테이너와 호스트 간의 데이터를 공유하기 위한 방법. 컨테이너가 삭제되어도 데이터가 유지된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ✔ 데이터 퍼시스턴시 (Data Persistency)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 컨테이너는 생성 및 폐기가 매우 빈번하므로 매번 데이터를 옮기는 대신 애초에 컨테이너 외부에 데이터를 둔다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &lt;b&gt;✔ 네트워크 (Network)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 여러 컨테이너 간의 통신을 위한 네트워크 구성을 정의한다. 기본적으로 브릿지, 호스트, 오버레이 등 여러 네트워크 모드를 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;b&gt; ✔ 오케스트레이션 (Orchestration)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - 여러 개의 컨테이너를 효과적으로 관리하고 자동화하기 위해 사용하는 기술. 대표적인 도구로 Kubernetes, Docker Swarm등이 있음&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ CMD와 ENTRYPOINT&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - CMD와 ENTRYPOINT는 Docker컨테이너가 실행될 때 수행할 기본 명령어를 지정한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - CMD는 인자처럼 변경이 가능하고&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - ENTRYPOINT는 고정된 명령어로 설정된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&amp;nbsp; ✔ 데몬 (Daemon)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; - 유닉스 또는 리눅스에서 동작하는 프로그램 중에서 백그라운드에서 항상 동작하는 프로그램을 관례적으로 일컬어 데몬이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  컨테이너&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;✔ 컨테이너의 생애주기?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; - 컨테이너는 쉽게 만들 수 있기 때문에 오래된 컨테이너를 유지보수 하는 수고보다 새로 만드는 것이 덜 수고스럽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; - 컨테이너를 만들고 &amp;rarr; 실행하고 &amp;rarr; 종료하고 &amp;rarr; 폐기하는 과정이 컨테이너의 생애 주기이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; - 하지만 폐기하기 전, 데이터가 존재한다면 도커가 설치된 물리적 서버(호스트)의 디스크를 마운트해 데이터를 저장해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;✔ 컨테이너의 로그 관리&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; - Docker는 기본적으로 컨테이너의 표준 출력 로그를 관리한다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; - docker logs 명령어를 사용해 로그를 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; &amp;zwj;♀️ 도커의 장단점&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;✔ 도커의 장점&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;background-color: #ef5369; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;nbsp;&quot;환경을 격리할 수 있다&quot; &lt;/b&gt;&lt;/span&gt;는 핵심이 되는 성질 덕분에 아래와 같은 장점을 가진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;1. 독립된 환경&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 독립된 환경으로 여러 개의 컨테이너를 띄울 수 있으며, 똑같은 애플리케이션도 여러 개 띄울 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;b&gt; 2. 이미지 생성 및 배포&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 이미지를 만들고 도커허브에 배포하여 사용할 수 있으므로 교체가 쉽고, 업데이트가 간편하다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 또한, 이미지를 사용해 이동이 쉬우므로 똑같은 컨테이너를 쉽게 만들거나 환경 이동, 개발환경 구축이 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;3. 커널이 없다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 운영체제의 핵심이 되는 커널을 포함시킬 필요가 없으므로 소프트웨어적으로 하드웨어를 재현하는 가상화 기술에 비하면 압도적으로 가볍다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;✔ 도커의 단점&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;1. 리눅스 한정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 리눅스 운영체제를 사용하는 기술이므로 리눅스용 소프트웨어밖에 지원하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;b&gt; 2. 물리서버 한 대에 여러 대의 서버를 띄우는 형태&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 호스트 서버에 문제가 생기면 모든 컨테이너에 영향을 미친다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;3. 단일 컨테이너라면 장점을 느끼기 힘들다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 단일 컨테이너라면 도커 엔진이 단순한 오버헤드에 지나지 않기 때문에 컨테이너를 여러 개 사용하는 형태를 가정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  윈도우 설치 방법&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;1. 제어판 항목 활성화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - 제어판 &amp;gt; 프로그램 &amp;gt; 프로그램 및 기능 &amp;gt; Windows 기능 켜기/끄기 접속&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - &lt;b&gt;[Linux용 Windows 하위시스템]&lt;/b&gt; 과 &lt;b&gt;[가상 머신 플랫폼]&lt;/b&gt; 기능을 체크한 뒤 확인버튼 클릭&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - PC 재부팅&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;설치1.png&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7aJWb/btsKoToYiWP/nOJ0kbuDXwjB3ieB8daNqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7aJWb/btsKoToYiWP/nOJ0kbuDXwjB3ieB8daNqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7aJWb/btsKoToYiWP/nOJ0kbuDXwjB3ieB8daNqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7aJWb%2FbtsKoToYiWP%2FnOJ0kbuDXwjB3ieB8daNqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;351&quot; height=&quot;483&quot; data-filename=&quot;설치1.png&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;2. 리눅스 커널 업데이트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi&lt;/a&gt; 접속 후 다운 및 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;3. 윈도우용 Docker 다운로드 및 설치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - &lt;a href=&quot;https://docs.docker.com/docker-for-windows/install&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.docker.com/docker-for-windows/install&lt;/a&gt; 접속 후 다운 및 설치파일 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - 환경 설정 항목 모두 체크표시 후 [OK] 버튼 클릭&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - 설치완료 후 [Close and log out] 버튼을 클릭해 윈도우에 다시 로그인 (여기서 블로그 백업을 안해서 캡처본이 다 날아감 ಥ_ಥ)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;4. Docker Subscription 동의&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; - Accept 버튼 클릭&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;시작1.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;625&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GRIr3/btsKqzo0fw3/CIGZPPqtEVOYSnRJBGux9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GRIr3/btsKqzo0fw3/CIGZPPqtEVOYSnRJBGux9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GRIr3/btsKqzo0fw3/CIGZPPqtEVOYSnRJBGux9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGRIr3%2FbtsKqzo0fw3%2FCIGZPPqtEVOYSnRJBGux9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;346&quot; data-filename=&quot;시작1.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;625&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;5. Use recommended settings 체크 후 Finish&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;시작2.png&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;1025&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGFR7p/btsKqB1q9BD/2ONGUxKNtkiXJgw4ZkFhZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGFR7p/btsKqB1q9BD/2ONGUxKNtkiXJgw4ZkFhZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGFR7p/btsKqB1q9BD/2ONGUxKNtkiXJgw4ZkFhZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGFR7p%2FbtsKqB1q9BD%2F2ONGUxKNtkiXJgw4ZkFhZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;474&quot; data-filename=&quot;시작2.png&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;1025&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;6. 계정 로그인 (없으면 간단히 회원가입 가능!)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;시작3.png&quot; data-origin-width=&quot;1671&quot; data-origin-height=&quot;973&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l2Nwj/btsKo0amR7o/YahgxsSIbkHFGnStZBP8t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l2Nwj/btsKo0amR7o/YahgxsSIbkHFGnStZBP8t1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l2Nwj/btsKo0amR7o/YahgxsSIbkHFGnStZBP8t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl2Nwj%2FbtsKo0amR7o%2FYahgxsSIbkHFGnStZBP8t1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;415&quot; data-filename=&quot;시작3.png&quot; data-origin-width=&quot;1671&quot; data-origin-height=&quot;973&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;7. 쨔란~✨&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1589&quot; data-origin-height=&quot;900&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D2JAC/btsKp5Pk9Ts/zvloargwvkJ4ZP4RlHV56k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D2JAC/btsKp5Pk9Ts/zvloargwvkJ4ZP4RlHV56k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D2JAC/btsKp5Pk9Ts/zvloargwvkJ4ZP4RlHV56k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD2JAC%2FbtsKp5Pk9Ts%2FzvloargwvkJ4ZP4RlHV56k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;703&quot; height=&quot;398&quot; data-origin-width=&quot;1589&quot; data-origin-height=&quot;900&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;  내가 WSL 2를 사용하고 있나 궁금하다면 해당 대쉬보드 우측 상단에 setting접속 &amp;gt; General &amp;gt; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Use the WSL 2 based engine 항목에 체크되어있나 확인&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt; &amp;rarr; 체크안되어있으면 도커 엔진이 Hyper-V를 통해 동작하고 있음&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start; font-family: 'Noto Sans Light';&quot;&gt;도커의 조작 및 컨테이너 생성 작업들은 추후 게시글에 업로드하기 안하면 앞으로 빵 없음 (내자신과의 약속임)&lt;/span&gt;&lt;/p&gt;</description>
      <category>Programming/DevOps</category>
      <category>Container</category>
      <category>docker</category>
      <category>IMAGE</category>
      <category>linux</category>
      <author>오딩이</author>
      <guid isPermaLink="true">https://odingcoding.tistory.com/58</guid>
      <comments>https://odingcoding.tistory.com/58#entry58comment</comments>
      <pubDate>Wed, 30 Oct 2024 10:59:03 +0900</pubDate>
    </item>
  </channel>
</rss>