<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발일지</title>
    <link>https://chaechaeros.tistory.com/</link>
    <description>중요한 것은 꺾여도 그냥 하는 마음</description>
    <language>ko</language>
    <pubDate>Fri, 26 Jun 2026 19:44:06 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>째로스</managingEditor>
    <image>
      <title>개발일지</title>
      <url>https://tistory1.daumcdn.net/tistory/5540974/attach/3dd7c9c1e2334de387336aeacb7f81a4</url>
      <link>https://chaechaeros.tistory.com</link>
    </image>
    <item>
      <title>Docker, Jenkins, Nginx를 활용한 CI/CD 구축 (1)</title>
      <link>https://chaechaeros.tistory.com/234</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;구성한 프로젝트 아키텍쳐&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;766&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/liPxY/btsJcAb8Yqa/ydKYe2F5wp9oA3Gac2PVY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/liPxY/btsJcAb8Yqa/ydKYe2F5wp9oA3Gac2PVY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/liPxY/btsJcAb8Yqa/ydKYe2F5wp9oA3Gac2PVY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FliPxY%2FbtsJcAb8Yqa%2FydKYe2F5wp9oA3Gac2PVY0%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;601&quot; height=&quot;371&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;766&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;- Blue Green 무중단 배포를 위해 Spring 서버와 React 서버를 각각 포트 2개씩 사용했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Dockerfile을 사용해 docker hub에 현재 파일을 업로드하여 버전 관리를 했습니다.&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;b&gt;무중단 CI/CD 구축을 위한 과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. EC2에 Docker 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. EC2에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Docker로&lt;span&gt; &lt;/span&gt;&lt;/span&gt;Jenkins 띄우기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. EC2에 Nginx 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. https 접근을 위한 Nginx 인증서 설정(SSL 인증서)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Jenkins에서 GitLab 접근을 위한 GitLab 토큰 발급&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Jenkins에서 GitLab 접근 플러그인 설치 및 접근 토큰/GitLab 계정 등록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. Jenkins 파이프라인 작성&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;/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;b&gt;1. EC2에 Docker 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Docker : 애플리케이션을 컨테이너라는 가벼운 독립 실행 환경에서 실행할 수 있도록 해주는 오픈 소스 플랫폼&lt;/p&gt;
&lt;pre id=&quot;code_1724311051159&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 의존성 설치
sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release

# 레포지토리
sudo mkdir -p /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 레포지토리 추가
echo &quot;deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release &amp;amp;&amp;amp; echo &quot;$VERSION_CODENAME&quot;) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null

# 도커 설치하기
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin&lt;/code&gt;&lt;/pre&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;b&gt;2. EC2에 Docker로 Jenkins 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Jenkins : 소프트웨어 개발에서 지속적인 통합(CI) 및 지속적인 배포(CD) 프로세스를 자동화하기 위해 사용되는&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; 오픈 소스 자동화 서버&lt;/p&gt;
&lt;pre id=&quot;code_1724311134054&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 도커 소켓 마운트 하기 (젠킨스 컨테이너에서 도커 명령어 실행되도록 하기)
sudo docker run -itd --name jenkins -p 9005:8080 -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker jenkins/jenkins:jdk21

# 도커 명령어가 젠킨스에서 실행이 안되거나 권한 오류가 나면 아래 명령어 실행
sudo chmod 666 /var/run/docker.sock

# 젠킨스 컨테이너 비밀번호 확인 명령어
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

# 젠킨스 컨테이너로 접속해서 도커 명령어 실행 여부 확인 명령어
docker ps
docker exec -it &amp;lt;container_name_or_id&amp;gt; /bin/bash
docker exec -it jenkins /bin/bash

# 젠킨스 컨테이너에 접속해서 Docker 명령어 되는지 확인
docker ps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Jenkins는 Nginx를 통해 별도의 설정을 하지 않기때문에, https가 아닌 http로 접속해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 9005:8080는 외부에서 9005번 포트로 접근하지만, 실제 내부에서는 8000번 포트로 접근함을 의미합니다.&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-origin-width=&quot;1252&quot; data-origin-height=&quot;839&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPwnOQ/btsJHxtvGJ8/Lc7zx33nPsg4QTnb7QzIc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPwnOQ/btsJHxtvGJ8/Lc7zx33nPsg4QTnb7QzIc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPwnOQ/btsJHxtvGJ8/Lc7zx33nPsg4QTnb7QzIc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPwnOQ%2FbtsJHxtvGJ8%2FLc7zx33nPsg4QTnb7QzIc0%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;412&quot; height=&quot;276&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;839&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인터넷 브라우저에서 &amp;lt;url&amp;gt;:9005 을 입력하면 위와 같은 화면을 마주할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1727063204508&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 위 입력을 통해 패스워드를 얻어내고, 값을 붙여놓습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/canvS2/btsJJws1qsG/woflMOsxsSfeFSUu2KzHuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/canvS2/btsJJws1qsG/woflMOsxsSfeFSUu2KzHuk/img.png&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;837&quot; data-is-animation=&quot;false&quot; width=&quot;361&quot; height=&quot;241&quot; style=&quot;width: 40.445%; margin-right: 10px;&quot; data-widthpercent=&quot;40.92&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/canvS2/btsJJws1qsG/woflMOsxsSfeFSUu2KzHuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcanvS2%2FbtsJJws1qsG%2FwoflMOsxsSfeFSUu2KzHuk%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;1256&quot; height=&quot;837&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r08or/btsJInwMx6Y/4bTUofvpuHcQ464ykjqBwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r08or/btsJInwMx6Y/4bTUofvpuHcQ464ykjqBwk/img.png&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;877&quot; data-is-animation=&quot;false&quot; width=&quot;435&quot; height=&quot;201&quot; style=&quot;width: 58.3922%;&quot; data-widthpercent=&quot;59.08&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r08or/btsJInwMx6Y/4bTUofvpuHcQ464ykjqBwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr08or%2FbtsJInwMx6Y%2F4bTUofvpuHcQ464ykjqBwk%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;1900&quot; height=&quot;877&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Install suggested plugins 를 선택한 뒤, 플러그인 설치 후 계정 값을 입력하면 오른쪽 페이지가 등장합니다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1033&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kPSMX/btsJcnRPhnF/KUOnE9u6SVKfJ4k33GdK21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kPSMX/btsJcnRPhnF/KUOnE9u6SVKfJ4k33GdK21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kPSMX/btsJcnRPhnF/KUOnE9u6SVKfJ4k33GdK21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkPSMX%2FbtsJcnRPhnF%2FKUOnE9u6SVKfJ4k33GdK21%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;567&quot; height=&quot;1033&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1033&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 플러그인 설치 시 입력했던 계정으로 다음부터 로그인할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. EC2에 Nginx 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;Nginx : 고성능 웹 서버이자 리버스 프록시 서버, 그리고 로드 밸런서 및 HTTP 캐시로도 사용할 수 있는 오픈 소스 소프트웨어&lt;/p&gt;
&lt;pre id=&quot;code_1724311338682&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update
sudo apt upgrade
sudo apt install nginx
sudo service nginx start
sudo service nginx status&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 4. https 접근을 위한 Nginx 인증서 설정(SSL 인증서)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;0) ssl 인증을 위한 nginx 설정&lt;/p&gt;
&lt;pre id=&quot;code_1727099298610&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo vi /etc/nginx/sites-available/default&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1727099326996&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        server_name &amp;lt;EC2 도메인주소 또는 IP주소&amp;gt; &amp;lt;www.EC2 도메인주소 또는 IP주소&amp;gt;;

        location / {
                try_files $uri $uri/ =404;
        }

        location /.well-known/acme-challenge/ {
                root /var/www/html;
        }
}&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;1) 20 이전의 우분투 버전에서의 certbot 설치 명령어&lt;/p&gt;
&lt;pre id=&quot;code_1724311706568&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://dl.eff.org/certbot-auto&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;2) 20 이상의 우분투 버전에서의 certbot 설치 명령어&lt;/p&gt;
&lt;pre id=&quot;code_1724311740497&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# snap을 이용하여 core 설치 -&amp;gt; snap을 최신 버전으로 유지하기 위해 설치
sudo snap install core

# core를 refresh 해준다.
sudo snap refresh core

# 기존에 잘못된 certbot이 설치되어있을 수도 있으니 삭제 해준다.
sudo apt remove certbot

# certbot 설치
sudo snap install --classic certbot

# certbot 명령을 로컬에서 실행할 수 있도록 snap의 certbot 파일을 로컬의 cerbot과 링크(연결) 시켜준다. -s 옵션은 심볼릭링크를 하겠다는 것.
ln -s /snap/bin/certbot /usr/bin/certbot&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) &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;certbot을 이용해 ssl 인증서를 받아온 뒤 cerbot이 스스로 nginx설정을 해주도록 하는 명령어&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724312040562&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt install python3-certbot-nginx

sudo certbot --nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;- 명령어 입력 후, 질문에 맞춰 답변을 해주면된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;- &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;domain을 입력하라는 질문에서는 본인이 사용할 Domain을 입력해주면 된다.&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;- 만약 실패한다면 ufw에서 80, 443 포트가 열려있는지 확인합니다.&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;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;4) 정상적으로 성공한 모습&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724312120248&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Your existing certificate has been successfully renewed, and the new certificate
has been installed.

The new certificate covers the following domains: https://{내가 입력한 도메인} # https가 설정된 도메인을 알려준 것.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Subscribe to the EFF mailing list (email: woorimprog@gmail.com).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/idu-market.shop/fullchain.pem # 공개키 경로이므로 기억해두자.
   Your key file has been saved at:
   /etc/letsencrypt/live/idu-market.shop/privkey.pem # 비밀키 경로이므로 기억해두자.
   Your certificate will expire on 2021-08-15. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again with the &quot;certonly&quot; option. To non-interactively
   renew *all* of your certificates, run &quot;certbot renew&quot;
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le&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;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;5) https가 적용된 내 도메인과 비밀키, 공개키가 저장된 경로&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724312233437&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. https가 설정된 도메인
https://{내가 입력한 도메인 주소}

2. 공개키 경로
/etc/letsencrypt/live/{내가 입력한 도메인 주소}/fullchain.pem

3. 비밀키 경로
 /etc/letsencrypt/live/{내가 입력한 도메인 주소}/privkey.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;6) 결과 확인&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724312308736&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;

        server_name j11b204.p.ssafy.io www.j11b204.p.ssafy.io;

        location / {
                try_files $uri $uri/ =404;
        }

        location /.well-known/acme-challenge/ {
                root /var/www/html;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/j11b204.p.ssafy.io/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/j11b204.p.ssafy.io/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


# 80 포트로 접근시 443 포트로 리다이렉트 시켜주는 설정
# certbot에서 2번 선택지 선택 시에 적용되는 설정입니다.
server {
        if ($host = {내가 입력한 도메인 이름}) {
                return 301 https://$host$request_uri;
        } # managed by Certbot


        listen 80;
        server_name {내가 입력한 도메인 이름};
        return 404; # managed by Certbot
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;- 5번까지의 과정을 잘 입력했다면, 위와 같이 자동으로 Nginx의 설정이 변한 것을 확인할 수 있다.&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;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;7) SSL 인증서&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;갱신 방법&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;- &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;certbot을 이용하여 ssl인증서를 발급할 경우 3개월 마다 갱신을 해줘야 한다.&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724312440825&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;certbot renew&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp;- 일정 기간마다 자동으로 인증서를 갱신시키기 위해서는 아래의 링크를 참고바란다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;(&lt;a href=&quot;https://devlog.jwgo.kr/2019/04/16/how-to-lets-encrypt-ssl-renew/&quot;&gt;https://devlog.jwgo.kr/2019/04/16/how-to-lets-encrypt-ssl-renew/&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;a href=&quot;https://gist.github.com/woorim960/dda0bc85599f61a025bb8ac471dfaf7a&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gist.github.com/woorim960/dda0bc85599f61a025bb8ac471dfaf7a&lt;/a&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;b&gt; 5. Jenkins에서 GitLab 접근을 위한 GitLab 토큰 발급 &lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQVY4s/btsJdkGAiHe/99jwFkAK3WMXP5HfKrKL3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQVY4s/btsJdkGAiHe/99jwFkAK3WMXP5HfKrKL3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQVY4s/btsJdkGAiHe/99jwFkAK3WMXP5HfKrKL3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQVY4s%2FbtsJdkGAiHe%2F99jwFkAK3WMXP5HfKrKL3k%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;687&quot; height=&quot;329&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&amp;nbsp;- Setting &amp;gt; Access Tokens &amp;gt; Add new token 를 클릭한다.&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;1219&quot; data-origin-height=&quot;870&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCRsPx/btsJcJNNxpv/VdPTcSUww7FVKeYnXnRsNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCRsPx/btsJcJNNxpv/VdPTcSUww7FVKeYnXnRsNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCRsPx/btsJcJNNxpv/VdPTcSUww7FVKeYnXnRsNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCRsPx%2FbtsJcJNNxpv%2FVdPTcSUww7FVKeYnXnRsNk%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;700&quot; height=&quot;500&quot; data-origin-width=&quot;1219&quot; data-origin-height=&quot;870&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ia8MQ/btsJbOoRm5y/GX1kdbmPK1f8akKoV3Osnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ia8MQ/btsJbOoRm5y/GX1kdbmPK1f8akKoV3Osnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ia8MQ/btsJbOoRm5y/GX1kdbmPK1f8akKoV3Osnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIa8MQ%2FbtsJbOoRm5y%2FGX1kdbmPK1f8akKoV3Osnk%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;694&quot; height=&quot;117&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 위 과정을 통해 GitLab에 접근할 수 있는 토큰을 제작할 수 있다.&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;b&gt; 6. Jenkins에서 GitLab 접근 플러그인 설치 및 접근 토큰/GitLab 계정 등록&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;1) GitLab 플러그인 설치 ( Dashboard &amp;gt; Jenkins 관리 &amp;gt; Plugins &amp;gt; Available plugins 검색창에 'gitlab' 입력 후 해당 플러그인 설치 )&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mr4VL/btsJcG4ELNf/5kcGhnqBv8k6t7YLTknEP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mr4VL/btsJcG4ELNf/5kcGhnqBv8k6t7YLTknEP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mr4VL/btsJcG4ELNf/5kcGhnqBv8k6t7YLTknEP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmr4VL%2FbtsJcG4ELNf%2F5kcGhnqBv8k6t7YLTknEP0%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;785&quot; height=&quot;240&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;491&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;2) GitLab 계정 및 API 접근 토큰 Credential에 등록&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1740&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVQQ2o/btsJdkNpuVk/1Vltomt3w42U5j6lmaFRB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVQQ2o/btsJdkNpuVk/1Vltomt3w42U5j6lmaFRB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVQQ2o/btsJdkNpuVk/1Vltomt3w42U5j6lmaFRB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVQQ2o%2FbtsJdkNpuVk%2F1Vltomt3w42U5j6lmaFRB1%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;1740&quot; height=&quot;230&quot; data-origin-width=&quot;1740&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Dashboard &amp;gt; Jenkins 관리 &amp;gt; Credentials &amp;gt; System &amp;gt; Global credentials (unrestriced) &amp;gt; '+ Add Credentials' 버튼 클릭&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;3) GitLab 계정 정보 Jenkins에 등록&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIheis/btsJcAcrgk6/cIE6x3nIt54k1Zm4wHYnX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIheis/btsJcAcrgk6/cIE6x3nIt54k1Zm4wHYnX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIheis/btsJcAcrgk6/cIE6x3nIt54k1Zm4wHYnX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIheis%2FbtsJcAcrgk6%2FcIE6x3nIt54k1Zm4wHYnX0%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;433&quot; height=&quot;418&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Kind : Username with password&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Scope : Global&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Username : GitLab 아이디&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Password : GitLab에서 발급받은 Personal Access Token&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ID : 추후 파이프라인에서 불러올 때 사용할 닉네임(저는 'GitLab_User' 라고 명칭하겠습니다.)&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;4) GitLab API 접근 토큰 Jenkins에 등록&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vcuXU/btsJb6bOhR9/mKgVgskwsheVkYdUJuB3Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vcuXU/btsJb6bOhR9/mKgVgskwsheVkYdUJuB3Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vcuXU/btsJb6bOhR9/mKgVgskwsheVkYdUJuB3Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvcuXU%2FbtsJb6bOhR9%2FmKgVgskwsheVkYdUJuB3Ck%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;446&quot; height=&quot;274&quot; data-origin-width=&quot;987&quot; data-origin-height=&quot;607&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Kind : GitLab API token&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Scope : Global&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- API token : 위 GitLab에서 발급받은 access token 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 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;&amp;nbsp;5) GitLab, Jenkins 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Dashboard &amp;gt; Jenkins 관리 &amp;gt; System&amp;nbsp; 이동 후, 스크롤을 내려서 GitLab 파트로 이동&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;911&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IzubN/btsJc3LUkbj/kwqYaRrB4qS7dv2xpkSYxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IzubN/btsJc3LUkbj/kwqYaRrB4qS7dv2xpkSYxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IzubN/btsJc3LUkbj/kwqYaRrB4qS7dv2xpkSYxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIzubN%2FbtsJc3LUkbj%2FkwqYaRrB4qS7dv2xpkSYxk%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;746&quot; height=&quot;393&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;911&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Connection name : 원하는 값 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- GitLab host URL : 내가 만든 GitLab의 레포지토리 URL이 아닌 사용 중인 GitLab의 기본 URL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Credential : 앞서 Jenkins에 등록한 GitLab AccessToken&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;-&amp;gt; 입력 후 Test &amp;gt; Success &amp;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;b&gt; 7. Jenkins 파이프라인 구축&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dashboard &amp;gt; All &amp;gt; New Item&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;871&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cplk5F/btsJJu31QoA/84JhyURVpvuGcX3QzVqFVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cplk5F/btsJJu31QoA/84JhyURVpvuGcX3QzVqFVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cplk5F/btsJJu31QoA/84JhyURVpvuGcX3QzVqFVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcplk5F%2FbtsJJu31QoA%2F84JhyURVpvuGcX3QzVqFVK%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;506&quot; height=&quot;302&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;871&quot;/&gt;&lt;/span&gt;&lt;/figure&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;- 파이프라인 선택 후 OK&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-origin-width=&quot;1258&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xzAy3/btsJIoXIG3L/N3klQstZ0JETjGTrkfK1L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xzAy3/btsJIoXIG3L/N3klQstZ0JETjGTrkfK1L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xzAy3/btsJIoXIG3L/N3klQstZ0JETjGTrkfK1L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxzAy3%2FbtsJIoXIG3L%2FN3klQstZ0JETjGTrkfK1L0%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;612&quot; height=&quot;321&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;769&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brhyJL/btsJI3r5Hgn/akQTgIx8HEgJ2QqILamTnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brhyJL/btsJI3r5Hgn/akQTgIx8HEgJ2QqILamTnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brhyJL/btsJI3r5Hgn/akQTgIx8HEgJ2QqILamTnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrhyJL%2FbtsJI3r5Hgn%2FakQTgIx8HEgJ2QqILamTnk%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;597&quot; height=&quot;376&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;769&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- OK 이후 스크롤을 내려 위 설정을 맞춥니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Secret token을 Generate 버튼을 통해 생성하고, 이를 보관해둡니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1727105595962&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 {
	    stage('Git Clone'){
            steps {
                git branch: 'backend', credentialsId: 'GitLab_User', url: 'https://test.com/test/project.git'
            }
            post {
                failure {
                  echo 'Repository clone failure !'
                }
                success {
                  echo 'Repository clone success !'
                }
            }
	    }
	}
}&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;8. WebHook 등록&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1887&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAwK3Z/btsJJKS3FHp/GV9Bfbu6gjuIO2xkV3KZZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAwK3Z/btsJJKS3FHp/GV9Bfbu6gjuIO2xkV3KZZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAwK3Z/btsJJKS3FHp/GV9Bfbu6gjuIO2xkV3KZZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAwK3Z%2FbtsJJKS3FHp%2FGV9Bfbu6gjuIO2xkV3KZZk%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;1887&quot; height=&quot;508&quot; data-origin-width=&quot;1887&quot; data-origin-height=&quot;508&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;Settings &amp;gt; Webhooks &amp;gt; Add new webhook&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;URL : 위에서 등록한 items &amp;gt; 구성 &amp;gt; Build Triggers &amp;gt; webhook URL 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Secret token : 위 items 작성에서 Generate 버튼 클릭을 통해 생성해낸 token 입력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Trigger : Push event &amp;amp; Merge request event Click&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;gt; test 브랜치만 설정해두고 싶다면 wildcard 버튼 클릭 후 test 를 입력합니다.&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;- 위처럼 webhook을 등록했다면, 위 그림에서 Test &amp;gt; Push events 를 통해 웹훅을 날릴 수 있습니다.&lt;/p&gt;</description>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/234</guid>
      <comments>https://chaechaeros.tistory.com/234#entry234comment</comments>
      <pubDate>Thu, 22 Aug 2024 17:48:01 +0900</pubDate>
    </item>
    <item>
      <title>도커 허브(DockerHub)</title>
      <link>https://chaechaeros.tistory.com/233</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Docker Hub&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 많이 사용되는 Public Image Registry로 깃허브가 소스코드를 저장하는 저장소라면,&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;/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;/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;- 파이프라인 : DevOps 파이프라인 기능과 연계하여 자동 배포가 가능하도록 연계하거나 알림 기능 제공&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;1) 도커가 설치되어 있는 호스트 머신의 로컬스토리지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 주로 기업에서 사용하는 프라이빗 레지스트리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 도커 허브와 같은 퍼블릭 레지스트리&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Private Registry : 특정한 네트워크에서만 접근이 가능한 레지스트리(사내망)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - Public Registry : 모든 네트워크에서 접근이 가능한 레지스트리(Docker Hub)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;=&amp;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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 컨테이너 실행 시 이미지의 이름을 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;ex ) docker run nginx&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 먼저 호스트 머신의 로컬스토리지에 해당 이미지가 있는지 검색&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;4) 로컬 스토리지에 있었거나 다운로드한 이미지를 사용해서 컨테이너를 실행시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5) 이 다음부터는 온라인 레지스트리에 접곤하지 않고도 로컬 스토리지에 이미지가 존재하기 때문에 바로 컨테이너로 실행이 가능하다.&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;/p&gt;
