반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • FastAPI (0)
    • ------레거시 (2025.08.23 이전)--.. (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 토비의 스프링
  • Pre-rendering
  • 메이븐 페이즈
  • 자바스크립트 면접
  • serverless computing
  • bean Validation
  • try-with-resources
  • next js app
  • 메이븐 골
  • 서버리스 컴퓨팅
  • 자바 디자인패턴
  • item7
  • Java
  • Javadoc 자바독 자바주석 주석 Comment
  • 디자인패턴
  • 이펙티브자바
  • Next.js
  • pnpm
  • 팩터리 메서드 패턴
  • 추상 팩터리 패턴
  • 자바스크립트
  • 자바 검증
  • 자바스크립트 인터뷰
  • 싱글톤 패턴
  • 슬로우 쿼리
  • 싱글톤
  • 느린 쿼리
  • 이펙티브 자바 item9
  • 도커공식문서
  • 외래키 제약조건
  • 객체복사
  • item8
  • 자바
  • rust
  • 러스트
  • NEXT JS
  • 참조 해제
  • 싱글턴
  • 메이븐 라이프사이클
  • 빈 검증
  • 이펙티브 자바
  • 프로그래머의 뇌
  • 작업기억공간
  • 알고리즘
  • item9
  • 플라이웨이트패턴
  • 자료구조
  • prerendering
  • 스프링 검증
  • MSSQL

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

인프라/도커

도커 명령어의 run -it 옵션은 어떤 의미일까?

2022. 6. 4. 20:40

도커를 사용하다 생긴 궁금증

도커를 공부하다가 docker run -it ubuntu /bin/bash 명령어를 보게 되었다.

여기서 -it 라는 옵션에 대해서 궁금해서 무엇인지 찾아보았는데, -i 는 -interactive 의 의미로 터미널을 통해 도커와 상호작용하겠다는 의미였다.

그렇다면, -t 는 무엇일까 했는데, -tty 로 설명에는 Allocate a pseudo-tty 라고 적혀있었다.

스택 오버플로 답변 1

스택 오버플로의 친절한 답변에서 답을 찾을 수 있었다.

-t 옵션은 Unix/Linux 가 어떻게 터미널에 접근하는지에 대한 것이다. 과거에는 터미널이 물리적인 선으로 연결되어(hard line connection) 있었다. 그리고 이후엔 모뎀을 기반으로 한 연결이 되었다. 이 때는 물리적인 디바이스 드라이버를 가지고 있었고 당연히 실제 장비도 있었다. 일단 일반화된 네트워크가 사용되기 시작하면, pseudo-terminal 드라이버가 개발되었다. 프로그램에 직접 터미널과 관련된 것을 작성할 필요 없이 터미널의 어떤 기능이 사용될 수 있는지를 알도록 분리하기 위해서였다. (stty 와 curses 의 매뉴얼 페이지를 읽어보라.)

위와 같은 배경 지식을 가지고 접근해보자. 옵션을 주지 않고 기본 값으로 컨테이너를 실행하면, stdout 스트림을 얻게 된다 (docker run | <cmd>). -i 옵션을 추가하면, stdin 스트림이 추가된다 (<cmd> | docker run -i). 마지막으로 -t 를 사용해서 -it 옵션을 붙여서 사용하면, 드라이버가 추가된 터미널을 갖게 된다. 만일 프로세스와 상호작용하고 있다면, 아마 이게 우리가 원하던 일일 것이다. 이는 컨테이너를 터미널 커넥션 세션처럼 보이도록 만들어준다.

스택 오버플로 답변 2

먼저 -i 에 대해 알아보자. docker run/exec -i 는 커멘드의 컨테이너 내부의 stdin 을 docker run/exec 자체의 stdin 과 연결해준다.

그래서

  • docker run -i alpine cat 은 입력을 기다리는 빈 라인을 제공한다. "hello" 를 입력하면 "hello" 가 나올 것이다. CTRD + D 를 입력할 때까지 컨테이너는 종료되지 않는다. 왜냐하면, 메인 프로세스인 cat 은 infinite stream 에서 docker run 의 터미널 입력을 기다리기 때문이다.
  • 반면에, echo "hello" | docker run -i alpine cat 은 "hello" 를 출력하고 즉시 종료된다. 왜냐하면 cat 은 인풋 스트림이 끝났다는 것을 인지하고 자신을 종료하기 때문이다.

만일 위의 과정이 끝난 후 docker ps 를 입력하면, 실행중인 컨테이너를 찾아볼 수 없을 것이다. 두 경우 모두 cat 이 자체적으로 종료된다. 그래서 도커도 컨테이너를 종료시킨다.

이제 -t 에 대해 알아보자. -t 는 도커 내부에 있는 메인 프로세스에게 입력이 터미널 디바이스를 통해 들어온다는 것을 알린다.

그래서

  • docker run -t alpine cat 은 빈 라인을 제공하지만, "hello" 를 타이핑해도 어떠한 응답도 받지 못한다. cat 은 터미널 입력과 연결되었다. 하지만 우리가 입력하는 것과는 연결되지 않았다. 우리가 타이핑한 "hello" 는 cat 에게 도착하지 못한다. cat 은 영영 도착하지 않을 입력을 기다리게 된다.
  • echo "hello" | docker run -t alpine cat 은 빈 라인을 제공할 것이고, CTRL + D 명령으로도 종료되지 않을 것이다. 또한 "hello" 라는 응답도 받지 못한다. 왜냐하면 -i 옵션을 넘기지 않았기 때문에 입력 자체가 전달되지 않기 때문이다.

CTRL + C 를 입력하면, 쉘을 돌려받는다. 하지만 docker ps 를 입력해보았을 때, cat 컨테이너가 여전히 돌아가는 중임을 볼 수 있다. cat 은 종료 명령을 정상적으로 입력받지 못했고, 입력 스트림이 끝나지도 않았기 때문에 아직 기다리고 있다.

-t 옵션은 혼자써서는 별 의미가 없고, -i 와 함께 써야 의미를 갖는다.

이번엔, -it 를 함께 썼을 때를 생각해보자. 이는 cat 에게 인풋이 터미널이라고 알리고 동시에 이 터미널을 docker run 터미널의 입력에 연결시킨다. docker run/exec 은 cat 으로 넘기기 전의 tty 가 입력 이라는 것을 보장할 것이다. echo "hello" | docker run -it alpine cat 명령을 시도했을 때, input device is not a TTY 라는 응답을 받는 것은 이 때문이다. 위 경우엔, docker run 의 입력이 터미널이 아닌 이전 echo 로부터의 파이프이다. 그래서 docker run 이 실행되는 곳이 터미널이 아니게 된다.

마지막으로, -i 가 우리가 터미널에서 입력하는 것을 cat 으로 넘긴다면, 왜 -t 를 또 넘겨야 하는 걸까? 이는 터미널이라면, 커멘드가 입력을 다루는 방식이 달라지기 때문이다. 아래의 예를 보자.

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -u root -p 명령어는 패스워드 프롬프트를 제공한다. 이 프롬프트에서 패스워드를 입력하면, 문자들이 그대로 나타날 것이다.
  • docker run -i alpine sh 는 빈 라인을 제공한다. ls 와 같은 커멘드를 입력하면, 출력값을 받는다. 하지만, 프롬프트나 색이 입혀진 출력값은 받지 못한다.

마지막 두 경우에, mysql 과 shell 은 입력을 tty 로 다루지 않기에 인풋을 마스킹하거나 색상을 주는 것과 같이 tty 에 맞춰진 행위를 하지 않는다.

결론

-i 는 stdin 을 연결시켜 우리의 입력이 무사히 도커의 프로세스까지 닿게 한다. 단, 터미널이 연결된 것은 아니어서 터미널에 특화된 행위인 글씨색 제공, 프롬프트 제공, 마스킹 제공 등을 받지 못한다. 단순히 stdout 을 통해 오는 문자열을 볼 수 있을 뿐이다. -t 옵션까지 함께 주어야 터미널에 특화된 기능까지 함께 제공받을 수 있다.

레퍼런스

스택오버플로우 답변 - Confused about Docker -t option to Allocate a pseudo-TTY

반응형
저작자표시 비영리 (새창열림)

'인프라 > 도커' 카테고리의 다른 글

하이퍼바이저 (Hypervisor) 란 무엇인가?  (1) 2024.02.04
도커 실무 - Mariadb 를 사용하는 스프링부트 프로젝트 배포해보기  (0) 2022.06.07
도커 자주 쓰이는 명령어 정리 (Docker Cheat Sheet)  (0) 2022.06.03
도커 소개 (Docker overview - get started 공식문서 번역)  (0) 2022.05.28
도커 (Docker) 가 무엇인지 알아보자.  (0) 2022.05.24
    '인프라/도커' 카테고리의 다른 글
    • 하이퍼바이저 (Hypervisor) 란 무엇인가?
    • 도커 실무 - Mariadb 를 사용하는 스프링부트 프로젝트 배포해보기
    • 도커 자주 쓰이는 명령어 정리 (Docker Cheat Sheet)
    • 도커 소개 (Docker overview - get started 공식문서 번역)
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바