Docker 간단하게 실행해보기
Cloud Shell 기본 명령어
gcloud auth list -> active 계정 이름 확인
gcloud config list project -> 프로젝트 ID 확인
Docker 파일 실행해보기
- hello-world라는 container 실행
docker run hello-world
- 코드 실행 과정
- 도커 daemon이 hello-world라는 image를 로컬에서 확인
- image가 없다면 Docker Hub라는 public registry에서 다운로드하여 사용
- 현재 사용 가능한 도커 images 확인
- 사용 가능하려면 도커 이미지가 built 돼야 함
docker images
- 현재 실행 중인 container 확인 하기
docker ps
- 현재는 안 쓰고 기존에 사용했던 containers까지 확인하기
docker ps -a
->
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2eaebdcdd00 hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago amazing_heyrovsky
- 이때, docker run 실행 시 container의 이름은 임의로 할당
- docker run --name container-name hello-world 사용하면 이름 할당 가능
Docker Image 구성하기
Dockerfile 만들기
- FROM node:lts : base parent image로 lts(long term support) 선택
- WORKDIR /app : container 작업 폴더 선택
- ADD . /app : container의 컨텐츠 설정
- EXPOSE 80 : 80 포트 개방
- CMD ["node", "app.js"] : container가 실행 될 때 node를 통해 app.js 실행
cat > Dockerfile <<EOF
# Use an official Node runtime as the parent image
FROM node:lts
# Set the working directory in the container to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Make the container's port 80 available to the outside world
EXPOSE 80
# Run app.js using node when the container launches
CMD ["node", "app.js"]
EOF
Node application 생성
- 80 포트 개방한 HTTP 서버
- 서버 응답 요청에 Hello World를 반환함
cat > app.js <<EOF
const http = require('http');
const hostname = '0.0.0.0';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\\n');
});
server.listen(port, hostname, () => {
console.log('Server running at http://%s:%s/', hostname, port);
});
process.on('SIGINT', function() {
console.log('Caught interrupt signal and will exit');
process.exit();
});
EOF
Image Build
- . : 현재 위치 정보
- -t : 이름 및 태그 지정
- -t node-app:0.1
- node-app : 이름
- 0.1 : 태그(버전 정보)
- -t node-app:0.1
docker build -t node-app:0.1 .
- 설정한 Dockerfile과 Node Application 정보가 반영됨
Step 2/5 : WORKDIR /app
---> Running in b4507deeca58
Removing intermediate container b4507deeca58
---> c336ae1a770e
Step 3/5 : ADD . /app
---> e7b43644db9e
Step 4/5 : EXPOSE 80
---> Running in 2d040b7fc3c3
Removing intermediate container 2d040b7fc3c3
---> e460aff02083
Step 5/5 : CMD ["node", "app.js"]
---> Running in 409a5c51726d
Removing intermediate container 409a5c51726d
---> fb0551fb9752
Successfully built fb0551fb9752
Successfully tagged node-app:0.1
Run 이해하기
- --name : container 이름 지정
- -p : 포트 포워딩
- 도커의 80 포트에 접근할 포트(4000)
- http://localhost:4000 에 생성된 서버로 접근 가능
- session이 실행 중인 경우만 사용 가능 → background 실행하려면 별도의 옵션 필요
docker run -p 4000:80 --name my-app node-app:0.1
- localhost:4000 서버와 통신하기
curl <http://localhost:4000>
Hello World # app.js에서 설정한 res가 출력 됨
- container 사용 중지 및 삭제
docker stop my-app && docker rm my-app
- -d : background 실행
docker run -p 4000:80 --name my-app -d node-app:0.1
docker ps
- 로그 확인
docker logs container_id
Image 변경 하기
- 생성한 app.js와 Dockerfile을 변경해 image를 변경 가능
- 변경 후 다시 build 해서 node-app:0.2를 생성
docker build -t node-app:0.2 .
- Step 2에서 처럼 변경 사항이 없는 경우 cache를 활용하여 실행 시간을 단축 시킴
Step 1/5 : FROM node:lts
---> e6b2a509415b
Step 2/5 : WORKDIR /app
---> Using cache
---> f6abaccb9891
Step 3/5 : ADD . /app
---> dfd51c48a448
Step 4/5 : EXPOSE 80
---> Running in 06db9ad462de
Removing intermediate container 06db9ad462de
---> c342b8fabeaa
Step 5/5 : CMD ["node", "app.js"]
---> Running in 7ec7d519578a
Removing intermediate container 7ec7d519578a
---> cd70c2529b93
Successfully built cd70c2529b93
Successfully tagged node-app:0.2
Debug
log
- -f : log를 계속 출력
- docker logs -f container_id
exec
- 실행 중인 container를 session에서 접근하기
- -it : pseudo-tty(커맨드) 할당 → 디버그 가능
docker exec -it container_id bash
- 실행 시 root@container_id 에 접근 가능
- exit : 종료
- https://docs.docker.com/engine/reference/commandline/exec/
inspect
- docker inspect container_id
- JSON 형식으로 반환
[
{
"Id": "xxxxxxxxxxxx....",
"Created": "2017-08-07T22:57:49.261726726Z",
"Path": "node",
"Args": [
"app.js"
],
...
- --format : JSON에서 특정 필드 선택해 반환 가능
- IPAddress만 반환
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_id
Publish
- GCR에 image push 후 pull 하기
- 이때, format은 다음과 같이 설정해야 함
- [hostname]/[project-id]/[image]:[tag]
- project-id는 gcloud config list project 를 통해서 확인 가능
- [hostname]/[project-id]/[image]:[tag]
- container publish 진행
docker tag node-app:0.2 gcr.io/project-id/node-app:0.2
- docker images
- gcr.io/[project-id]/node-app 가 추가 됨
REPOSITORY TAG IMAGE ID CREATED
node-app 0.2 76b3beef845e 22 hours ago
gcr.io/[project-id]/node-app 0.2 76b3beef845e 22 hours ago
node-app 0.1 f166cd2a9f10 26 hours ago
node lts 5a767079e3df 7 days ago
hello-world latest 1815c82652c0 7 weeks ago
- push image
- GCP의 Container Registry에 저장 됨!
docker push gcr.io/[project-id]/node-app:0.2
- pull 기능을 확인하기 위해서 모든 기존 container를 실행 중단하고 삭제하기
docker stop $(docker ps -q) # 중지
docker rm $(docker ps -aq) # 삭제
- image도 삭제하기
- node:lts 와 child의 image를 삭제해야 함
- rmi : image 삭제
docker rmi node-app:0.2 gcr.io/[project-id]/node-app node-app:0.1
docker rmi node:lts
docker rmi $(docker images -aq) # remove remaining images
docker images # 실행 결과 아무 image도 없음
- Container Registry에 저장된 이미지 pull하여 실행해보기
docker pull gcr.io/[project-id]/node-app:0.2 # pull
docker run -p 4000:80 -d gcr.io/[project-id]/node-app:0.2
- curl로 확인
curl <http://localhost:4000>
Hello World!