&lt;pre id=&quot;code_1721795179714&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;레지스트리주소/프로젝트명/이미지명:이미지태그&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;1) 레지스트리 주소 : 어떤 레지스트리에서 이미지를 다운로드할지 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- 아무것도 적지 않으면 도커 허브의 레지스트리 주소인 docker.io가 기본값으로 지정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2) 프로젝트명 : 이미지를 보관하는 폴더&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;- 도커 허브를 사용하면서 프로젝트명을 입력하지 않으면 도커사가 별도 제공하는 library 폴더가 기본값으로 지정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;3) 이미지명 : 다운로드 받을 이미지의 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;4) 이미지태그 : 다운로드 받을 이미지의 버전&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- 아무것도 적지 않으면 최신버전을 의미하는 latest가 기본값으로 지정된다.&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; ex1)&amp;nbsp; chaeros.com/myProject/myNginx:2.1.0-alpine&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;=&amp;gt; chaeros.com이라는 레지스트리에서 myProject라는 프로젝트의 myNginx라는이미지를 2.1.0-alpine 버전으로 다운&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ex2) chaeros/myImage&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;=&amp;gt; 도커 허브에서 chaeros라는 계정의 myImage 이미지를 최신 버전으로 다운로드한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ex3) nginx&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;=&amp;gt; 도커사가 직접 검증한 이미지는 오피셜 이미지로 지정하여, 라이브러리라는 프로젝트에서 별도 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;따라서 별도의 계정명을 입력하지 않았을 경우, library가 기본값으로 지정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;그렇기에 프로젝트명을 비워두면 docker.io의 library 폴더에 있는 이미지를 다운로드 하게 되는 것이다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 로컬 스토리지로 이미지 다운로드&lt;/p&gt;
&lt;pre id=&quot;code_1721796963528&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker pull {이미지명}&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. 로컬스토리지의 이미지명 추가&lt;/p&gt;
&lt;pre id=&quot;code_1721797039391&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker tag {기존이미지명} {추가할이미지명}&lt;/code&gt;&lt;/pre&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;- 이미지명을 바꾸는 이유는 프로젝트의 이름을 바꾸고 다른 레지스트리로 전송하기 위해서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; (도커허브에서 프로젝트의 이름은 도커 사용자의 계정명인데, 해당 이미지를 내 이미지 레지스트리로 옮기고 싶을 때 tag 명령을 통해 이미지의 프로젝트명을 변경하고, 내 이미지 레지스트리로 push하여 업로드할 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 이름만 바꿨기 때문에 이미지의 ID는 동일하다. 이미지의 ID가 동일하다는 것은 실제로 파일이 하나만 있다는 의미다.&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;3. 이미지 레지스트리에 이미지 업로드&lt;/p&gt;
&lt;pre id=&quot;code_1721797049140&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker push {이미지명}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 내 Hub에 push한다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/riylp/btsIK5KTo5V/fxbZ5qcXLrbd1fowBO4mQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/riylp/btsIK5KTo5V/fxbZ5qcXLrbd1fowBO4mQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/riylp/btsIK5KTo5V/fxbZ5qcXLrbd1fowBO4mQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Friylp%2FbtsIK5KTo5V%2FfxbZ5qcXLrbd1fowBO4mQ0%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;607&quot; height=&quot;496&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;496&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;4. 이미지 레지스트르 인증 정보 생성&lt;/p&gt;
&lt;pre id=&quot;code_1721797659572&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker login&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;5. 이미지 레지스트르 인증 정보 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1721797669261&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker logout&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;6. 로컬 스토리지의 이미지 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1721797681373&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker image rm {이미지명}&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 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;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[이 블로그에 정리된 Docker 관련 자료는 인프런 데브위키님의 강의 내용을 바탕으로 작성되었습니다.]&lt;/p&gt;
&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #24292f;&quot;&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot;&gt;https://inf.run/Apgvc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1721799622000&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&quot; data-og-description=&quot;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/Apgvc&quot; data-og-url=&quot;https://www.inflearn.com/course/개발자를-위한-쉬운-도커&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SvJHY/hyWCPOC11w/JoJuc8nJ0t0WRXlVOY3apK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/8hnj3/hyWG0Ovzpj/PKvEclgEK8GR3pQggfOYZK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/9OZeX/hyWGN9sQDD/KAmy6Hz7gogGePcRN3yHUk/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/Apgvc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SvJHY/hyWCPOC11w/JoJuc8nJ0t0WRXlVOY3apK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/8hnj3/hyWG0Ovzpj/PKvEclgEK8GR3pQggfOYZK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/9OZeX/hyWGN9sQDD/KAmy6Hz7gogGePcRN3yHUk/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>Docker</category>
      <category>Docker hub</category>
      <category>도커 허브</category>
      <category>이미지 네이밍</category>
      <category>이미지 레지스트리</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/233</guid>
      <comments>https://chaechaeros.tistory.com/233#entry233comment</comments>
      <pubDate>Wed, 24 Jul 2024 14:40:27 +0900</pubDate>
    </item>
    <item>
      <title>이미지의 메타데이터</title>
      <link>https://chaechaeros.tistory.com/232</link>
      <description>&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;&amp;nbsp;- 이미지가 실제로 압축된 데이터라면, 메타데이터는 이미지에 대한 정보를 기술하는 데이터를 뜻한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ex) 이미지에 대한 이름 및 사이즈 등의 정보를 담고있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xyM2q/btsIB4ZCnl0/MvAUYhwQlbd265Dx7AjZWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xyM2q/btsIB4ZCnl0/MvAUYhwQlbd265Dx7AjZWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xyM2q/btsIB4ZCnl0/MvAUYhwQlbd265Dx7AjZWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxyM2q%2FbtsIB4ZCnl0%2FMvAUYhwQlbd265Dx7AjZWK%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;662&quot; height=&quot;240&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;240&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;- Env: 소프트웨어가 실행할 때 사용할 설정 정보&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 1) VERSION=1.23.2에서 '='를 기준으로 왼쪽이 키, 오른쪽이 값을 의미한다.&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;- 이미지를 컨테이너로 실행할 때, CMD에 있는 명령어를 통해서 어떤 프로그램을 실행할지를 메타데이터에서 결정한다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv0n15/btsICcXA08h/Z4gT39B0PZPkhzitG315Dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv0n15/btsICcXA08h/Z4gT39B0PZPkhzitG315Dk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv0n15/btsICcXA08h/Z4gT39B0PZPkhzitG315Dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv0n15%2FbtsICcXA08h%2FZ4gT39B0PZPkhzitG315Dk%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;618&quot; height=&quot;314&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;646&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;b&gt;docker inspect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 이미지의 메타데이터 등 세부 정보 조회&lt;/p&gt;
&lt;pre id=&quot;code_1721149194389&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker image inspect {이미지명}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;931&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVSXrE/btsIBK8bltg/Gd676XsRmxGDiVd5nxJsSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVSXrE/btsIBK8bltg/Gd676XsRmxGDiVd5nxJsSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVSXrE/btsIBK8bltg/Gd676XsRmxGDiVd5nxJsSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVSXrE%2FbtsIBK8bltg%2FGd676XsRmxGDiVd5nxJsSK%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;758&quot; height=&quot;348&quot; data-origin-width=&quot;931&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 이미지의 ID, 태그, 생성시간 등의 메타데이터 정보를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcVSFN/btsIB7vh1d1/gW25bkRq2Op3hExb56bP1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcVSFN/btsIB7vh1d1/gW25bkRq2Op3hExb56bP1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcVSFN/btsIB7vh1d1/gW25bkRq2Op3hExb56bP1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcVSFN%2FbtsIB7vh1d1%2FgW25bkRq2Op3hExb56bP1K%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;751&quot; height=&quot;90&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- cmd도 확인할 수 있다.&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;2. 실행중인 컨테이너의 메타데이터 등 세부 정보 조회&lt;/p&gt;
&lt;pre id=&quot;code_1721149249372&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker container inspect {컨테이너명}&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;1 ) 컨테이너를 실행시킨다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4Tnxj/btsICR6isc3/VlUKSdZX9ind6bHIVA7oj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4Tnxj/btsICR6isc3/VlUKSdZX9ind6bHIVA7oj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4Tnxj/btsICR6isc3/VlUKSdZX9ind6bHIVA7oj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4Tnxj%2FbtsICR6isc3%2FVlUKSdZX9ind6bHIVA7oj1%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;686&quot; height=&quot;55&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2 ) 실행중인 컨테이너를 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WKziR/btsIBnk3R4Y/CVDEoqXBUgdKHMVQInhVWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WKziR/btsIBnk3R4Y/CVDEoqXBUgdKHMVQInhVWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WKziR/btsIBnk3R4Y/CVDEoqXBUgdKHMVQInhVWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWKziR%2FbtsIBnk3R4Y%2FCVDEoqXBUgdKHMVQInhVWk%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;1057&quot; height=&quot;71&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 3 ) 실행 중인 컨테이너의 메타데이터 정보를 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;315&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3iBh4/btsICylBC6M/NJVY9Q9CHbjov0QpqaenK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3iBh4/btsICylBC6M/NJVY9Q9CHbjov0QpqaenK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3iBh4/btsICylBC6M/NJVY9Q9CHbjov0QpqaenK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3iBh4%2FbtsICylBC6M%2FNJVY9Q9CHbjov0QpqaenK0%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;717&quot; height=&quot;277&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;315&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5Axtk/btsICeHQKSc/hKJHDkNQk5S24eOdh4aJUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5Axtk/btsICeHQKSc/hKJHDkNQk5S24eOdh4aJUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5Axtk/btsICeHQKSc/hKJHDkNQk5S24eOdh4aJUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5Axtk%2FbtsICeHQKSc%2FhKJHDkNQk5S24eOdh4aJUK%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;731&quot; height=&quot;245&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 컨테이너의 env, cmd가 이미지의 env, cmd와 동일한 것을 확인할 수 있다.&amp;nbsp; &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;3.&amp;nbsp; 컨테이너 실행 시 메타데이터의 cmd 덮어쓰기&lt;/p&gt;
&lt;pre id=&quot;code_1721149310032&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run {이미지명} {덮어쓰기할 실행명령}&lt;/code&gt;&lt;/pre&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;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 컨테이너 실행 시 메타데이터의 env 필드 덮어쓰기&lt;/p&gt;
&lt;pre id=&quot;code_1721149365908&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run --env KEY=VALUE {이미지명}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 기존 이미지에서 메타데이터 내부의 env의 입력한 KEY값을 VALUE로 변환하여 컨테이너를 실행한다.&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;위의 명령들을 통해 메타데이터 내부의 cmd 또는 env 필드를 변경하여 컨테이너를 실행할 수 있다.&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 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[이 블로그에 정리된 Docker 관련 자료는 인프런 데브위키님의 강의 내용을 바탕으로 작성되었습니다.]&lt;/p&gt;
&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #24292f;&quot;&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot;&gt;https://inf.run/Apgvc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1721799590467&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&quot; data-og-description=&quot;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/Apgvc&quot; data-og-url=&quot;https://www.inflearn.com/course/개발자를-위한-쉬운-도커&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SvJHY/hyWCPOC11w/JoJuc8nJ0t0WRXlVOY3apK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/8hnj3/hyWG0Ovzpj/PKvEclgEK8GR3pQggfOYZK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/9OZeX/hyWGN9sQDD/KAmy6Hz7gogGePcRN3yHUk/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/Apgvc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SvJHY/hyWCPOC11w/JoJuc8nJ0t0WRXlVOY3apK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/8hnj3/hyWG0Ovzpj/PKvEclgEK8GR3pQggfOYZK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/9OZeX/hyWGN9sQDD/KAmy6Hz7gogGePcRN3yHUk/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>Docker/SECTION_2 이미지와 컨테이너</category>
      <category>메타데이터</category>
      <category>이미지</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/232</guid>
      <comments>https://chaechaeros.tistory.com/232#entry232comment</comments>
      <pubDate>Wed, 24 Jul 2024 14:40:01 +0900</pubDate>
    </item>
    <item>
      <title>이미지와 컨테이너</title>
      <link>https://chaechaeros.tistory.com/231</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 서버에서 프로그램이 실행되던 방식&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca0tPL/btsIAazc2uV/ALBF0drYTHyOnqHM9P0iJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca0tPL/btsIAazc2uV/ALBF0drYTHyOnqHM9P0iJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca0tPL/btsIAazc2uV/ALBF0drYTHyOnqHM9P0iJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca0tPL%2FbtsIAazc2uV%2FALBF0drYTHyOnqHM9P0iJK%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;646&quot; height=&quot;391&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;391&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;- 하지만 소프트웨어를 실행하기 위해서는 하드웨어 사용에 필수적인 OS가 필요하고,&lt;br /&gt;&amp;nbsp; 일반적으로 소프트웨어는 특정 패키지나 라이브러리의 의존성을 갖고있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 또한 실행을 위해 JVM 과 같은 런타임이 필요할 수도 있음&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;gt; 즉, 서버에서 프로그램을 실행하기 위해서는 OS, 설정에 필요한 언어, 라이브러리 등의 설정 구성, &lt;br /&gt;&amp;nbsp; &amp;nbsp; &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;이미지란?&lt;/b&gt;&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;- 제작 단계에서 소프트웨어뿐만 아니라, 소프트웨어가 실행하기 위해 필요한 모든 요소를 미리 압축해 놓은 파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 즉, OS, 설정에 필요한 구성요소, 실행시킬 프로그램이 포함되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1123&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2G5rZ/btsIzqoRf5F/ptfdJke6ctPXgHYgAGPTbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2G5rZ/btsIzqoRf5F/ptfdJke6ctPXgHYgAGPTbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2G5rZ/btsIzqoRf5F/ptfdJke6ctPXgHYgAGPTbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2G5rZ%2FbtsIzqoRf5F%2FptfdJke6ctPXgHYgAGPTbk%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;589&quot; height=&quot;303&quot; data-origin-width=&quot;1123&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 위 docker run nginx 명령을 통해, 해당 nginx가 압축된 이미지를 다운받고 격리된 공간에 컨테이너를 실행할 수 있다.&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;&lt;b&gt;애플리케이션 서버와 이미지&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7W9Gy/btsIAQmG0xo/wLa8Kzvz6YE0B3gjrLrW21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7W9Gy/btsIAQmG0xo/wLa8Kzvz6YE0B3gjrLrW21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7W9Gy/btsIAQmG0xo/wLa8Kzvz6YE0B3gjrLrW21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7W9Gy%2FbtsIAQmG0xo%2FwLa8Kzvz6YE0B3gjrLrW21%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;657&quot; height=&quot;720&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;720&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;- 컨테이너는 이미지를 통해 실행할 수 있으며, 이미지는 특정 소프트웨어를 실행하기 위해 OS, 의존 요소와 같은 설정에 필요한 구성요소, 실행시킬 소프트웨어가 포함되어 있는 파일 시스템의 상태를 저장해놓은 압축 파일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 이미지를 실행하면 Host Os 내에서 완전히 격리된 공간인 컨테이너가 만들어지고, 이 안에서 소프트웨어가 실행된다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;1) 프로그램 : CPU나 메모리같은 리소스를 사용하지 않고 스토리지의 디스크 공간만을 차지한 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2) 프로세스 : CPU나 메모리같은 리소스를 사용하면서 스토리지의 디스크 공간도 차지한 상태&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;&lt;b&gt;이미지와 컨테이너의 차이점&lt;/b&gt;&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Host 머신의 디스크 공간을차지하면서, CPU와 메모리같은 리소스를 사용하지 않는 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2) 컨테이너 : 이미지를 실행한&amp;nbsp; 것으로 CPU와 메모리같은 리소스를 사용하면서 디스크 공간을 차지한 상태&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;&lt;b&gt;도커 명령어&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도커 명령어는 Docker가 실행된 상태에서만 동작하므로, Docker를 실행한 후 명령해야한다.&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;1. 특정 이미지명을 가진 이미지 조회&lt;/p&gt;
