n = int(input())
data = dict()
for i inrange(n):
command = input().split()
if command[0] == "add":
a, b = int(command[1]), int(command[2])
data[a] = b
elif command[0] == "remove":
a = int(command[1])
del(data[a])
else:
a = int(command[1])
if a notin data:
print("None")
else:
print(data[a])
docker run에서의 command의 종류는 대충 제가 생각했을 때 중요한것만 보면 이렇게 있습니다.
--interactive or -i
--tty or -t
--detach or -d
--name
--publish or -p
--restart
--workdir or -w
--volume or -v
--env or -e
--entrypoint
--link
제가 중요하다고 생각한 기준은 이번 구성할때 사용했는가, 검색을 했을때 많이 보였는가와 같은 주관적인 질문의 결과입니다. ㅎㅎ
암튼 하나씩 설명을 해 드리자면
--interactive or -i
Keep STDIN open even if not attached
--tty or -t
Allocate a pseudo-TTY
위의 두가지 -i, -t는 같이 쓰이는 경우가 대부분이며 같이 쓸 경우 -it와 같이 사용할 수도 있습니다.(아마 99.99%는 이렇게 쓰지 않을까 생각합니다... ㅋㅋ)
그리고 이 두가지는 컨테이너를 종료하지 않고 터미널의 데이터를 컨테이너로 전달하기 위해 사용하는 옵션이라고 합니다...
자세한건 저도 잘 모르겠으니까 이 두가지는 필수라고 생각하고 넘어가도 되지 않을까요..? ㅎㅎ
--detach or -d
docker run -d ubuntu- ubuntu 이미지를 사용해서 컨테이너를 올릴건데, 백그라운드로 실행하겠다.
Run container in background and print container ID
컨테이너(container)를 run 시켰을 때 -d 옵션이 있다면 백그라운드(background)에서 실행되게 됩니다. 일반적으로 컨테이너를 실행시키게 되면 command 부분에 입력된 명령을 바로 진행하게 되는데, 이 경우 작업하고 있던 터미널에서 로그(log)가 출력되거나, welcome 메시지와 같은 컨테이너가 출력하고자 하는 명령이 보이는 경우가 많습니다. 또한 python의 경우 일반적으로 python3 명령어가 실행되어 컨테이너를 실행시켰을 때 파이썬 창이 뜨는 경우도 있죠. 이것을 막고자 백그라운드에서 실행시키게 됩니다.
저는 이 명령어를 모든 컨테이너에 써줬는데, 일단 컨테이너만 올리고 설정은 차차 진행할것이기 때문입니다.
--name
docker run --name ubuntu-con ubuntu
- ubuntu 이미지를 사용해서 컨테이너를 올릴건데, 이름을 ubuntu-con으로 정하겠다.
Assign a name to the container
컨테이너의 이름을 설정해 줄 수 있습니다. docker run을 통해서 컨테이너를 올렸을 때 이를 설정해주지 않으면 랜덤으로 이름이 주어지게 됩니다. 컨테이너간의 통신에서 주소대신 해당 이름이 사용되기도 한다니까, 이름 설정할 때 알아보기 쉽게 설정하면 좋겠죠?
--publish or -p
docker run -p 8080:7080/tcp ubuntu
- ubuntu 이미지를 사용해서 컨테이너를 올릴건데, 포트를 tcp방식으로 외부에서 8080포트로 들어오면 컨테이너에서는 7080포트로 사용겠다. ( 포트포워딩 )
Publish a container's port(s) to the host
컨테이너에서 사용할 포트를 설정해줄 수 있습니다. {public port}:{container port}/protocol 의 형식으로 사용되며, public port로 데이터가 들어왔을 때 포트포워딩이 진행되어 container port로 전송되게 됩니다. protocol은 udp, tcp와 같은 여러 종류가 있지만, 기본적으로 tcp로 동작이 되며 굳이 작성 안해도 됩니다. -p 8080:7080 까지만 작성해도 어지간한 작업은 모두 진행할 수 있으니 그냥 모르겠다 싶은 사람들은 이렇게만 사용해주셔도 됩니다.아 참고로 여러개의 포트를 연결하고 싶을 때에는 -p 옵션을 여러번 써주시면 됩니다.
--restart
docker run --restart always ubuntu
- ubuntu 이미지를 사용해서 컨테이너를 올릴건데, 항상 재시작 하겠다.
Restart policy to apply when a container exits
컨테이너가 종료되었을 때 재시작 할것인지 정하는 옵션입니다. 기본적으로 이 부분을 작성하지 않으면 no 상태로 재시작시키지 않지만, 서버의 경우에는 종료되어도 항상 재시작 되어있어야하기 때문에 always나 unless-stopped를 많이 쓰는것 같습니다. 아래의 설명은 restart 옵션의 종류입니다.
- no: 컨테이너를 재시작 X (기본)
- on-failure[:max-retries]: 컨테이너가 정상적으로 종료되지 않은 경우 exit가 0이 아닐때만 재시작.max-retries로 최대 재시작 횟수를 설정할 수 있음
- always: 컨테이너를 exit code에 상관 없이 항상 재시작.
- unless-stopped: 컨테이너를stop시키기 전까지 항상 재시작.
--workdir or -w
docker run --workdir /src python- python 이미지를 사용해서 컨테이너를 올릴건데, 작업을 /src 에서 진행하겠다.
Working directory inside the container
working directory, 즉 작업공간을 설정하는 옵션입니다. 굳이 필요하지는 않지만, bash로 들어갔을 때 해당 디렉토리로 이동하게 됩니다. 전 이 directory를 volume과 함께 연결해서 사용했습니다. 참고로 해당 폴더가 없다면 자동으로 생성하게 됩니다. 이거 때문에 volume과 함께 사용했습니다.
--volume or -v
docker run --workdir /src --volume {HOSTDIR}:/src node- python 이미지를 사용해서 컨테이너를 올릴건데, 작업을 /src에서 진행할거고 {HOSTDIR}과 이 /src 폴더를 동기화시켜서 사용하겠다.
Bind mount a volume
volume을 mount 합니다. 말 그대로 host 폴더와 컨테이너 폴더를 동기화시켜서 사용할 있습니다. 저렇게 작성하게 되면 HOSTDIR의 파일과 /src의 파일이 동일하게 구성됩니다. volume을 /var/lib/docker/volumes와 같은 기본적으로 docker volume이 저장되는 곳에 docker volume create {볼륨이름} 처럼 해서 만들어서 사용할 수도 있고, 이 방법이 제일 권장되기는 하지만, 귀찮다면 그냥 이렇게 해도 되는 것 같습니다. 아직까진 문제를 발견하지를 못했... 참고로 저는 맥 환경에서는 귀찮아서 제 폴더로 연결시켜서 진행했고, 서버에서는 volume을 만들어서 진행했습니다. mount 방법도 3가지인가 있었던거같은데, 저는 본 프로젝트에서는 그 방식을 사용하지는 않았으므로 일단은 넘어가겠습니다
-언젠가 설명하겠지-
--env or -e
docker run -e MYSQL_ROOT_PASSWORD=1234 mysql- mysql 이미지를 사용해서 컨테이너를 올릴건데, MYSQL_ROOT_PASSWORD라는 환경변수의 값을 1234로 설정하겠다.
Set environment variables
그냥 컨테이너 내부에 환경변수를 설정하는 부분입니다. 일반적으로 docker hub에서 이미지의 설명 내용을 보면 각 환경변수가 어떤것을 나타내는지에 대한 설명이 존재합니다. mysql같은 경우는 MYSQL_ROOT_PASSWORD라는 환경변수의 값이 DB의 비밀번호라는 정보를 주었기 때문에, 이를 통해서 컨테이너를 올릴때 비밀번호를 설정하고 실행할 수 있습니다.이부분도 여러개의 환경변수를 설정해주기 위해서는 -e를 여러번 써주시면 됩니다.
이 옵션은 도커 레퍼런스에서는 사용을 권장하고 있지는 않습니다. 그냥 컨테이너를 특정한 별명으로 부르겠다! 라는 설정인데... 그냥 컨테이너 이름으로 접근하거나, ip로 접근하는게 더 낫다고 합니다. 따라서 설명을 길게 하지는 않겠습니다. 공식 사이트에서 하지 말라는건 이유가 있는 법이니까요... 근데, 설명하고 있는 사이트가 많아서 일단 넣기는 했습니다.
아래는 docker-compose 설치하는 내용이지만, 열심히 yml 작성해서 올렸는데, command 부분이 좀 말썽이라서 실제로 올렸을 때에는 사용하지 않았습니다. 미래에 사용할거고, 언젠가 쓰겠지 하는분은 받으셔도 좋은데 이후 게시글에서는 따로 언급이...없을.. 예정입니다 ㅎ
- docker-compose 설치
# docker-compose 설치 - 아래 깃 링크에서 버전 확인하고 {version!!!}대신 넣기
sudo curl -L "https://github.com/docker/compose/releases/download/{version!!!}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 권한설정
sudo chmod +x /usr/local/bin/docker-compose
# Path 에러 방지
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 설치된 docker-compose 버전확인
docker-compose --version