&lt;pre id=&quot;code_1721054964869&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker image ls (이미지명)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdd5VQ/btsIBCH1Adm/IWRceRn9KM8k0yvs2cDy9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdd5VQ/btsIBCH1Adm/IWRceRn9KM8k0yvs2cDy9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdd5VQ/btsIBCH1Adm/IWRceRn9KM8k0yvs2cDy9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcdd5VQ%2FbtsIBCH1Adm%2FIWRceRn9KM8k0yvs2cDy9K%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;559&quot; height=&quot;125&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;131&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;- REPOSITORY : 이미지의 이름. TAG : 이미지의 버전, IMAGE 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;2. 가지고 있는 이미지를 백그라운드로 실행하기&lt;/p&gt;
&lt;pre id=&quot;code_1721055216323&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run -d --name {컨테이너명} 이미지명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;1) -d : 백그라운드로 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2) --name {컨테이너명} : 컨테이너의 이름 지정&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwFdYF/btsIBoJUWFs/IcgePSoC8cCm5ZkgTv85H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwFdYF/btsIBoJUWFs/IcgePSoC8cCm5ZkgTv85H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwFdYF/btsIBoJUWFs/IcgePSoC8cCm5ZkgTv85H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwFdYF%2FbtsIBoJUWFs%2FIcgePSoC8cCm5ZkgTv85H1%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;632&quot; height=&quot;169&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1589&quot; data-origin-height=&quot;917&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDwAIi/btsIAUvJ7lV/cMHRL9UZZmgkx1Be5HsOS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDwAIi/btsIAUvJ7lV/cMHRL9UZZmgkx1Be5HsOS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDwAIi/btsIAUvJ7lV/cMHRL9UZZmgkx1Be5HsOS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDwAIi%2FbtsIAUvJ7lV%2FcMHRL9UZZmgkx1Be5HsOS1%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;603&quot; height=&quot;917&quot; data-origin-width=&quot;1589&quot; data-origin-height=&quot;917&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Docker Desktop에도 컨테이너들이 생성됨을 확인할 수 있다.&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;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 실행 중인 컨테이너 리스트 조회&lt;/p&gt;
&lt;pre id=&quot;code_1721055273743&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- ps는 process의 줄임말&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;119&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H5Hgd/btsIBlfsiEj/mkSIWyozD59Lo8mlDEbrn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H5Hgd/btsIBlfsiEj/mkSIWyozD59Lo8mlDEbrn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H5Hgd/btsIBlfsiEj/mkSIWyozD59Lo8mlDEbrn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH5Hgd%2FbtsIBlfsiEj%2FmkSIWyozD59Lo8mlDEbrn1%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;1141&quot; height=&quot;119&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;119&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 모두 동일한 nginx 이미지를 실행시킨 컨테이너지만,, CONTAINER 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;4. 실행 중인 컨테이너 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1721055293400&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker rm -f&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;1) -f : 실행중인 컨테이너 삭제를 위한 옵션(사용하지 않으면 실행 중인 컨테이너 삭제가 불가하다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;95&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/080tO/btsIz7CoLsk/wi2Famh4yYIl9g54lzxFGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/080tO/btsIz7CoLsk/wi2Famh4yYIl9g54lzxFGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/080tO/btsIz7CoLsk/wi2Famh4yYIl9g54lzxFGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F080tO%2FbtsIz7CoLsk%2Fwi2Famh4yYIl9g54lzxFGk%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;656&quot; height=&quot;95&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;95&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1589&quot; data-origin-height=&quot;919&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GUIvh/btsIAyzO7hF/bHKU8glGEvRMkc9OKKrF21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GUIvh/btsIAyzO7hF/bHKU8glGEvRMkc9OKKrF21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GUIvh/btsIAyzO7hF/bHKU8glGEvRMkc9OKKrF21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGUIvh%2FbtsIAyzO7hF%2FbHKU8glGEvRMkc9OKKrF21%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;663&quot; height=&quot;919&quot; data-origin-width=&quot;1589&quot; data-origin-height=&quot;919&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Docker Desktop에서도 컨테이너가 삭제된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;[이 블로그에 정리된 Docker 관련 자료는 인프런 데브위키님의 강의 내용을 바탕으로 작성되었습니다.]&lt;/p&gt;
&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #24292f;&quot;&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot;&gt;https://inf.run/Apgvc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1721055774955&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&quot; data-og-description=&quot;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/Apgvc&quot; data-og-url=&quot;https://www.inflearn.com/course/개발자를-위한-쉬운-도커&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/guZMQ/hyWCBVuOTv/CGDddLMIQhdNySEjky39m0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/pse13/hyWCAbdn7E/uVAjoRKUqsDnOGXaQzqZkK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bYESLW/hyWCEdB4VJ/8kw6k0pZWqlV6BsxkIMsV0/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/Apgvc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/guZMQ/hyWCBVuOTv/CGDddLMIQhdNySEjky39m0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/pse13/hyWCAbdn7E/uVAjoRKUqsDnOGXaQzqZkK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bYESLW/hyWCEdB4VJ/8kw6k0pZWqlV6BsxkIMsV0/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>Docker/SECTION_2 이미지와 컨테이너</category>
      <category>이미지</category>
      <category>컨테이너</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/231</guid>
      <comments>https://chaechaeros.tistory.com/231#entry231comment</comments>
      <pubDate>Tue, 16 Jul 2024 00:01:21 +0900</pubDate>
    </item>
    <item>
      <title>도커(DOCKER)</title>
      <link>https://chaechaeros.tistory.com/230</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpeAtm/btsIy5jDAf8/0PtJQmn4o2dYGzFKr3d12K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpeAtm/btsIy5jDAf8/0PtJQmn4o2dYGzFKr3d12K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpeAtm/btsIy5jDAf8/0PtJQmn4o2dYGzFKr3d12K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpeAtm%2FbtsIy5jDAf8%2F0PtJQmn4o2dYGzFKr3d12K%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;363&quot; height=&quot;299&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;299&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;b&gt;도커(DOCKER)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 가상화 기술을 사용하기 위한 2013년에 공개된 오픈소스 소프트웨어&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;컨테이너 플랫폼 구성&lt;/b&gt;&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;1) 컨테이너 엔진 : 사용자의 요청을 받아서 컨테이너를 관리하는 역할 수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 컨테이너 런타임 : 직접 커널과 통신하면서 실제로 격리된 공간을 만드는 역할 수행&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;- 도커는 runc라는 컨테이너 런타임을 사용한다.&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1568&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cacsbT/btsIxKVCHL4/vzSDyQEDFhf57nDlrNJ1z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cacsbT/btsIxKVCHL4/vzSDyQEDFhf57nDlrNJ1z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cacsbT/btsIxKVCHL4/vzSDyQEDFhf57nDlrNJ1z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcacsbT%2FbtsIxKVCHL4%2FvzSDyQEDFhf57nDlrNJ1z1%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;533&quot; height=&quot;724&quot; data-origin-width=&quot;1568&quot; data-origin-height=&quot;724&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;b&gt;도커 아키텍처&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYxYeL/btsIxfH4Jgz/y7jBdOMDmfKAWP2rxdRZxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYxYeL/btsIxfH4Jgz/y7jBdOMDmfKAWP2rxdRZxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYxYeL/btsIxfH4Jgz/y7jBdOMDmfKAWP2rxdRZxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYxYeL%2FbtsIxfH4Jgz%2Fy7jBdOMDmfKAWP2rxdRZxk%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;783&quot; height=&quot;524&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 클라이언트 : 사용자의 명령을 도커 데몬에 전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 도커 데몬 : 컨테이너를 관리하는 기능을 제공하고 도커 D라고 불린다.&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;- 도커 데몬은 호스트 OS 커널의 기능을 활용해서 컨테이너를 관리함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 클라이언트에게 컨테이너 관리 기능을 제공하기 위해 API 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- API 명세 제공(&lt;a href=&quot;https://docs.docker.com/engine/api/v1.41/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.docker.com/engine/api/v1.41/&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 사용자가 직접 API를 파악하고 사용하기는 번거롭기 때문에, 중간 다리로서 Command Line 도구인 Docker CLI 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자는 CLI를 통해 간단한 명령어를 사용해 컨테이너를 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;(Docker CLI에서는 복잡한 API 요청을 간소화하여 사용할 수 있는 명령어를 제공한다.)&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- CLI에서 클라이언트가 명령하면, 명령에 맞게 CLI가 API 요청으로 변환하여 도커 데몬으로 명령을 대신 전달한다.&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;- 요청한 작업에 대한 결과를 다시 Docker CLI를 통해 클라이언트에게 JSON 형태로 전달한다.&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;Docker CLI 명령 전달 과정 도식화&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1559&quot; data-origin-height=&quot;745&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bszJiJ/btsIyvQSERy/QwvlKzdoFzKWlNTlkko7Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bszJiJ/btsIyvQSERy/QwvlKzdoFzKWlNTlkko7Vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bszJiJ/btsIyvQSERy/QwvlKzdoFzKWlNTlkko7Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbszJiJ%2FbtsIyvQSERy%2FQwvlKzdoFzKWlNTlkko7Vk%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;753&quot; height=&quot;745&quot; data-origin-width=&quot;1559&quot; data-origin-height=&quot;745&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;(클라이언트는 CLI, 서버는 도커 데몬으로 구성)&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[이 블로그에 정리된 Docker 관련 자료는 인프런 데브위키님의 강의 내용을 바탕으로 작성되었습니다.]&lt;/p&gt;
&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #24292f;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot;&gt;https://inf.run/Apgvc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1720867264440&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&quot; data-og-description=&quot;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/Apgvc&quot; data-og-url=&quot;https://www.inflearn.com/course/개발자를-위한-쉬운-도커&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9aTwR/hyWzrGnRlB/hmVXOxWLyrBtYuNqYSRor0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/wOkD7/hyWzC8Ylkl/UWywKUrdUF5jL2iekBWYj1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cIId3r/hyWzuiMrmz/Tbyo2Kb1VYKWdSKHSV0Sb1/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/Apgvc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9aTwR/hyWzrGnRlB/hmVXOxWLyrBtYuNqYSRor0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/wOkD7/hyWzC8Ylkl/UWywKUrdUF5jL2iekBWYj1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cIId3r/hyWzuiMrmz/Tbyo2Kb1VYKWdSKHSV0Sb1/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;</description>
      <category>Docker/SECTION_1 가상화기술</category>
      <category>docker cli</category>
      <category>도커</category>
      <category>도커 데몬</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/230</guid>
      <comments>https://chaechaeros.tistory.com/230#entry230comment</comments>
      <pubDate>Sat, 13 Jul 2024 19:18:54 +0900</pubDate>
    </item>
    <item>
      <title>컨테이너 가상화</title>
      <link>https://chaechaeros.tistory.com/229</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하이퍼바이저 가상화 방식 vs 컨테이너 가상화 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 하이퍼바이저 가상화 : 하이퍼바이저라는 소프트웨어가 격릭된 공간을 만들어 주었음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 컨테이너 가상화 : LXC 기술을 사용하여 호스트 OS 커널의 자체 기능만을 사용하여 격리된 공간을 만듦&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;p data-ke-size=&quot;size16&quot;&gt;- LXC : 리눅스 커널의 Namespace,&amp;nbsp; Cgroups라는 기능을 활용하여 컨테이너 가상화를 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Namespace : 프로세스, 하드드라이브, 네트워크, 사용자, 호스트 네임 처럼 리소스를 나누는 기준의 역할 수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Cgroups : 프로세스가 사용하는 메모리, CPU, 하드디스크, 네트워크 밴스위스처럼 리소스의 사용량을 배분하는 기술&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컨테이너 : LXC 기술을 사용하여 만들어진 각각의 격리된 공간&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; 즉, 컨테이너 가상화란 하이퍼바이저 없이 커널의 자체 기술을 활용한 가상화를 뜻한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 그렇기 때문에 모든 컨테이너는 Host OS의 커널을 공유해서 사용한다.(컨테이너 가상화의 가장 중요한 특징)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;701&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xp6mB/btsIxLmHBBf/S0Bjv4KlI8Pz7G4k66atK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xp6mB/btsIxLmHBBf/S0Bjv4KlI8Pz7G4k66atK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xp6mB/btsIxLmHBBf/S0Bjv4KlI8Pz7G4k66atK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxp6mB%2FbtsIxLmHBBf%2FS0Bjv4KlI8Pz7G4k66atK1%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;643&quot; height=&quot;701&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;701&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;b&gt;하이퍼바이저 가상화 방식보다 속도가 빠른 컨테이너 가상화 방식&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1339&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwsxUu/btsIxKVCorc/zS2Wlsm8A3Z0e6ohnFoeeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwsxUu/btsIxKVCorc/zS2Wlsm8A3Z0e6ohnFoeeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwsxUu/btsIxKVCorc/zS2Wlsm8A3Z0e6ohnFoeeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwsxUu%2FbtsIxKVCorc%2FzS2Wlsm8A3Z0e6ohnFoeeK%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;561&quot; height=&quot;637&quot; data-origin-width=&quot;1339&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하이퍼바이저 가상화는 Host OS와 Guest OS의 커널이 독립적으로 존재하고,&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;(Host OS와 Guets OS가 다르면 하드웨어에 접근하는 System call 함수가 일치하지 않기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Guest OS에서 요청한 System call을 Host OS에서 이해하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 하이퍼바이저가 중간에 위치해 번역해주면서 서로 다른 두 OS 사이에도 System call이 가능하도록 하였음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하지만 Guest OS에서 요청하는 각각의 System call들이 하이퍼바이저의 통역을 거쳐가기 떄문에,&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;- 이에 반해 컨테이너는 Host OS의 커널을 그대로 사용하기 때문에, 중간 단계가 없어 하이퍼바이저 방식보다&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;- 다만 커널을 독립적으로 가지고 있는 가상 머신이 보안면에서는 더 뛰어나다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 또한 컨테이너는 Host OS의 커널을 공유하기 때문에, 컨테이너에서 호스트 OS와 다른 종류의 OS는 실행할 수가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 커널이 자체적으로 제공하는 가상화 기술은 사용자가 직접 컨트롤하기 어렵다. -&amp;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;하이퍼바이저 방식 vs 도커&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;- 컨테이너 가상화에서 격리를 수행하는 주체는 도커 소프트웨어가 아닌 커널 자체&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;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;[이 블로그에 정리된 Docker 관련 자료는 인프런 데브위키님의 강의 내용을 바탕으로 작성되었습니다.]&lt;/p&gt;
&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #24292f;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot;&gt;https://inf.run/Apgvc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1720867279382&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&quot; data-og-description=&quot;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/Apgvc&quot; data-og-url=&quot;https://www.inflearn.com/course/개발자를-위한-쉬운-도커&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9aTwR/hyWzrGnRlB/hmVXOxWLyrBtYuNqYSRor0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/wOkD7/hyWzC8Ylkl/UWywKUrdUF5jL2iekBWYj1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cIId3r/hyWzuiMrmz/Tbyo2Kb1VYKWdSKHSV0Sb1/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/Apgvc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9aTwR/hyWzrGnRlB/hmVXOxWLyrBtYuNqYSRor0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/wOkD7/hyWzC8Ylkl/UWywKUrdUF5jL2iekBWYj1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cIId3r/hyWzuiMrmz/Tbyo2Kb1VYKWdSKHSV0Sb1/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>Docker/SECTION_1 가상화기술</category>
      <category>가상화</category>
      <category>컨테이너</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/229</guid>
      <comments>https://chaechaeros.tistory.com/229#entry229comment</comments>
      <pubDate>Sat, 13 Jul 2024 18:40:48 +0900</pubDate>
    </item>
    <item>
      <title>가상화기술과 하이퍼바이저 가상화</title>
      <link>https://chaechaeros.tistory.com/228</link>
      <description>&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&amp;lsquo;가상&amp;rsquo; 의 사전적 의미&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&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;가상화 컴퓨팅 기술&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;하나의 컴퓨터에서 여러 대의 컴퓨터를 실행할 수 있음&lt;/li&gt;
&lt;li&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;b&gt;하나의 컴퓨터에서 여러 서버 프로그램을 실행하였을 경우?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/63zBb/btsIx0Q6cqU/I8cLmY42z5zhMAazKxQZC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/63zBb/btsIx0Q6cqU/I8cLmY42z5zhMAazKxQZC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/63zBb/btsIx0Q6cqU/I8cLmY42z5zhMAazKxQZC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F63zBb%2FbtsIx0Q6cqU%2FI8cLmY42z5zhMAazKxQZC0%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;584&quot; height=&quot;340&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;/figure&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하나의 컴퓨터에서 가상 환경으로 여러 프로그램을 실행시키면?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u9fgW/btsIzL5YgWB/uw4QlkVV4iQJzG8KuYKDZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u9fgW/btsIzL5YgWB/uw4QlkVV4iQJzG8KuYKDZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u9fgW/btsIzL5YgWB/uw4QlkVV4iQJzG8KuYKDZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu9fgW%2FbtsIzL5YgWB%2Fuw4QlkVV4iQJzG8KuYKDZK%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;582&quot; height=&quot;346&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;/figure&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;하나의 환경에서 리소스 사용이 급증해도, OS 한 대의 사용량이 제한되어 있기에 다른 프로그램에 영향을 끼치지 않는 것&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;하드웨어를 여러 대 사용하지 않고, 복잡하게 가상화 기술을 사용하는 이유&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;엔터프라이즈 서버 운영 방식&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;베어메탈(Baremetal) 방식 : 물리적인 하나의 서버 위에 하나의 OS를 설치하여 여러 개의 소프트웨어를 실행&lt;/li&gt;
&lt;li&gt;하이퍼바이저 방식&lt;/li&gt;
&lt;li&gt;컨테이너 방식&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 하이퍼바이저 방식과 컨테이너 방식은 가상화 기술을 활용한 서버 운영 방식으로 아래에 더 자세한 설명을 추가함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c26fFc/btsIxkJsJ5o/NGPNk5uJJc8k3hwPh8mwEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c26fFc/btsIxkJsJ5o/NGPNk5uJJc8k3hwPh8mwEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c26fFc/btsIxkJsJ5o/NGPNk5uJJc8k3hwPh8mwEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc26fFc%2FbtsIxkJsJ5o%2FNGPNk5uJJc8k3hwPh8mwEK%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;575&quot; height=&quot;371&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;371&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;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;컴퓨터에 설치되는 프로그램으로 OS에서 가상화 환경을 만들고 관리한다.&lt;/li&gt;
&lt;li&gt;사용자가 지정해둔 CPU나 메모리 만큼 컴퓨터 내에 격리된 공간을 만들어 낼 수 있다.&lt;/li&gt;
&lt;li&gt;하이퍼바이저에서 실행 버튼을 통해 가상 환경에서 CPU와 메모리를 사용하게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vfGcu/btsIyDugYiI/NA4zSr04cw3SwiDzUSux10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vfGcu/btsIyDugYiI/NA4zSr04cw3SwiDzUSux10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vfGcu/btsIyDugYiI/NA4zSr04cw3SwiDzUSux10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvfGcu%2FbtsIyDugYiI%2FNA4zSr04cw3SwiDzUSux10%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;570&quot; height=&quot;354&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;575&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;b&gt;하이퍼바이저에서의 주요 개념&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;호스트 OS : 물리적인 서버에 설치되어 있는 OS&lt;/li&gt;
&lt;li&gt;게스트 OS : 호스트 OS를 논리적으로 나눈 격리된 OS (=가상머신에 올린 OS)&lt;/li&gt;
&lt;/ol&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;엔터프라이즈 환경에서 서버에 호스트 OS를 설치&lt;/li&gt;
&lt;li&gt;가상화를 사용하기 위해 호스트 OS에 하이퍼바이저를 설치&lt;/li&gt;
&lt;li&gt;하이퍼바이저에서 가상 머신을 만들어 게스트 OS를 실행&lt;/li&gt;
&lt;li&gt;게스트 OS에 실제 실행을 원하는 프로세스를 운영&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;호스트 OS와 게스트 OS가 다를 떄 생기는 문제를 해결해주는 하이퍼바이저&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스가 하드웨어를 사용하기 위해서는 OS를 거쳐야만 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kernal : 프로세스가 하드웨어 사용 요청을 위해 거치는 중간 다리&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;System Call : 커널이 프로세스가 요청한 하드웨어 사용 요청을 대신 전해주는 표준 소통 도구&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각각의 OS는 다른 종류의 커널을 사용하며, System Call 또한 각각 다르다.&lt;/li&gt;
&lt;li&gt;따라서 게스트 OS와 호스트 OS가 다르면, 호스트 OS는 게스트 OS에서 전달받은 System Call을 이해하지 못해 요청을 처리할 수가 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 하이퍼바이저가 다른 커널 간 System call을 통역해주는 통역가 역할을 수행한다. 이를 통해 가상 환경에 격리된 OS를 만들어 내면서도, 호스트 OS와 다른 종류의 게스트 OS도 사용할 수 있는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVYOcj/btsIzWl6vAH/Sk0t3ckSBbK3JuC8nY1Q1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVYOcj/btsIzWl6vAH/Sk0t3ckSBbK3JuC8nY1Q1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVYOcj/btsIzWl6vAH/Sk0t3ckSBbK3JuC8nY1Q1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVYOcj%2FbtsIzWl6vAH%2FSk0t3ckSBbK3JuC8nY1Q1k%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;613&quot; height=&quot;535&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;535&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[이 블로그에 정리된 Docker 관련 자료는 인프런 데브위키님의 강의 내용을 바탕으로 작성되었습니다.]&lt;/p&gt;
&lt;div id=&quot;350425&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-comment-id=&quot;350425&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div style=&quot;color: #24292f;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot;&gt;https://inf.run/Apgvc&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1720867121595&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&quot; data-og-description=&quot;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://inf.run/Apgvc&quot; data-og-url=&quot;https://www.inflearn.com/course/개발자를-위한-쉬운-도커&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9aTwR/hyWzrGnRlB/hmVXOxWLyrBtYuNqYSRor0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/wOkD7/hyWzC8Ylkl/UWywKUrdUF5jL2iekBWYj1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cIId3r/hyWzuiMrmz/Tbyo2Kb1VYKWdSKHSV0Sb1/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479&quot;&gt;&lt;a href=&quot;https://inf.run/Apgvc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://inf.run/Apgvc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9aTwR/hyWzrGnRlB/hmVXOxWLyrBtYuNqYSRor0/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/wOkD7/hyWzC8Ylkl/UWywKUrdUF5jL2iekBWYj1/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/cIId3r/hyWzuiMrmz/Tbyo2Kb1VYKWdSKHSV0Sb1/img.png?width=736&amp;amp;height=479&amp;amp;face=0_0_736_479');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;/div&gt;</description>
      <category>Docker/SECTION_1 가상화기술</category>
      <category>가상화</category>
      <category>하이퍼바이저</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/228</guid>
      <comments>https://chaechaeros.tistory.com/228#entry228comment</comments>
      <pubDate>Sat, 13 Jul 2024 12:35:34 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 21609] 상어 중학교 - JAVA, Gold2</title>
      <link>https://chaechaeros.tistory.com/227</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/21609&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/21609&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703826454271&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;21609번: 상어 중학교&quot; data-og-description=&quot;상어 중학교의 코딩 동아리에서 게임을 만들었다. 이 게임은 크기가 N&amp;times;N인 격자에서 진행되고, 초기에 격자의 모든 칸에는 블록이 하나씩 들어있고, 블록은 검은색 블록, 무지개 블록, 일반 블록&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/21609&quot; data-og-url=&quot;https://www.acmicpc.net/problem/21609&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dwYYeS/hyUXL6v3Tu/KRcC4BpdLIZ7ejkAt7BwlK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/21609&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/21609&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dwYYeS/hyUXL6v3Tu/KRcC4BpdLIZ7ejkAt7BwlK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;21609번: 상어 중학교&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;상어 중학교의 코딩 동아리에서 게임을 만들었다. 이 게임은 크기가 N&amp;times;N인 격자에서 진행되고, 초기에 격자의 모든 칸에는 블록이 하나씩 들어있고, 블록은 검은색 블록, 무지개 블록, 일반 블록&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chzOPZ/btsCTwGACMd/poxPPRyHvOXVgP0r7IQQWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chzOPZ/btsCTwGACMd/poxPPRyHvOXVgP0r7IQQWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chzOPZ/btsCTwGACMd/poxPPRyHvOXVgP0r7IQQWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchzOPZ%2FbtsCTwGACMd%2FpoxPPRyHvOXVgP0r7IQQWK%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;1432&quot; height=&quot;920&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCBVsM/btsCTyEkFhj/BS2tfJLbhOWdLTvVAdAyT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCBVsM/btsCTyEkFhj/BS2tfJLbhOWdLTvVAdAyT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCBVsM/btsCTyEkFhj/BS2tfJLbhOWdLTvVAdAyT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCBVsM%2FbtsCTyEkFhj%2FBS2tfJLbhOWdLTvVAdAyT1%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;1425&quot; height=&quot;728&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;911&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nrHCU/btsCK63WyYI/ktuxNcmz8RKwlczMo5K7gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nrHCU/btsCK63WyYI/ktuxNcmz8RKwlczMo5K7gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nrHCU/btsCK63WyYI/ktuxNcmz8RKwlczMo5K7gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnrHCU%2FbtsCK63WyYI%2FktuxNcmz8RKwlczMo5K7gK%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;1432&quot; height=&quot;911&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;911&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwlLQ8/btsCMy0atyq/t011uLa1eUWiuq0hIXorG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwlLQ8/btsCMy0atyq/t011uLa1eUWiuq0hIXorG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwlLQ8/btsCMy0atyq/t011uLa1eUWiuq0hIXorG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwlLQ8%2FbtsCMy0atyq%2Ft011uLa1eUWiuq0hIXorG1%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;1428&quot; height=&quot;904&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1433&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pnqmJ/btsCRgjT8Wv/E4C23gfZjF1XAYISrfuo71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pnqmJ/btsCRgjT8Wv/E4C23gfZjF1XAYISrfuo71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pnqmJ/btsCRgjT8Wv/E4C23gfZjF1XAYISrfuo71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpnqmJ%2FbtsCRgjT8Wv%2FE4C23gfZjF1XAYISrfuo71%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;1433&quot; height=&quot;325&quot; data-origin-width=&quot;1433&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 구현할 기능 목록&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 격자 한 변의 크기, 색상의 개수와 각 격자 칸에 들어있는 블록의 정보를 입력받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 격차 한 변의 크기 : 1~20&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 색상의 개수 : 1~5&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - [블록의 정보] 검정 블록 : -1, 무지개 블록 : 0, 일반 블록 : 1~N&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;2. BFS 탐색을 통해 격자에서 가장 큰 블록 그룹을 찾는다.&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; 행/열 블록의 번호가 최소인 블록은 기준 블록으로 한다.&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;3. 2번에서 찾은 블록 그룹을 삭제하고, 해당 블록 그룹의 크기의 제곱의 수만큼의 점수를 획득한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;- 만약 2번에서 찾은 블록 그룹의 크기가 2 미만이라면, 3~7번 과정을 생략한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 삭제된 블록의 값을 -1, 0, 1~N의 수가 아닌 임의의 수로 변경하여 삭제된 블록임을 나타낸다.&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;4. 격자에 중력을 작용시켜, 삭제되어 빈 블록 위에 일반 블록이 있다면 위치를 뒤바꿔 이동시킨다.&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;5. 격자를 반시계 방향으로 90도 회전시킨다.&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;6. 격자에 중력을 다시 작용시킨다.&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;7. 3~6번 과정을 반복한다.&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;8. 획득한 점수의 총합을 출력한다.&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;/b&gt;&lt;/h2&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;이차원 배열을 반시계 방향으로 90도 회전시켜야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXEUtC/btsCSC76miM/8iExkgrfrMyLc1xgbuLFpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXEUtC/btsCSC76miM/8iExkgrfrMyLc1xgbuLFpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXEUtC/btsCSC76miM/8iExkgrfrMyLc1xgbuLFpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXEUtC%2FbtsCSC76miM%2F8iExkgrfrMyLc1xgbuLFpK%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;660&quot; height=&quot;301&quot; data-origin-width=&quot;971&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1703828258464&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int arr[N][N], tmp_arr[N][N];

for(int i=0; i&amp;lt;N; i++){
	for(int j=0; j&amp;lt;N; j++) tmp_arr[size-1-j][i] = arr[i][j];
}

arr = tmp_arr;&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;&lt;b&gt;&amp;lt;'틀렸습니다' 판정 주의사항&amp;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;/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;한번의 BFS 탐색을 마친 후에 반드시 방문여부를 초기화 시켜줘야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1703829195087&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if(map[mx][my]==0){
    tempRainbowBlockSize++;
    rainbowList.add(new Position(mx,my));
}

...(생략)

for(Position position:rainbowList){
    visited[position.row][position.col]=false;
}&lt;/code&gt;&lt;/pre&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;b&gt;- 기준 값들을 적절한 위치에서 초기화&lt;/b&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;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기준 값들을 적절한 위치에서 초기화 시켜줘야한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;⌨ 제출 코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1703828098443&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;

public class Main {

    static int N,M;
    static int map[][];

    static int dx[] = {-1,0,1,0};
    static int dy[] = {0,1,0,-1};

    static List&amp;lt;Position&amp;gt; blockSet = new ArrayList&amp;lt;&amp;gt;();
    static int rainbowBlockSize=0;
    static int standardRow=0;
    static int standardCol=0;
    static int totalScore=0;
    static boolean visited[][];
    static final int SPACE_NUMBER = -2;

    static class Position{
        int row;
        int col;

        public Position(int row,int col){
            this.row=row;
            this.col=col;
        }
    }

    static void removeBlock(){
        for(Position block:blockSet){
            int row = block.row;
            int col = block.col;
            map[row][col]=SPACE_NUMBER;
        }
        totalScore+=(int)Math.pow(blockSet.size(),2);
    }

    static void gravity(){
        for(int col=0;col&amp;lt;N;++col){
            for(int i=N-2;i&amp;gt;=0;--i){
                for(int j=i;j&amp;lt;N-1;++j){
                    if(map[j][col]==-1 || map[j][col]==SPACE_NUMBER) break;
                    if(map[j+1][col]==SPACE_NUMBER){
                        map[j+1][col]=map[j][col];
                        map[j][col]=SPACE_NUMBER;
                    }
                    else break;
                }
            }
        }
    }

    static void rotate(){
        int tempMap[][] = new int[N][N];
        for(int i=0;i&amp;lt;N;++i){
            for(int j=0;j&amp;lt;N;++j){
                tempMap[i][j]=map[j][N-1-i];
            }
        }
        for(int i=0;i&amp;lt;N;++i){
            System.arraycopy(tempMap[i],0,map[i],0,tempMap[i].length);
        }
    }

    static void printMap(){
        for(int i=0;i&amp;lt;N;++i){
            for(int j=0;j&amp;lt;N;++j){
                System.out.printf(&quot;%2d &quot;,map[i][j]);
            }
            System.out.println();
        }
    }

    static int bfs(int r,int c,int standardBlock){
        int blockSize=0;
        if(visited[r][c]) return blockSize;
        if(standardBlock==-1 || standardBlock==0 || standardBlock == SPACE_NUMBER){
            return blockSize;
        }
        Queue&amp;lt;Position&amp;gt; q = new LinkedList&amp;lt;&amp;gt;();
        q.offer(new Position(r,c));
        int tempRainbowBlockSize=0;
        int tempStandardRow=r;
        int tempStandardCol=c;
        visited[r][c]=true;
        List&amp;lt;Position&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        List&amp;lt;Position&amp;gt; rainbowList = new ArrayList&amp;lt;&amp;gt;();
        list.add(new Position(r,c));
        blockSize++;

        while(!q.isEmpty()){
            Position now = q.poll();
            for(int i=0;i&amp;lt;4;++i){
                int mx = now.row+dx[i];
                int my = now.col+dy[i];

                if(mx&amp;lt;0 || mx&amp;gt;=N || my&amp;lt;0 || my&amp;gt;= N) continue;
                if(visited[mx][my]) continue;
                if(map[mx][my]==-1 || map[mx][my]==SPACE_NUMBER) continue;
                if(map[mx][my]!=0 &amp;amp;&amp;amp; map[mx][my]!=standardBlock) continue;

                if(map[mx][my]==0){
                    tempRainbowBlockSize++;
                    rainbowList.add(new Position(mx,my));
                }

                if(map[mx][my]==standardBlock){
                    if(tempStandardRow&amp;gt;mx){
                        tempStandardRow=mx;
                        tempStandardCol=my;
                    }
                    else if(tempStandardRow==mx){
                        if(tempStandardCol&amp;gt;my){
                            tempStandardRow=mx;
                            tempStandardCol=my;
                        }
                    }
                }
                visited[mx][my]=true;
                q.offer(new Position(mx,my));
                list.add(new Position(mx,my));
                blockSize++;
            }
        }

        if(blockSize&amp;lt;2){
            return blockSize;
        }

        for(Position position:rainbowList){
            visited[position.row][position.col]=false;
        }

        if(blockSet.size()&amp;lt;list.size()){
            blockSet=new ArrayList&amp;lt;&amp;gt;(list);
            rainbowBlockSize=tempRainbowBlockSize;
            standardRow=tempStandardRow;
            standardCol=tempStandardCol;
        }
        else if(blockSet.size()==list.size()){
            if(rainbowBlockSize&amp;lt;tempRainbowBlockSize){
                blockSet=new ArrayList&amp;lt;&amp;gt;(list);
                rainbowBlockSize=tempRainbowBlockSize;
                standardRow=tempStandardRow;
                standardCol=tempStandardCol;
            }
            else if(rainbowBlockSize==tempRainbowBlockSize){
                if(standardRow&amp;lt;tempStandardRow){
                    blockSet=new ArrayList&amp;lt;&amp;gt;(list);
                    rainbowBlockSize=tempRainbowBlockSize;
                    standardRow=tempStandardRow;
                    standardCol=tempStandardCol;
                }
                else if(standardRow==tempStandardRow){
                    if(standardCol&amp;lt;tempStandardCol){
                        blockSet=new ArrayList&amp;lt;&amp;gt;(list);
                        rainbowBlockSize=tempRainbowBlockSize;
                        standardRow=tempStandardRow;
                        standardCol=tempStandardCol;
                    }
                }
            }
        }
        return blockSize;
    }


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        map = new int[N][N];

        for(int i=0;i&amp;lt;N;++i){
            st = new StringTokenizer(br.readLine());
            for(int j=0;j&amp;lt;N;++j){
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        while(true){
            blockSet = new ArrayList&amp;lt;&amp;gt;();
            visited = new boolean[N][N];
            boolean isContinue=false;
            standardRow=0;
            standardCol=0;
            for(int i=0;i&amp;lt;N;++i){
                for(int j=0;j&amp;lt;N;++j){
                    if(bfs(i,j,map[i][j])&amp;gt;=2) isContinue=true;
                }
            }
            if(!isContinue) break;

            removeBlock();
            gravity();
            rotate();
            gravity();
        }

        bw.write(totalScore+&quot;\n&quot;);
        bw.flush();
        bw.close();
    }
}&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMFVph/btsCJjCK44N/kKGIjMIGRgFWTXPd7668Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMFVph/btsCJjCK44N/kKGIjMIGRgFWTXPd7668Gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMFVph/btsCJjCK44N/kKGIjMIGRgFWTXPd7668Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMFVph%2FbtsCJjCK44N%2FkKGIjMIGRgFWTXPd7668Gk%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;1428&quot; height=&quot;91&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;91&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;</description>
      <category>알고리즘||코딩테스트/삼성 SW 역량테스트</category>
      <category>21609</category>
      <category>BOJ</category>
      <category>Java</category>
      <category>상어 중학교</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/227</guid>
      <comments>https://chaechaeros.tistory.com/227#entry227comment</comments>
      <pubDate>Fri, 29 Dec 2023 14:54:57 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 13460] 구슬 탈출 2 - JAVA, Gold1</title>
      <link>https://chaechaeros.tistory.com/225</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13460&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/13460&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702958339819&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;13460번: 구슬 탈출 2&quot; data-og-description=&quot;첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 &amp;le; N, M &amp;le; 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/13460&quot; data-og-url=&quot;https://www.acmicpc.net/problem/13460&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Aks1J/hyUL4AtQAV/5zcsHO1PyHoKcYhXB1gDfK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13460&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/13460&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Aks1J/hyUL4AtQAV/5zcsHO1PyHoKcYhXB1gDfK/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;13460번: 구슬 탈출 2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 &amp;le; N, M &amp;le; 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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-origin-width=&quot;1434&quot; data-origin-height=&quot;863&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bduUZT/btsB7dpq9BX/xuyWHIWczHkigEK7l63pvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bduUZT/btsB7dpq9BX/xuyWHIWczHkigEK7l63pvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bduUZT/btsB7dpq9BX/xuyWHIWczHkigEK7l63pvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbduUZT%2FbtsB7dpq9BX%2FxuyWHIWczHkigEK7l63pvK%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;1434&quot; height=&quot;863&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;863&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1436&quot; data-origin-height=&quot;734&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vJQLr/btsB7fniHzy/cYE2O2nEzy4QPfnRLh58R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vJQLr/btsB7fniHzy/cYE2O2nEzy4QPfnRLh58R0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vJQLr/btsB7fniHzy/cYE2O2nEzy4QPfnRLh58R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvJQLr%2FbtsB7fniHzy%2FcYE2O2nEzy4QPfnRLh58R0%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;1436&quot; height=&quot;734&quot; data-origin-width=&quot;1436&quot; data-origin-height=&quot;734&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;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 직사각형 맵의 크기와 맵의 좌표별 위치 정보를 입력받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - R, B, O 값을 입력받았을 경우, 해당 좌표값을 별도의 배열에 저장한다.&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;2. 1~10번 기울여 이동하여 조건에 만족하는 결과가 나오도록 DFS 함수를 구현한다.&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;3. 특정 방향으로 기울일 경우 빨간공과 파란공이 이동할 수 없을 때까지 이동하는 함수를 작성한다.&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; - 예로 위쪽으로 직사각형을 기울인 경우, 만약 빨간공이 파란공보다 더 위에 존재한다면&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; - 파란공이 목적지에 도달하면 해당 이동은 어떠한 경우에도 실패이다.&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;4. 조건을 성공적으로 만족하는 최소의 이동횟수를 출력하고 프로그램을 종료시킨다.&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 주요 로직&lt;/b&gt;&lt;/h2&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1286&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byxmqm/btsB7RtiUwC/TlzZEL1Ub06gWBeRKK16v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byxmqm/btsB7RtiUwC/TlzZEL1Ub06gWBeRKK16v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byxmqm/btsB7RtiUwC/TlzZEL1Ub06gWBeRKK16v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyxmqm%2FbtsB7RtiUwC%2FTlzZEL1Ub06gWBeRKK16v1%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;596&quot; height=&quot;418&quot; data-origin-width=&quot;1286&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&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;/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;[위 맵을 왼쪽으로 기울인 경우 공이 이동하는 과정]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;1354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7pF8C/btsB7P915Qd/7HCQbnxxFRs9JQ6zUztQ91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7pF8C/btsB7P915Qd/7HCQbnxxFRs9JQ6zUztQ91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7pF8C/btsB7P915Qd/7HCQbnxxFRs9JQ6zUztQ91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7pF8C%2FbtsB7P915Qd%2F7HCQbnxxFRs9JQ6zUztQ91%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;466&quot; height=&quot;816&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;1354&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;/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;&lt;b&gt; 코드 적용&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 직사각형 맵의 크기와 맵의 좌표별 위치 정보를 입력받는다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - R, B, O 값을 입력받았을 경우, 해당 좌표값을 별도의 배열에 저장한다.&lt;/p&gt;
&lt;pre id=&quot;code_1702965334287&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());

N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());

map = new char[N][M];
originMap = new char[N][M];

for(int i=0;i&amp;lt;N;++i){
    String tempMap = br.readLine();
    for(int j=0;j&amp;lt;M;++j){
        originMap[i][j]=tempMap.charAt(j);
        if(originMap[i][j]=='R'){
            originRedBallPosition[0]=i;
            originRedBallPosition[1]=j;
        }
        else if(originMap[i][j]=='B'){
            originBlueBallPosition[0]=i;
            originBlueBallPosition[1]=j;
        }
        else if(originMap[i][j]=='O'){
            goal[0]=i;
            goal[1]=j;
        }
    }
}&lt;/code&gt;&lt;/pre&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;b&gt;2. 1~10번 기울여 이동하여 조건에 만족하는 결과가 나오도록 DFS 함수를 구현한다.&lt;/b&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;pre id=&quot;code_1702965366041&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void dfs(int depth){
    if(depth==maxCount){
        init();
        if(incline()){
            isSuccess=true;
        }
        return;
    }

    for(int i=0;i&amp;lt;4;++i){
        direction[depth]=i;
        dfs(depth+1);
    }
}&lt;/code&gt;&lt;/pre&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;b&gt;3. 특정 방향으로 기울일 경우 빨간공과 파란공이 이동할 수 없을 때까지 이동하는 함수를 작성한다.&lt;/b&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;&amp;nbsp; &amp;nbsp; - 예로 위쪽으로 직사각형을 기울인 경우, 만약 빨간공이 파란공보다 더 위에 존재한다면&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &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;/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;/p&gt;
&lt;pre id=&quot;code_1702965418208&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static boolean incline(){
    boolean result=false;
    for(int i=0;i&amp;lt;maxCount;++i){
        if(direction[i]==0){ // 상
            if(redBallPosition[0]&amp;lt;blueBallPosition[0]){
                while(true){
                    int redMx = redBallPosition[0]+dx[0];
                    int blueMx = blueBallPosition[0]+dx[0];

                    if(!(map[redMx][redBallPosition[1]]=='.' || map[redMx][redBallPosition[1]]=='O'
                    || map[blueMx][blueBallPosition[1]]=='.' || map[blueMx][blueBallPosition[1]]=='O')){
                        break;
                    }

                    if(redMx&amp;gt;=1 &amp;amp;&amp;amp; map[redMx][redBallPosition[1]]!='#'){
                        map[redBallPosition[0]][redBallPosition[1]]='.';
                        redBallPosition[0]=redMx;
                        map[redBallPosition[0]][redBallPosition[1]]='R';
                    }

                    if(blueMx&amp;gt;=1 &amp;amp;&amp;amp; map[blueMx][blueBallPosition[1]]!='#'){
                        map[blueBallPosition[0]][blueBallPosition[1]]='.';
                        blueBallPosition[0]=blueMx;
                        map[blueBallPosition[0]][blueBallPosition[1]]='B';
                    }

                    if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                        map[goal[0]][goal[1]]='O';
                        result=true;
                    }

                    if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                        return false;
                    }
                }
                if(result) return true;
            }
            else{
                while(true){
                    int redMx = redBallPosition[0]+dx[0];
                    int blueMx = blueBallPosition[0]+dx[0];

                    if(!(map[redMx][redBallPosition[1]]=='.' || map[redMx][redBallPosition[1]]=='O'
                            || map[blueMx][blueBallPosition[1]]=='.' || map[blueMx][blueBallPosition[1]]=='O')){
                        break;
                    }

                    if(blueMx&amp;gt;=1 &amp;amp;&amp;amp; map[blueMx][blueBallPosition[1]]!='#'){
                        map[blueBallPosition[0]][blueBallPosition[1]]='.';
                        blueBallPosition[0]=blueMx;
                        map[blueBallPosition[0]][blueBallPosition[1]]='B';
                    }

                    if(redMx&amp;gt;=1 &amp;amp;&amp;amp; map[redMx][redBallPosition[1]]!='#'){
                        map[redBallPosition[0]][redBallPosition[1]]='.';
                        redBallPosition[0]=redMx;
                        map[redBallPosition[0]][redBallPosition[1]]='R';
                    }

                    if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                        map[goal[0]][goal[1]]='O';
                        result=true;
                    }

                    if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                        return false;
                    }
                }
                if(result) return true;
            }
        }
        else if(direction[i]==1){ // 우
            ...(중략)
        }
    }
}&lt;/code&gt;&lt;/pre&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;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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 조건을 성공적으로 만족하는 최소의 이동횟수를 출력하고 프로그램을 종료시킨다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 조건을 만족하는 경우의 수가 없다면 -1을 출력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1702965468898&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) throws IOException {
    ...(생략)

    for(int i=1;i&amp;lt;=10;++i){
        maxCount=i;
        init();
        dfs(0);
        if(isSuccess){
            bw.write(maxCount+&quot;\n&quot;);
            bw.flush();
            bw.close();
            return;
        }
    }
    bw.write(&quot;-1\n&quot;);
    bw.flush();
    bw.close();
}&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;b&gt;⌨제출 코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1702965509877&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.StringTokenizer;

public class Main {
    static int N,M;
    static char map[][];
    static char originMap[][];
    static int maxCount=0;
    static boolean isSuccess=false;
    static int direction[] = new int[10];
    static int dx[]={-1,0,1,0}; // 상우하좌
    static int dy[]={0,1,0,-1};
    static int originRedBallPosition[] = new int[2]; // [0] -&amp;gt; x, [1] -&amp;gt; y
    static int originBlueBallPosition[] = new int[2];
    static int redBallPosition[] = new int[2]; // [0] -&amp;gt; x, [1] -&amp;gt; y
    static int blueBallPosition[] = new int[2];
    static int goal[] = new int[2];

    static boolean incline(){
        boolean result=false;
        for(int i=0;i&amp;lt;maxCount;++i){
            if(direction[i]==0){ // 상
                if(redBallPosition[0]&amp;lt;blueBallPosition[0]){
                    while(true){
                        int redMx = redBallPosition[0]+dx[0];
                        int blueMx = blueBallPosition[0]+dx[0];

                        if(!(map[redMx][redBallPosition[1]]=='.' || map[redMx][redBallPosition[1]]=='O'
                        || map[blueMx][blueBallPosition[1]]=='.' || map[blueMx][blueBallPosition[1]]=='O')){
                            break;
                        }

                        if(redMx&amp;gt;=1 &amp;amp;&amp;amp; map[redMx][redBallPosition[1]]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[0]=redMx;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(blueMx&amp;gt;=1 &amp;amp;&amp;amp; map[blueMx][blueBallPosition[1]]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[0]=blueMx;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }
                else{
                    while(true){
                        int redMx = redBallPosition[0]+dx[0];
                        int blueMx = blueBallPosition[0]+dx[0];

                        if(!(map[redMx][redBallPosition[1]]=='.' || map[redMx][redBallPosition[1]]=='O'
                                || map[blueMx][blueBallPosition[1]]=='.' || map[blueMx][blueBallPosition[1]]=='O')){
                            break;
                        }

                        if(blueMx&amp;gt;=1 &amp;amp;&amp;amp; map[blueMx][blueBallPosition[1]]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[0]=blueMx;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redMx&amp;gt;=1 &amp;amp;&amp;amp; map[redMx][redBallPosition[1]]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[0]=redMx;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }
            }
            else if(direction[i]==1){ // 우
                if(redBallPosition[1]&amp;gt;blueBallPosition[1]){
                    while(true){
                        int redMy = redBallPosition[1]+dy[1];
                        int blueMy = blueBallPosition[1]+dy[1];

                        if(!(map[redBallPosition[0]][redMy]=='.' || map[redBallPosition[0]][redMy]=='O'
                                || map[blueBallPosition[0]][blueMy]=='.' || map[blueBallPosition[0]][blueMy]=='O')){
                            break;
                        }

                        if(redMy&amp;lt;M-1 &amp;amp;&amp;amp; map[redBallPosition[0]][redMy]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[1]=redMy;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(blueMy&amp;lt;M-1 &amp;amp;&amp;amp; map[blueBallPosition[0]][blueMy]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[1]=blueMy;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }
                else{
                    while(true){
                        int redMy = redBallPosition[1]+dy[1];
                        int blueMy = blueBallPosition[1]+dy[1];

//                        System.out.println(redBallPosition[0]+&quot; &quot;+redBallPosition[1]);
//                        System.out.println(blueBallPosition[0]+&quot; &quot;+blueBallPosition[1]);
//                        System.out.println(&quot;========================&quot;);
//                        System.out.println(redBallPosition[0]+&quot; &quot;+redMy);
//                        System.out.println(blueBallPosition[0]+&quot; &quot;+blueMy);
//                        System.out.println(redMy+&quot; &quot;+blueMy);

                        if(!(map[redBallPosition[0]][redMy]=='.' || map[redBallPosition[0]][redMy]=='O'
                                || map[blueBallPosition[0]][blueMy]=='.' || map[blueBallPosition[0]][blueMy]=='O')){
                            break;
                        }

                        if(blueMy&amp;lt;M-1 &amp;amp;&amp;amp; map[blueBallPosition[0]][blueMy]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[1]=blueMy;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redMy&amp;lt;M-1 &amp;amp;&amp;amp; map[redBallPosition[0]][redMy]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[1]=redMy;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }

            }
            else if(direction[i]==2){ // 하
                if(redBallPosition[0]&amp;gt;blueBallPosition[0]){
                    while(true){
                        int redMx = redBallPosition[0]+dx[2];
                        int blueMx = blueBallPosition[0]+dx[2];

                        if(!(map[redMx][redBallPosition[1]]=='.' || map[redMx][redBallPosition[1]]=='O'
                                || map[blueMx][blueBallPosition[1]]=='.' || map[blueMx][blueBallPosition[1]]=='O')){
                            break;
                        }

                        if(redMx&amp;lt;N-1 &amp;amp;&amp;amp; map[redMx][redBallPosition[1]]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[0]=redMx;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(blueMx&amp;lt;N-1 &amp;amp;&amp;amp; map[blueMx][blueBallPosition[1]]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[0]=blueMx;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }
                else{
                    while(true){
                        int redMx = redBallPosition[0]+dx[2];
                        int blueMx = blueBallPosition[0]+dx[2];

                        if(!(map[redMx][redBallPosition[1]]=='.' || map[redMx][redBallPosition[1]]=='O'
                                || map[blueMx][blueBallPosition[1]]=='.' || map[blueMx][blueBallPosition[1]]=='O')){
                            break;
                        }

                        if(blueMx&amp;lt;N-1 &amp;amp;&amp;amp; map[blueMx][blueBallPosition[1]]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[0]=blueMx;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redMx&amp;lt;N-1 &amp;amp;&amp;amp; map[redMx][redBallPosition[1]]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[0]=redMx;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }
            }
            else if(direction[i]==3){ // 좌
                if(redBallPosition[1]&amp;lt;blueBallPosition[1]){
                    while(true){
                        int redMy = redBallPosition[1]+dy[3];
                        int blueMy = blueBallPosition[1]+dy[3];

                        if(!(map[redBallPosition[0]][redMy]=='.' || map[redBallPosition[0]][redMy]=='O'
                                || map[blueBallPosition[0]][blueMy]=='.' || map[blueBallPosition[0]][blueMy]=='O')){
                            break;
                        }

                        if(redMy&amp;gt;=1 &amp;amp;&amp;amp; map[redBallPosition[0]][redMy]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[1]=redMy;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(blueMy&amp;gt;=1 &amp;amp;&amp;amp; map[blueBallPosition[0]][blueMy]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[1]=blueMy;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
//                        printMap();
                    }
                    if(result) return true;
                }
                else{
                    while(true){
                        int redMy = redBallPosition[1]+dy[3];
                        int blueMy = blueBallPosition[1]+dy[3];

                        if(!(map[redBallPosition[0]][redMy]=='.' || map[redBallPosition[0]][redMy]=='O'
                                || map[blueBallPosition[0]][blueMy]=='.' || map[blueBallPosition[0]][blueMy]=='O')){
                            break;
                        }

                        if(blueMy&amp;gt;=1 &amp;amp;&amp;amp; map[blueBallPosition[0]][blueMy]!='#'){
                            map[blueBallPosition[0]][blueBallPosition[1]]='.';
                            blueBallPosition[1]=blueMy;
                            map[blueBallPosition[0]][blueBallPosition[1]]='B';
                        }

                        if(redMy&amp;gt;=1 &amp;amp;&amp;amp; map[redBallPosition[0]][redMy]!='#'){
                            map[redBallPosition[0]][redBallPosition[1]]='.';
                            redBallPosition[1]=redMy;
                            map[redBallPosition[0]][redBallPosition[1]]='R';
                        }

                        if(redBallPosition[0]==goal[0] &amp;amp;&amp;amp; redBallPosition[1]==goal[1]){
                            map[goal[0]][goal[1]]='O';
                            result=true;
                        }

                        if(blueBallPosition[0]==goal[0] &amp;amp;&amp;amp; blueBallPosition[1]==goal[1]){
                            return false;
                        }
                    }
                    if(result) return true;
                }
            }
//            printMap();
        }
        return result;
    }

    static void printDirection(){
        for(int i=0;i&amp;lt;maxCount;++i){
            System.out.print(direction[i]+&quot; &quot;);
        }
        System.out.println();
    }

    static void printMap(){
        System.out.println(&quot;=======================&quot;);
        for(int i=0;i&amp;lt;N;++i){
            for(int j=0;j&amp;lt;M;++j){
                System.out.print(map[i][j]+&quot; &quot;);
            }
            System.out.println();
        }
        System.out.println(&quot;=======================&quot;);
    }

    static void dfs(int depth){
        if(depth==maxCount){
            init();
            if(incline()){
                isSuccess=true;
            }
            return;
        }

        for(int i=0;i&amp;lt;4;++i){
            direction[depth]=i;
            dfs(depth+1);
        }
    }

    static void init(){
        for(int i=0;i&amp;lt;N;++i){
            map[i]=originMap[i].clone();
        }

        redBallPosition[0]=originRedBallPosition[0];
        redBallPosition[1]=originRedBallPosition[1];
        blueBallPosition[0]=originBlueBallPosition[0];
        blueBallPosition[1]=originBlueBallPosition[1];
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        map = new char[N][M];
        originMap = new char[N][M];

        for(int i=0;i&amp;lt;N;++i){
            String tempMap = br.readLine();
            for(int j=0;j&amp;lt;M;++j){
                originMap[i][j]=tempMap.charAt(j);
                if(originMap[i][j]=='R'){
                    originRedBallPosition[0]=i;
                    originRedBallPosition[1]=j;
                }
                else if(originMap[i][j]=='B'){
                    originBlueBallPosition[0]=i;
                    originBlueBallPosition[1]=j;
                }
                else if(originMap[i][j]=='O'){
                    goal[0]=i;
                    goal[1]=j;
                }
            }
        }

        for(int i=1;i&amp;lt;=10;++i){
            maxCount=i;
            init();
            dfs(0);
            if(isSuccess){
                bw.write(maxCount+&quot;\n&quot;);
                bw.flush();
                bw.close();
                return;
            }
        }
        bw.write(&quot;-1\n&quot;);
        bw.flush();
        bw.close();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgT9YA/btsCc4eAnu8/dIeBeUsIp6HNoK1D38zb81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgT9YA/btsCc4eAnu8/dIeBeUsIp6HNoK1D38zb81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgT9YA/btsCc4eAnu8/dIeBeUsIp6HNoK1D38zb81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgT9YA%2FbtsCc4eAnu8%2FdIeBeUsIp6HNoK1D38zb81%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;1430&quot; height=&quot;94&quot; data-origin-width=&quot;1430&quot; data-origin-height=&quot;94&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;</description>
      <category>알고리즘||코딩테스트/삼성 SW 역량테스트</category>
      <category>13460</category>
      <category>BOJ</category>
      <category>Java</category>
      <category>구슬 탈출 2</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/225</guid>
      <comments>https://chaechaeros.tistory.com/225#entry225comment</comments>
      <pubDate>Tue, 19 Dec 2023 15:00:39 +0900</pubDate>
    </item>
    <item>
      <title>[BOJ 5373] 큐빙 - JAVA, Platinum5</title>
      <link>https://chaechaeros.tistory.com/224</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/5373&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/5373&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702895954314&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;5373번: 큐빙&quot; data-og-description=&quot;각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/5373&quot; data-og-url=&quot;https://www.acmicpc.net/problem/5373&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9GEci/hyULQ3iOXt/XMqn3AEfXtKja9Aand3Z30/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/5373&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/5373&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9GEci/hyULQ3iOXt/XMqn3AEfXtKja9Aand3Z30/img.png?width=2834&amp;amp;height=1480&amp;amp;face=0_0_2834_1480');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;5373번: 큐빙&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1437&quot; data-origin-height=&quot;845&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4mihB/btsCfCakqLN/FShJe7KcFbo9quiyCcFcjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4mihB/btsCfCakqLN/FShJe7KcFbo9quiyCcFcjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4mihB/btsCfCakqLN/FShJe7KcFbo9quiyCcFcjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4mihB%2FbtsCfCakqLN%2FFShJe7KcFbo9quiyCcFcjK%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;1437&quot; height=&quot;845&quot; data-origin-width=&quot;1437&quot; data-origin-height=&quot;845&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sLDuY/btsCgwHrtPq/UNahQ4O1qKAOnv3lguFrD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sLDuY/btsCgwHrtPq/UNahQ4O1qKAOnv3lguFrD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sLDuY/btsCgwHrtPq/UNahQ4O1qKAOnv3lguFrD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsLDuY%2FbtsCgwHrtPq%2FUNahQ4O1qKAOnv3lguFrD1%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;1429&quot; height=&quot;420&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1436&quot; data-origin-height=&quot;534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/474eg/btsB81aICso/zjIqFBvu3VDaheeZ0d6TpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/474eg/btsB81aICso/zjIqFBvu3VDaheeZ0d6TpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/474eg/btsB81aICso/zjIqFBvu3VDaheeZ0d6TpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F474eg%2FbtsB81aICso%2FzjIqFBvu3VDaheeZ0d6TpK%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;1436&quot; height=&quot;534&quot; data-origin-width=&quot;1436&quot; data-origin-height=&quot;534&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;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;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;2. 큐브를 이중 배열 사용하여 손수 구현한다.&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;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;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;/b&gt;&lt;/h2&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;/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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회전으로 인해 값 변경의 영향을 받는 4 방위 면의 값이 변경되는 배열의 위치를 조사하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알맞은 변경 값을 대입시켜줘야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;1054&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTCts/btsB7ftQGYS/r38kK3hPy6vk5Lw4qfbduK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTCts/btsB7ftQGYS/r38kK3hPy6vk5Lw4qfbduK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTCts/btsB7ftQGYS/r38kK3hPy6vk5Lw4qfbduK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTCts%2FbtsB7ftQGYS%2Fr38kK3hPy6vk5Lw4qfbduK%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;506&quot; height=&quot;427&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;1054&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림은 큐브에서 Left 방향을 회전시킬 때 영향받는 4방위 면을 그림으로 나타냈다.&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;/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;Front[0][0] = Up[0][0];&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 위처럼 Front[0][0]의 값을 본 상태의 Up[0][0]값으로 입력시켰을 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 Down[0][0]=Front[0][0]을 대입했을 때 Down[0][0]에 Up[0][0] 값이 대입되는 문제가 생기기 때문이다.&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;tempUp[]= { Up[0][0], Up[1][0], Up[2][0]};&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tempFront[]= {Front[0][0],Front[1][0],Front[2][0]};&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과 같이 필요한 값이 포함된 배열로 복사해 생성한 뒤&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fornt[0][0]=tempUp[0];&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Down[0][0]=Front[0];&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;&lt;b&gt; 코드 적용&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 큐브를 돌릴 횟수와 방향을 입력받는다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1702898249705&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st;

    int T = Integer.parseInt(br.readLine()); // 테스트 케이스 횟수 입력
    for(int i=0;i&amp;lt;T;++i){
        // resetCube(); // 큐브 초기화 함수로 나중에 사용됨
        int n = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        while(st.hasMoreTokens()){
            String command = st.nextToken();
            // rotate(command.charAt(0),command.charAt(1)); // 큐브 회전 함수로 나중에 사용됨
        }
        // printUpSide(); // 큐브 윗면 출력 함수로 나중에 사용됨
    }
}&lt;/code&gt;&lt;/pre&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;b&gt;2. 큐브를 이중 배열 사용하여 손수 구현한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1702898273410&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static char upSide[][] = {{'w','w','w'},{'w','w','w'},{'w','w','w'}};
static char downSide[][] = {{'y','y','y'},{'y','y','y'},{'y','y','y'}};
static char frontSide[][] = {{'r','r','r'},{'r','r','r'},{'r','r','r'}};
static char backSide[][] = {{'o','o','o'},{'o','o','o'},{'o','o','o'}};
static char leftSide[][] = {{'g','g','g'},{'g','g','g'},{'g','g','g'}};
static char rightSide[][] = {{'b','b','b'},{'b','b','b'},{'b','b','b'}};&lt;/code&gt;&lt;/pre&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;b&gt;3. 큐브의 특정 부분을 원하는 방향으로 회전시키는 함수를 작성한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1702898309750&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void rotate(char side, char direction){
    if(side=='U'){
        if(direction=='+'){
            char tempUpside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempUpside[i]=upSide[i].clone();
            }
            upSide[0][0]=tempUpside[2][0];
            upSide[0][1]=tempUpside[1][0];
            upSide[0][2]=tempUpside[0][0];

            upSide[1][0]=tempUpside[2][1];
            upSide[1][2]=tempUpside[0][1];

            upSide[2][0]=tempUpside[2][2];
            upSide[2][1]=tempUpside[1][2];
            upSide[2][2]=tempUpside[0][2];

            char tempFrontSide[] = frontSide[0].clone();
            char tempLeftSide[] = leftSide[0].clone();
            char tempBackSide[] = backSide[0].clone();
            char tempRightSide[] = rightSide[0].clone();
            frontSide[0]=tempRightSide;
            leftSide[0]=tempFrontSide;
            backSide[0]=tempLeftSide;
            rightSide[0]=tempBackSide;
        }
        else if(direction=='-'){
            char tempUpside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempUpside[i]=upSide[i].clone();
            }
            upSide[0][0]=tempUpside[0][2];
            upSide[0][1]=tempUpside[1][2];
            upSide[0][2]=tempUpside[2][2];

            upSide[1][0]=tempUpside[0][1];
            upSide[1][2]=tempUpside[2][1];

            upSide[2][0]=tempUpside[0][0];
            upSide[2][1]=tempUpside[1][0];
            upSide[2][2]=tempUpside[2][0];

            char tempFrontSide[] = frontSide[0].clone();
            char tempLeftSide[] = leftSide[0].clone();
            char tempBackSide[] = backSide[0].clone();
            char tempRightSide[] = rightSide[0].clone();
            frontSide[0]=tempLeftSide;
            leftSide[0]=tempBackSide;
            backSide[0]=tempRightSide;
            rightSide[0]=tempFrontSide;
        }
    }
    else if(side=='D'){
        if(direction=='+'){
            char tempDownside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempDownside[i]=downSide[i].clone();
            }
            downSide[0][0]=tempDownside[2][0];
            downSide[0][1]=tempDownside[1][0];
            downSide[0][2]=tempDownside[0][0];

            downSide[1][0]=tempDownside[2][1];
            downSide[1][2]=tempDownside[0][1];

            downSide[2][0]=tempDownside[2][2];
            downSide[2][1]=tempDownside[1][2];
            downSide[2][2]=tempDownside[0][2];

            char tempFrontSide[] = frontSide[2].clone();
            char tempLeftSide[] = leftSide[2].clone();
            char tempBackSide[] = backSide[2].clone();
            char tempRightSide[] = rightSide[2].clone();
            frontSide[2]=tempLeftSide;
            leftSide[2]=tempBackSide;
            backSide[2]=tempRightSide;
            rightSide[2]=tempFrontSide;
        }
        else if(direction=='-'){
            char tempDownside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempDownside[i]=downSide[i].clone();
            }
            downSide[0][0]=tempDownside[0][2];
            downSide[0][1]=tempDownside[1][2];
            downSide[0][2]=tempDownside[2][2];

            downSide[1][0]=tempDownside[0][1];
            downSide[1][2]=tempDownside[2][1];

            downSide[2][0]=tempDownside[0][0];
            downSide[2][1]=tempDownside[1][0];
            downSide[2][2]=tempDownside[2][0];

            char tempFrontSide[] = frontSide[2].clone();
            char tempLeftSide[] = leftSide[2].clone();
            char tempBackSide[] = backSide[2].clone();
            char tempRightSide[] = rightSide[2].clone();
            frontSide[2]=tempRightSide;
            leftSide[2]=tempFrontSide;
            backSide[2]=tempLeftSide;
            rightSide[2]=tempBackSide;
        }
    }
    else if(side=='F'){
        if(direction=='+'){
            char tempFrontside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempFrontside[i]=frontSide[i].clone();
            }
            frontSide[0][0]=tempFrontside[2][0];
            frontSide[0][1]=tempFrontside[1][0];
            frontSide[0][2]=tempFrontside[0][0];

            frontSide[1][0]=tempFrontside[2][1];
            frontSide[1][2]=tempFrontside[0][1];

            frontSide[2][0]=tempFrontside[2][2];
            frontSide[2][1]=tempFrontside[1][2];
            frontSide[2][2]=tempFrontside[0][2];

            char tempUpSide[] = upSide[2].clone();
            char tempLeftSide[] = {leftSide[2][2],leftSide[1][2],leftSide[0][2]};
            char tempDownSide[] = {downSide[0][2],downSide[0][1],downSide[0][0]};
            char tempRightSide[] = {rightSide[0][0],rightSide[1][0],rightSide[2][0]};

            upSide[2][0]=tempLeftSide[0];
            upSide[2][1]=tempLeftSide[1];
            upSide[2][2]=tempLeftSide[2];

            rightSide[0][0]=tempUpSide[0];
            rightSide[1][0]=tempUpSide[1];
            rightSide[2][0]=tempUpSide[2];

            downSide[0][2]=tempRightSide[0];
            downSide[0][1]=tempRightSide[1];
            downSide[0][0]=tempRightSide[2];

            leftSide[2][2]=tempDownSide[0];
            leftSide[1][2]=tempDownSide[1];
            leftSide[0][2]=tempDownSide[2];
        }
        else if(direction=='-'){
            char tempFrontside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempFrontside[i]=frontSide[i].clone();
            }
            frontSide[0][0]=tempFrontside[0][2];
            frontSide[0][1]=tempFrontside[1][2];
            frontSide[0][2]=tempFrontside[2][2];

            frontSide[1][0]=tempFrontside[0][1];
            frontSide[1][2]=tempFrontside[2][1];

            frontSide[2][0]=tempFrontside[0][0];
            frontSide[2][1]=tempFrontside[1][0];
            frontSide[2][2]=tempFrontside[2][0];

            char tempUpSide[] = upSide[2].clone();
            char tempLeftSide[] = {leftSide[2][2],leftSide[1][2],leftSide[0][2]};
            char tempDownSide[] = {downSide[0][2],downSide[0][1],downSide[0][0]};
            char tempRightSide[] = {rightSide[0][0],rightSide[1][0],rightSide[2][0]};

            upSide[2][0]=tempRightSide[0];
            upSide[2][1]=tempRightSide[1];
            upSide[2][2]=tempRightSide[2];

            rightSide[0][0]=tempDownSide[0];
            rightSide[1][0]=tempDownSide[1];
            rightSide[2][0]=tempDownSide[2];

            downSide[0][2]=tempLeftSide[0];
            downSide[0][1]=tempLeftSide[1];
            downSide[0][0]=tempLeftSide[2];

            leftSide[2][2]=tempUpSide[0];
            leftSide[1][2]=tempUpSide[1];
            leftSide[0][2]=tempUpSide[2];
        }
    }
    else if(side=='B'){
        if(direction=='+'){
            char tempBackside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempBackside[i]=backSide[i].clone();
            }
            backSide[0][0]=tempBackside[2][0];
            backSide[0][1]=tempBackside[1][0];
            backSide[0][2]=tempBackside[0][0];

            backSide[1][0]=tempBackside[2][1];
            backSide[1][2]=tempBackside[0][1];

            backSide[2][0]=tempBackside[2][2];
            backSide[2][1]=tempBackside[1][2];
            backSide[2][2]=tempBackside[0][2];

            char tempUpSide[] = {upSide[0][2],upSide[0][1],upSide[0][0]};
            char tempLeftSide[] = {leftSide[0][0],leftSide[1][0],leftSide[2][0]};
            char tempDownSide[] = {downSide[2][0],downSide[2][1],downSide[2][2]};
            char tempRightSide[] = {rightSide[2][2],rightSide[1][2],rightSide[0][2]};
            leftSide[0][0]=tempUpSide[0];
            leftSide[1][0]=tempUpSide[1];
            leftSide[2][0]=tempUpSide[2];

            downSide[2][0]=tempLeftSide[0];
            downSide[2][1]=tempLeftSide[1];
            downSide[2][2]=tempLeftSide[2];

            rightSide[2][2]=tempDownSide[0];
            rightSide[1][2]=tempDownSide[1];
            rightSide[0][2]=tempDownSide[2];

            upSide[0][2]=tempRightSide[0];
            upSide[0][1]=tempRightSide[1];
            upSide[0][0]=tempRightSide[2];
        }
        else if(direction=='-'){
            char tempBackside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempBackside[i]=backSide[i].clone();
            }
            backSide[0][0]=tempBackside[0][2];
            backSide[0][1]=tempBackside[1][2];
            backSide[0][2]=tempBackside[2][2];

            backSide[1][0]=tempBackside[0][1];
            backSide[1][2]=tempBackside[2][1];

            backSide[2][0]=tempBackside[0][0];
            backSide[2][1]=tempBackside[1][0];
            backSide[2][2]=tempBackside[2][0];

            char tempUpSide[] = {upSide[0][2],upSide[0][1],upSide[0][0]};
            char tempLeftSide[] = {leftSide[0][0],leftSide[1][0],leftSide[2][0]};
            char tempDownSide[] = {downSide[2][0],downSide[2][1],downSide[2][2]};
            char tempRightSide[] = {rightSide[2][2],rightSide[1][2],rightSide[0][2]};
            leftSide[0][0]=tempDownSide[0];
            leftSide[1][0]=tempDownSide[1];
            leftSide[2][0]=tempDownSide[2];

            downSide[2][0]=tempRightSide[0];
            downSide[2][1]=tempRightSide[1];
            downSide[2][2]=tempRightSide[2];

            rightSide[2][2]=tempUpSide[0];
            rightSide[1][2]=tempUpSide[1];
            rightSide[0][2]=tempUpSide[2];

            upSide[0][2]=tempLeftSide[0];
            upSide[0][1]=tempLeftSide[1];
            upSide[0][0]=tempLeftSide[2];
        }
    }
    else if(side=='L'){
        if(direction=='+'){
            char tempLeftside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempLeftside[i]=leftSide[i].clone();
            }
            leftSide[0][0]=tempLeftside[2][0];
            leftSide[0][1]=tempLeftside[1][0];
            leftSide[0][2]=tempLeftside[0][0];

            leftSide[1][0]=tempLeftside[2][1];
            leftSide[1][2]=tempLeftside[0][1];

            leftSide[2][0]=tempLeftside[2][2];
            leftSide[2][1]=tempLeftside[1][2];
            leftSide[2][2]=tempLeftside[0][2];

            char tempUpSide[] = {upSide[0][0],upSide[1][0],upSide[2][0]};
            char tempFrontSide[] = {frontSide[0][0],frontSide[1][0],frontSide[2][0]};
            char tempDownSide[] = {downSide[0][0],downSide[1][0],downSide[2][0]};
            char tempBackSide[] = {backSide[2][2],backSide[1][2],backSide[0][2]};

            upSide[0][0]=tempBackSide[0];
            upSide[1][0]=tempBackSide[1];
            upSide[2][0]=tempBackSide[2];

            frontSide[0][0]=tempUpSide[0];
            frontSide[1][0]=tempUpSide[1];
            frontSide[2][0]=tempUpSide[2];

            downSide[0][0]=tempFrontSide[0];
            downSide[1][0]=tempFrontSide[1];
            downSide[2][0]=tempFrontSide[2];

            backSide[2][2]=tempDownSide[0];
            backSide[1][2]=tempDownSide[1];
            backSide[0][2]=tempDownSide[2];
        }
        else if(direction=='-'){
            char tempLeftside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempLeftside[i]=leftSide[i].clone();
            }
            leftSide[0][0]=tempLeftside[0][2];
            leftSide[0][1]=tempLeftside[1][2];
            leftSide[0][2]=tempLeftside[2][2];

            leftSide[1][0]=tempLeftside[0][1];
            leftSide[1][2]=tempLeftside[2][1];

            leftSide[2][0]=tempLeftside[0][0];
            leftSide[2][1]=tempLeftside[1][0];
            leftSide[2][2]=tempLeftside[2][0];

            char tempUpSide[] = {upSide[0][0],upSide[1][0],upSide[2][0]};
            char tempFrontSide[] = {frontSide[0][0],frontSide[1][0],frontSide[2][0]};
            char tempDownSide[] = {downSide[0][0],downSide[1][0],downSide[2][0]};
            char tempBackSide[] = {backSide[2][2],backSide[1][2],backSide[0][2]};

            upSide[0][0]=tempFrontSide[0];
            upSide[1][0]=tempFrontSide[1];
            upSide[2][0]=tempFrontSide[2];

            frontSide[0][0]=tempDownSide[0];
            frontSide[1][0]=tempDownSide[1];
            frontSide[2][0]=tempDownSide[2];

            downSide[0][0]=tempBackSide[0];
            downSide[1][0]=tempBackSide[1];
            downSide[2][0]=tempBackSide[2];

            backSide[2][2]=tempUpSide[0];
            backSide[1][2]=tempUpSide[1];
            backSide[0][2]=tempUpSide[2];
        }
    }
    else if(side=='R'){
        if(direction=='+'){
            char tempRightside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempRightside[i]=rightSide[i].clone();
            }
            rightSide[0][0]=tempRightside[2][0];
            rightSide[0][1]=tempRightside[1][0];
            rightSide[0][2]=tempRightside[0][0];

            rightSide[1][0]=tempRightside[2][1];
            rightSide[1][2]=tempRightside[0][1];

            rightSide[2][0]=tempRightside[2][2];
            rightSide[2][1]=tempRightside[1][2];
            rightSide[2][2]=tempRightside[0][2];

            char tempUpSide[] = {upSide[2][2],upSide[1][2],upSide[0][2]};
            char tempFrontSide[] = {frontSide[2][2],frontSide[1][2],frontSide[0][2]};
            char tempDownSide[] = {downSide[2][2],downSide[1][2],downSide[0][2]};
            char tempBackSide[] = {backSide[0][0],backSide[1][0],backSide[2][0]};

            upSide[2][2]=tempFrontSide[0];
            upSide[1][2]=tempFrontSide[1];
            upSide[0][2]=tempFrontSide[2];

            backSide[0][0]=tempUpSide[0];
            backSide[1][0]=tempUpSide[1];
            backSide[2][0]=tempUpSide[2];

            downSide[2][2]=tempBackSide[0];
            downSide[1][2]=tempBackSide[1];
            downSide[0][2]=tempBackSide[2];

            frontSide[2][2]=tempDownSide[0];
            frontSide[1][2]=tempDownSide[1];
            frontSide[0][2]=tempDownSide[2];
        }
        else if(direction=='-'){
            char tempRightside[][] = new char[3][3];
            for(int i=0;i&amp;lt;3;++i){
                tempRightside[i]=rightSide[i].clone();
            }
            rightSide[0][0]=tempRightside[0][2];
            rightSide[0][1]=tempRightside[1][2];
            rightSide[0][2]=tempRightside[2][2];

            rightSide[1][0]=tempRightside[0][1];
            rightSide[1][2]=tempRightside[2][1];

            rightSide[2][0]=tempRightside[0][0];
            rightSide[2][1]=tempRightside[1][0];
            rightSide[2][2]=tempRightside[2][0];

            char tempUpSide[] = {upSide[2][2],upSide[1][2],upSide[0][2]};
            char tempFrontSide[] = {frontSide[2][2],frontSide[1][2],frontSide[0][2]};
            char tempDownSide[] = {downSide[2][2],downSide[1][2],downSide[0][2]};
            char tempBackSide[] = {backSide[0][0],backSide[1][0],backSide[2][0]};

            upSide[2][2]=tempBackSide[0];
            upSide[1][2]=tempBackSide[1];
            upSide[0][2]=tempBackSide[2];

            backSide[0][0]=tempDownSide[0];
            backSide[1][0]=tempDownSide[1];
            backSide[2][0]=tempDownSide[2];

            downSide[2][2]=tempFrontSide[0];
            downSide[1][2]=tempFrontSide[1];
            downSide[0][2]=tempFrontSide[2];

            frontSide[2][2]=tempUpSide[0];
            frontSide[1][2]=tempUpSide[1];
            frontSide[0][2]=tempUpSide[2];
        }
    }
}&lt;/code&gt;&lt;/pre&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;b&gt;4. 윗면을 출력하는 함수를 작성한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1702898329292&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void printUpSide(){
    for(int i=0;i&amp;lt;3;++i){
        for(int j=0;j&amp;lt;3;++j){
            System.out.print(upSide[i][j]);
        }
        System.out.println();
    }
}&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;b&gt;⌨제출 코드&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1702898384346&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    static char upSide[][] = {{'w','w','w'},{'w','w','w'},{'w','w','w'}};
    static char downSide[][] = {{'y','y','y'},{'y','y','y'},{'y','y','y'}};
    static char frontSide[][] = {{'r','r','r'},{'r','r','r'},{'r','r','r'}};
    static char backSide[][] = {{'o','o','o'},{'o','o','o'},{'o','o','o'}};
    static char leftSide[][] = {{'g','g','g'},{'g','g','g'},{'g','g','g'}};
    static char rightSide[][] = {{'b','b','b'},{'b','b','b'},{'b','b','b'}};

    static void resetCube(){
        upSide = new char[][]{{'w', 'w', 'w'}, {'w', 'w', 'w'}, {'w', 'w', 'w'}};
        downSide = new char[][]{{'y','y','y'},{'y','y','y'},{'y','y','y'}};
        frontSide = new char[][]{{'r','r','r'},{'r','r','r'},{'r','r','r'}};
        backSide = new char[][]{{'o','o','o'},{'o','o','o'},{'o','o','o'}};
        leftSide = new char[][]{{'g','g','g'},{'g','g','g'},{'g','g','g'}};
        rightSide = new char[][]{{'b','b','b'},{'b','b','b'},{'b','b','b'}};
    }
    static void rotate(char side, char direction){
        if(side=='U'){
            if(direction=='+'){
                char tempUpside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempUpside[i]=upSide[i].clone();
                }
                upSide[0][0]=tempUpside[2][0];
                upSide[0][1]=tempUpside[1][0];
                upSide[0][2]=tempUpside[0][0];

                upSide[1][0]=tempUpside[2][1];
                upSide[1][2]=tempUpside[0][1];

                upSide[2][0]=tempUpside[2][2];
                upSide[2][1]=tempUpside[1][2];
                upSide[2][2]=tempUpside[0][2];

                char tempFrontSide[] = frontSide[0].clone();
                char tempLeftSide[] = leftSide[0].clone();
                char tempBackSide[] = backSide[0].clone();
                char tempRightSide[] = rightSide[0].clone();
                frontSide[0]=tempRightSide;
                leftSide[0]=tempFrontSide;
                backSide[0]=tempLeftSide;
                rightSide[0]=tempBackSide;
            }
            else if(direction=='-'){
                char tempUpside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempUpside[i]=upSide[i].clone();
                }
                upSide[0][0]=tempUpside[0][2];
                upSide[0][1]=tempUpside[1][2];
                upSide[0][2]=tempUpside[2][2];

                upSide[1][0]=tempUpside[0][1];
                upSide[1][2]=tempUpside[2][1];

                upSide[2][0]=tempUpside[0][0];
                upSide[2][1]=tempUpside[1][0];
                upSide[2][2]=tempUpside[2][0];

                char tempFrontSide[] = frontSide[0].clone();
                char tempLeftSide[] = leftSide[0].clone();
                char tempBackSide[] = backSide[0].clone();
                char tempRightSide[] = rightSide[0].clone();
                frontSide[0]=tempLeftSide;
                leftSide[0]=tempBackSide;
                backSide[0]=tempRightSide;
                rightSide[0]=tempFrontSide;
            }
        }
        else if(side=='D'){
            if(direction=='+'){
                char tempDownside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempDownside[i]=downSide[i].clone();
                }
                downSide[0][0]=tempDownside[2][0];
                downSide[0][1]=tempDownside[1][0];
                downSide[0][2]=tempDownside[0][0];

                downSide[1][0]=tempDownside[2][1];
                downSide[1][2]=tempDownside[0][1];

                downSide[2][0]=tempDownside[2][2];
                downSide[2][1]=tempDownside[1][2];
                downSide[2][2]=tempDownside[0][2];

                char tempFrontSide[] = frontSide[2].clone();
                char tempLeftSide[] = leftSide[2].clone();
                char tempBackSide[] = backSide[2].clone();
                char tempRightSide[] = rightSide[2].clone();
                frontSide[2]=tempLeftSide;
                leftSide[2]=tempBackSide;
                backSide[2]=tempRightSide;
                rightSide[2]=tempFrontSide;
            }
            else if(direction=='-'){
                char tempDownside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempDownside[i]=downSide[i].clone();
                }
                downSide[0][0]=tempDownside[0][2];
                downSide[0][1]=tempDownside[1][2];
                downSide[0][2]=tempDownside[2][2];

                downSide[1][0]=tempDownside[0][1];
                downSide[1][2]=tempDownside[2][1];

                downSide[2][0]=tempDownside[0][0];
                downSide[2][1]=tempDownside[1][0];
                downSide[2][2]=tempDownside[2][0];

                char tempFrontSide[] = frontSide[2].clone();
                char tempLeftSide[] = leftSide[2].clone();
                char tempBackSide[] = backSide[2].clone();
                char tempRightSide[] = rightSide[2].clone();
                frontSide[2]=tempRightSide;
                leftSide[2]=tempFrontSide;
                backSide[2]=tempLeftSide;
                rightSide[2]=tempBackSide;
            }
        }
        else if(side=='F'){
            if(direction=='+'){
                char tempFrontside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempFrontside[i]=frontSide[i].clone();
                }
                frontSide[0][0]=tempFrontside[2][0];
                frontSide[0][1]=tempFrontside[1][0];
                frontSide[0][2]=tempFrontside[0][0];

                frontSide[1][0]=tempFrontside[2][1];
                frontSide[1][2]=tempFrontside[0][1];

                frontSide[2][0]=tempFrontside[2][2];
                frontSide[2][1]=tempFrontside[1][2];
                frontSide[2][2]=tempFrontside[0][2];

                char tempUpSide[] = upSide[2].clone();
                char tempLeftSide[] = {leftSide[2][2],leftSide[1][2],leftSide[0][2]};
                char tempDownSide[] = {downSide[0][2],downSide[0][1],downSide[0][0]};
                char tempRightSide[] = {rightSide[0][0],rightSide[1][0],rightSide[2][0]};

                upSide[2][0]=tempLeftSide[0];
                upSide[2][1]=tempLeftSide[1];
                upSide[2][2]=tempLeftSide[2];

                rightSide[0][0]=tempUpSide[0];
                rightSide[1][0]=tempUpSide[1];
                rightSide[2][0]=tempUpSide[2];

                downSide[0][2]=tempRightSide[0];
                downSide[0][1]=tempRightSide[1];
                downSide[0][0]=tempRightSide[2];

                leftSide[2][2]=tempDownSide[0];
                leftSide[1][2]=tempDownSide[1];
                leftSide[0][2]=tempDownSide[2];
            }
            else if(direction=='-'){
                char tempFrontside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempFrontside[i]=frontSide[i].clone();
                }
                frontSide[0][0]=tempFrontside[0][2];
                frontSide[0][1]=tempFrontside[1][2];
                frontSide[0][2]=tempFrontside[2][2];

                frontSide[1][0]=tempFrontside[0][1];
                frontSide[1][2]=tempFrontside[2][1];

                frontSide[2][0]=tempFrontside[0][0];
                frontSide[2][1]=tempFrontside[1][0];
                frontSide[2][2]=tempFrontside[2][0];

                char tempUpSide[] = upSide[2].clone();
                char tempLeftSide[] = {leftSide[2][2],leftSide[1][2],leftSide[0][2]};
                char tempDownSide[] = {downSide[0][2],downSide[0][1],downSide[0][0]};
                char tempRightSide[] = {rightSide[0][0],rightSide[1][0],rightSide[2][0]};

                upSide[2][0]=tempRightSide[0];
                upSide[2][1]=tempRightSide[1];
                upSide[2][2]=tempRightSide[2];

                rightSide[0][0]=tempDownSide[0];
                rightSide[1][0]=tempDownSide[1];
                rightSide[2][0]=tempDownSide[2];

                downSide[0][2]=tempLeftSide[0];
                downSide[0][1]=tempLeftSide[1];
                downSide[0][0]=tempLeftSide[2];

                leftSide[2][2]=tempUpSide[0];
                leftSide[1][2]=tempUpSide[1];
                leftSide[0][2]=tempUpSide[2];
            }
        }
        else if(side=='B'){
            if(direction=='+'){
                char tempBackside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempBackside[i]=backSide[i].clone();
                }
                backSide[0][0]=tempBackside[2][0];
                backSide[0][1]=tempBackside[1][0];
                backSide[0][2]=tempBackside[0][0];

                backSide[1][0]=tempBackside[2][1];
                backSide[1][2]=tempBackside[0][1];

                backSide[2][0]=tempBackside[2][2];
                backSide[2][1]=tempBackside[1][2];
                backSide[2][2]=tempBackside[0][2];

                char tempUpSide[] = {upSide[0][2],upSide[0][1],upSide[0][0]};
                char tempLeftSide[] = {leftSide[0][0],leftSide[1][0],leftSide[2][0]};
                char tempDownSide[] = {downSide[2][0],downSide[2][1],downSide[2][2]};
                char tempRightSide[] = {rightSide[2][2],rightSide[1][2],rightSide[0][2]};
                leftSide[0][0]=tempUpSide[0];
                leftSide[1][0]=tempUpSide[1];
                leftSide[2][0]=tempUpSide[2];

                downSide[2][0]=tempLeftSide[0];
                downSide[2][1]=tempLeftSide[1];
                downSide[2][2]=tempLeftSide[2];

                rightSide[2][2]=tempDownSide[0];
                rightSide[1][2]=tempDownSide[1];
                rightSide[0][2]=tempDownSide[2];

                upSide[0][2]=tempRightSide[0];
                upSide[0][1]=tempRightSide[1];
                upSide[0][0]=tempRightSide[2];
            }
            else if(direction=='-'){
                char tempBackside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempBackside[i]=backSide[i].clone();
                }
                backSide[0][0]=tempBackside[0][2];
                backSide[0][1]=tempBackside[1][2];
                backSide[0][2]=tempBackside[2][2];

                backSide[1][0]=tempBackside[0][1];
                backSide[1][2]=tempBackside[2][1];

                backSide[2][0]=tempBackside[0][0];
                backSide[2][1]=tempBackside[1][0];
                backSide[2][2]=tempBackside[2][0];

                char tempUpSide[] = {upSide[0][2],upSide[0][1],upSide[0][0]};
                char tempLeftSide[] = {leftSide[0][0],leftSide[1][0],leftSide[2][0]};
                char tempDownSide[] = {downSide[2][0],downSide[2][1],downSide[2][2]};
                char tempRightSide[] = {rightSide[2][2],rightSide[1][2],rightSide[0][2]};
                leftSide[0][0]=tempDownSide[0];
                leftSide[1][0]=tempDownSide[1];
                leftSide[2][0]=tempDownSide[2];

                downSide[2][0]=tempRightSide[0];
                downSide[2][1]=tempRightSide[1];
                downSide[2][2]=tempRightSide[2];

                rightSide[2][2]=tempUpSide[0];
                rightSide[1][2]=tempUpSide[1];
                rightSide[0][2]=tempUpSide[2];

                upSide[0][2]=tempLeftSide[0];
                upSide[0][1]=tempLeftSide[1];
                upSide[0][0]=tempLeftSide[2];
            }
        }
        else if(side=='L'){
            if(direction=='+'){
                char tempLeftside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempLeftside[i]=leftSide[i].clone();
                }
                leftSide[0][0]=tempLeftside[2][0];
                leftSide[0][1]=tempLeftside[1][0];
                leftSide[0][2]=tempLeftside[0][0];

                leftSide[1][0]=tempLeftside[2][1];
                leftSide[1][2]=tempLeftside[0][1];

                leftSide[2][0]=tempLeftside[2][2];
                leftSide[2][1]=tempLeftside[1][2];
                leftSide[2][2]=tempLeftside[0][2];

                char tempUpSide[] = {upSide[0][0],upSide[1][0],upSide[2][0]};
                char tempFrontSide[] = {frontSide[0][0],frontSide[1][0],frontSide[2][0]};
                char tempDownSide[] = {downSide[0][0],downSide[1][0],downSide[2][0]};
                char tempBackSide[] = {backSide[2][2],backSide[1][2],backSide[0][2]};

                upSide[0][0]=tempBackSide[0];
                upSide[1][0]=tempBackSide[1];
                upSide[2][0]=tempBackSide[2];

                frontSide[0][0]=tempUpSide[0];
                frontSide[1][0]=tempUpSide[1];
                frontSide[2][0]=tempUpSide[2];

                downSide[0][0]=tempFrontSide[0];
                downSide[1][0]=tempFrontSide[1];
                downSide[2][0]=tempFrontSide[2];

                backSide[2][2]=tempDownSide[0];
                backSide[1][2]=tempDownSide[1];
                backSide[0][2]=tempDownSide[2];
            }
            else if(direction=='-'){
                char tempLeftside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempLeftside[i]=leftSide[i].clone();
                }
                leftSide[0][0]=tempLeftside[0][2];
                leftSide[0][1]=tempLeftside[1][2];
                leftSide[0][2]=tempLeftside[2][2];

                leftSide[1][0]=tempLeftside[0][1];
                leftSide[1][2]=tempLeftside[2][1];

                leftSide[2][0]=tempLeftside[0][0];
                leftSide[2][1]=tempLeftside[1][0];
                leftSide[2][2]=tempLeftside[2][0];

                char tempUpSide[] = {upSide[0][0],upSide[1][0],upSide[2][0]};
                char tempFrontSide[] = {frontSide[0][0],frontSide[1][0],frontSide[2][0]};
                char tempDownSide[] = {downSide[0][0],downSide[1][0],downSide[2][0]};
                char tempBackSide[] = {backSide[2][2],backSide[1][2],backSide[0][2]};

                upSide[0][0]=tempFrontSide[0];
                upSide[1][0]=tempFrontSide[1];
                upSide[2][0]=tempFrontSide[2];

                frontSide[0][0]=tempDownSide[0];
                frontSide[1][0]=tempDownSide[1];
                frontSide[2][0]=tempDownSide[2];

                downSide[0][0]=tempBackSide[0];
                downSide[1][0]=tempBackSide[1];
                downSide[2][0]=tempBackSide[2];

                backSide[2][2]=tempUpSide[0];
                backSide[1][2]=tempUpSide[1];
                backSide[0][2]=tempUpSide[2];
            }
        }
        else if(side=='R'){
            if(direction=='+'){
                char tempRightside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempRightside[i]=rightSide[i].clone();
                }
                rightSide[0][0]=tempRightside[2][0];
                rightSide[0][1]=tempRightside[1][0];
                rightSide[0][2]=tempRightside[0][0];

                rightSide[1][0]=tempRightside[2][1];
                rightSide[1][2]=tempRightside[0][1];

                rightSide[2][0]=tempRightside[2][2];
                rightSide[2][1]=tempRightside[1][2];
                rightSide[2][2]=tempRightside[0][2];

                char tempUpSide[] = {upSide[2][2],upSide[1][2],upSide[0][2]};
                char tempFrontSide[] = {frontSide[2][2],frontSide[1][2],frontSide[0][2]};
                char tempDownSide[] = {downSide[2][2],downSide[1][2],downSide[0][2]};
                char tempBackSide[] = {backSide[0][0],backSide[1][0],backSide[2][0]};

                upSide[2][2]=tempFrontSide[0];
                upSide[1][2]=tempFrontSide[1];
                upSide[0][2]=tempFrontSide[2];

                backSide[0][0]=tempUpSide[0];
                backSide[1][0]=tempUpSide[1];
                backSide[2][0]=tempUpSide[2];

                downSide[2][2]=tempBackSide[0];
                downSide[1][2]=tempBackSide[1];
                downSide[0][2]=tempBackSide[2];

                frontSide[2][2]=tempDownSide[0];
                frontSide[1][2]=tempDownSide[1];
                frontSide[0][2]=tempDownSide[2];
            }
            else if(direction=='-'){
                char tempRightside[][] = new char[3][3];
                for(int i=0;i&amp;lt;3;++i){
                    tempRightside[i]=rightSide[i].clone();
                }
                rightSide[0][0]=tempRightside[0][2];
                rightSide[0][1]=tempRightside[1][2];
                rightSide[0][2]=tempRightside[2][2];

                rightSide[1][0]=tempRightside[0][1];
                rightSide[1][2]=tempRightside[2][1];

                rightSide[2][0]=tempRightside[0][0];
                rightSide[2][1]=tempRightside[1][0];
                rightSide[2][2]=tempRightside[2][0];

                char tempUpSide[] = {upSide[2][2],upSide[1][2],upSide[0][2]};
                char tempFrontSide[] = {frontSide[2][2],frontSide[1][2],frontSide[0][2]};
                char tempDownSide[] = {downSide[2][2],downSide[1][2],downSide[0][2]};
                char tempBackSide[] = {backSide[0][0],backSide[1][0],backSide[2][0]};

                upSide[2][2]=tempBackSide[0];
                upSide[1][2]=tempBackSide[1];
                upSide[0][2]=tempBackSide[2];

                backSide[0][0]=tempDownSide[0];
                backSide[1][0]=tempDownSide[1];
                backSide[2][0]=tempDownSide[2];

                downSide[2][2]=tempFrontSide[0];
                downSide[1][2]=tempFrontSide[1];
                downSide[0][2]=tempFrontSide[2];

                frontSide[2][2]=tempUpSide[0];
                frontSide[1][2]=tempUpSide[1];
                frontSide[0][2]=tempUpSide[2];
            }
        }
    }

    static void printUpSide(){
        for(int i=0;i&amp;lt;3;++i){
            for(int j=0;j&amp;lt;3;++j){
                System.out.print(upSide[i][j]);
            }
            System.out.println();
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());
        for(int i=0;i&amp;lt;T;++i){
            resetCube();
            int n = Integer.parseInt(br.readLine());
            st = new StringTokenizer(br.readLine());
            while(st.hasMoreTokens()){
                String command = st.nextToken();
                rotate(command.charAt(0),command.charAt(1));
            }
            printUpSide();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AyZ5K/btsB8TYg57w/4rzd46KDMijRvpNh1SRkz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AyZ5K/btsB8TYg57w/4rzd46KDMijRvpNh1SRkz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AyZ5K/btsB8TYg57w/4rzd46KDMijRvpNh1SRkz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAyZ5K%2FbtsB8TYg57w%2F4rzd46KDMijRvpNh1SRkz1%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;1432&quot; height=&quot;88&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>알고리즘||코딩테스트/삼성 SW 역량테스트</category>
      <category>5373</category>
      <category>BOJ</category>
      <category>Java</category>
      <category>큐빙</category>
      <author>째로스</author>
      <guid isPermaLink="true">https://chaechaeros.tistory.com/224</guid>
      <comments>https://chaechaeros.tistory.com/224#entry224comment</comments>
      <pubDate>Mon, 18 Dec 2023 20:20:23 +0900</pubDate>
    </item>
  </channel>
</rss>