웹사이트 검색

Docker로 Node.js 애플리케이션을 구축하는 방법


소개

Docker 플랫폼을 사용하면 개발자가 애플리케이션을 컨테이너로 패키징하고 실행할 수 있습니다. 컨테이너는 공유 운영 체제에서 실행되는 격리된 프로세스로, 가상 머신에 대한 더 가벼운 대안을 제공합니다. 컨테이너가 새로운 것은 아니지만 더 많은 개발자가 분산 애플리케이션 아키텍처를 사용함에 따라 프로세스 격리 및 환경 표준화를 비롯한 여러 가지 이점을 제공합니다.

Docker를 사용하여 애플리케이션을 빌드하고 확장할 때 출발점은 일반적으로 애플리케이션용 이미지를 생성한 다음 컨테이너에서 실행할 수 있습니다. 이미지에는 애플리케이션 코드, 라이브러리, 구성 파일, 환경 변수 및 런타임이 포함됩니다. 이미지를 사용하면 컨테이너의 환경이 표준화되고 애플리케이션을 빌드하고 실행하는 데 필요한 항목만 포함됩니다.

이 자습서에서는 나중에 사용할 수 있도록 Docker 허브를 사용하는 정적 웹 사이트에 대한 애플리케이션 이미지를 만듭니다. 마지막으로 Docker Hub 리포지토리에서 저장된 이미지를 가져오고 다른 컨테이너를 빌드하여 애플리케이션을 다시 만들고 확장하는 방법을 보여줍니다.

전제 조건

이 자습서를 따르려면 다음이 필요합니다.

  • Ubuntu 18.04 서버 1개, 이 초기 서버 설정 가이드에 따라 설정
  • Ubuntu 18.04에서 Docker를 설치하고 사용하는 방법의 1단계와 2단계에 따라 서버에 Docker를 설치했습니다.
  • NodeSource에서 관리하는 PPA로 설치하는 지침에 따라 Node.js 및 npm이 설치되었습니다.
  • Docker 허브 계정. 이를 설정하는 방법에 대한 개요는 Docker Hub 시작하기 소개를 참조하세요.

1단계 - 애플리케이션 종속성 설치

이미지를 만들려면 먼저 애플리케이션 파일을 만든 다음 컨테이너에 복사해야 합니다. 이러한 파일에는 애플리케이션의 정적 콘텐츠, 코드 및 종속성이 포함됩니다.

루트가 아닌 사용자의 홈 디렉터리에 프로젝트 디렉터리를 만듭니다. 이 예제의 디렉터리 이름은 node_project이지만 다른 것으로 자유롭게 교체할 수 있습니다.

  1. mkdir node_project

다음 디렉터리로 이동합니다.

  1. cd node_project

이것은 프로젝트의 루트 디렉토리가 됩니다.

다음으로 프로젝트의 종속성 및 기타 식별 정보가 포함된 package.json 파일을 만듭니다. nano 또는 선호하는 편집기로 파일을 엽니다.

  1. nano package.json

이름, 작성자, 라이선스, 진입점 및 종속성을 포함하여 프로젝트에 대한 다음 정보를 추가합니다. 작성자 정보를 자신의 이름과 연락처 세부 정보로 바꾸십시오.

{
  "name": "nodejs-image-demo",
  "version": "1.0.0",
  "description": "nodejs image demo",
  "author": "Sammy the Shark <sammy@example.com>",
  "license": "MIT",
  "main": "app.js",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}

이 파일에는 공유되는 프로젝트 이름, 작성자 및 라이센스가 포함됩니다. 라이센스 필드에 npm MIT 라이센스를 부여하여 애플리케이션 코드의 무료 사용 및 배포를 허용합니다.

또한 파일은 다음을 지정합니다.

  • \main\: 애플리케이션 app.js의 진입점입니다. 다음에 이 파일을 생성합니다.
  • \dependencies\: 프로젝트 종속성 — 이 경우 Express 4.16.4 이상입니다.

이 파일은 리포지토리를 나열하지 않지만 package.json 파일에 리포지토리를 추가하는 지침에 따라 리포지토리를 추가할 수 있습니다. 이것은 응용 프로그램의 버전을 관리하는 경우 좋은 추가 기능입니다.

CTRL + X를 입력하여 파일을 저장하고 닫습니다. Y를 누른 다음 ENTER를 눌러 변경 사항을 확인합니다.

프로젝트의 종속성을 설치하려면 다음 명령을 실행하십시오.

  1. npm install

이렇게 하면 프로젝트 디렉터리의 package.json 파일에 나열된 패키지가 설치됩니다.

이제 애플리케이션 파일 빌드로 이동할 수 있습니다.

2단계 - 애플리케이션 파일 생성

사용자에게 상어에 대한 정보를 제공하는 웹사이트를 만들 것입니다. 이 애플리케이션에는 기본 진입점인 app.js와 프로젝트의 정적 자산을 포함할 views 디렉토리가 있습니다. 랜딩 페이지인 index.html은 사용자에게 몇 가지 예비 정보와 더 자세한 상어 정보가 있는 페이지 sharks.html에 대한 링크를 제공합니다. views 디렉토리에서 랜딩 페이지와 sharks.html을 모두 생성합니다.

먼저 기본 프로젝트 디렉토리에서 app.js를 열어 프로젝트 경로를 정의합니다.

  1. nano app.js

이 파일의 첫 번째 부분에서 Express 애플리케이션 및 라우터 개체를 만들고 기본 디렉터리 및 포트를 상수로 정의합니다.

const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

require 함수는 approuter 객체를 생성하는 데 사용되는 express 모듈을 로드합니다. router 개체는 응용 프로그램의 라우팅 기능을 수행하며 HTTP 메서드 경로를 정의할 때 이 개체에 추가하여 응용 프로그램이 요청을 처리하는 방법을 정의합니다.

파일의 이 섹션은 pathport와 같은 몇 가지 상수도 설정합니다.

  • path: 현재 프로젝트 디렉토리 내의 views 하위 디렉토리가 될 기본 디렉토리를 정의합니다.
  • port: 포트 8080에서 수신 대기하고 바인딩하도록 앱에 지시합니다.

다음으로 router 개체를 사용하여 애플리케이션의 경로를 설정합니다.

...

router.use(function (req,res,next) {
  console.log('/' + req.method);
  next();
});

router.get('/', function(req,res){
  res.sendFile(path + 'index.html');
});

router.get('/sharks', function(req,res){
  res.sendFile(path + 'sharks.html');
});

router.use 함수는 라우터의 요청을 기록하고 애플리케이션의 경로로 전달하는 미들웨어 함수를 로드합니다. 이는 기본 프로젝트 URL에 대한 GET 요청이 index.html 페이지를 반환하고 GET 페이지를 반환하도록 지정하는 후속 함수에서 정의됩니다. > /sharks 경로에 대한 요청은 sharks.html을 반환해야 합니다.

마지막으로 router 미들웨어와 애플리케이션의 정적 자산을 마운트하고 포트 8080에서 수신 대기하도록 앱에 지시합니다.

...

app.use(express.static(path));
app.use('/', router);

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

완성된 app.js 파일에는 다음 코드 줄이 모두 포함되어 있습니다.

const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

router.use(function (req,res,next) {
  console.log('/' + req.method);
  next();
});

router.get('/', function(req,res){
  res.sendFile(path + 'index.html');
});

router.get('/sharks', function(req,res){
  res.sendFile(path + 'sharks.html');
});

app.use(express.static(path));
app.use('/', router);

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

완료되면 파일을 저장하고 닫습니다.

다음으로 일부 정적 콘텐츠를 애플리케이션에 추가합니다. views 디렉터리를 생성하여 시작합니다.

  1. mkdir views

방문 페이지 파일인 index.html을 엽니다.

  1. nano views/index.html

다음 코드를 파일에 추가하면 Boostrap을 가져오고 더 자세한 sharks.html 정보 페이지에 대한 링크가 있는 jumbotron 구성 요소가 생성됩니다.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>About Sharks</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="css/styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>

<body>
    <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
        <div class="container">
            <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
            </button> <a class="navbar-brand" href="#">Everything Sharks</a>
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav mr-auto">
                    <li class="active nav-item"><a href="/" class="nav-link">Home</a>
                    </li>
                    <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="jumbotron">
        <div class="container">
            <h1>Want to Learn About Sharks?</h1>
            <p>Are you ready to learn about sharks?</p>
            <br>
            <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
            </p>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <h3>Not all sharks are alike</h3>
                <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.
                </p>
            </div>
            <div class="col-lg-6">
                <h3>Sharks are ancient</h3>
                <p>There is evidence to suggest that sharks lived up to 400 million years ago.
                </p>
            </div>
        </div>
    </div>
</body>

</html>

다음은 index.html 파일의 다양한 요소에 대한 빠른 분석입니다. 최상위 탐색 모음을 통해 사용자는 홈 페이지와 Sharks 페이지 사이를 전환할 수 있습니다. navbar-nav 하위 구성 요소에서 Bootstrap의 active 클래스를 사용하여 사용자에게 현재 페이지를 나타냅니다. 또한 app.js에서 정의한 경로와 일치하는 정적 페이지에 대한 경로를 지정했습니다.

...
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
   <ul class="nav navbar-nav mr-auto">
      <li class="active nav-item"><a href="/" class="nav-link">Home</a>
      </li>
      <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
      </li>
   </ul>
</div>
...

또한 점보트론 버튼에 상어 정보 페이지 링크를 만들었습니다.

...
<div class="jumbotron">
   <div class="container">
      <h1>Want to Learn About Sharks?</h1>
      <p>Are you ready to learn about sharks?</p>
      <br>
      <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
      </p>
   </div>
</div>
...

헤더에 사용자 지정 스타일 시트에 대한 링크도 있습니다.

...
<link href="css/styles.css" rel="stylesheet">
...

이 단계의 끝에서 이 스타일 시트를 생성합니다.

완료되면 파일을 저장하고 닫습니다.

애플리케이션 랜딩 페이지가 준비되면 상어 정보 페이지인 sharks.html을 생성하여 관심 있는 사용자에게 상어에 대한 자세한 정보를 제공할 수 있습니다.

파일 열기:

  1. nano views/sharks.html

Bootstrap, 사용자 지정 스타일 시트 및 특정 상어에 대한 자세한 정보를 가져오는 다음 코드를 추가합니다.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>About Sharks</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <link href="css/styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
    <div class="container">
        <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
        </button> <a class="navbar-brand" href="/">Everything Sharks</a>
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav mr-auto">
                <li class="nav-item"><a href="/" class="nav-link">Home</a>
                </li>
                <li class="active nav-item"><a href="/sharks" class="nav-link">Sharks</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<div class="jumbotron text-center">
    <h1>Shark Info</h1>
</div>
<div class="container">
    <div class="row">
        <div class="col-lg-6">
            <p>
                <div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
                </div>
                <img src="https://assets.linux-console.net/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
            </p>
        </div>
        <div class="col-lg-6">
            <p>
                <div class="caption">Other sharks are known to be friendly and welcoming!</div>
                <img src="https://assets.linux-console.net/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
            </p>
        </div>
    </div>
</div>

</html>

이 파일에서 다시 한 번 active Bootstrap 클래스를 사용하여 현재 페이지를 나타냅니다.

완료되면 파일을 저장하고 닫습니다.

마지막으로 css 폴더를 생성하여 index.htmlsharks.html에 연결한 사용자 정의 CSS 스타일 시트를 생성합니다. 디렉토리:

  1. mkdir views/css

스타일 시트를 엽니다.

  1. nano views/css/styles.css

페이지에 원하는 색상과 글꼴을 설정하는 다음 코드를 추가합니다.

.navbar {
	margin-bottom: 0;
}

body {
	background: #020A1B;
	color: #ffffff;
	font-family: 'Merriweather', sans-serif;
}

h1,
h2 {
	font-weight: bold;
}

p {
	font-size: 16px;
	color: #ffffff;
}

.jumbotron {
	background: #0048CD;
	color: white;
	text-align: center;
}

.jumbotron p {
	color: white;
	font-size: 26px;
}

.btn-primary {
	color: #fff;
	text-color: #000000;
	border-color: white;
	margin-bottom: 5px;
}

img,
video,
audio {
	margin-top: 20px;
	max-width: 80%;
}

div.caption: {
	float: left;
	clear: both;
}

글꼴 및 색상 설정 외에도 이 파일은 최대 너비를 80%로 지정하여 이미지 크기를 제한합니다. 이렇게 하면 사진이 페이지에서 원하는 것보다 더 많은 공간을 차지하는 것을 방지할 수 있습니다.

완료되면 파일을 저장하고 닫습니다.

애플리케이션 파일이 준비되고 프로젝트 종속 항목이 설치되면 애플리케이션을 시작할 준비가 된 것입니다.

필수 구성 요소의 초기 서버 설정 자습서를 따랐다면 SSH 트래픽만 허용하는 활성 방화벽을 갖게 됩니다. 포트 8080에 대한 트래픽을 허용하려면 다음을 실행하십시오.

  1. sudo ufw allow 8080

애플리케이션을 시작하려면 프로젝트의 루트 디렉토리에 있는지 확인하십시오.

  1. cd ~/node_project

node app.js로 애플리케이션을 시작합니다.

  1. node app.js

브라우저에서 http://your_server_ip:8080으로 이동합니다. 다음은 방문 페이지입니다.

Get Shark Info 버튼을 클릭하면 다음 정보 페이지로 이동합니다.

이제 애플리케이션이 실행되고 있습니다. 준비가 되면 CTRL + C를 입력하여 서버를 종료합니다. 이제 원하는 대로 이 애플리케이션을 재생성하고 확장할 수 있는 Dockerfile 생성으로 이동할 수 있습니다.

3단계 - Dockerfile 작성

Dockerfile은 애플리케이션이 실행될 때 애플리케이션 컨테이너에 포함될 항목을 지정합니다. Dockerfile을 사용하면 컨테이너 환경을 정의하고 종속성 또는 런타임 버전과의 불일치를 방지할 수 있습니다.

최적화된 컨테이너 구축에 대한 이러한 지침을 따르면 이미지 레이어 수를 최소화하고 이미지의 기능을 애플리케이션 파일 및 정적 콘텐츠 재생성이라는 단일 목적으로 제한하여 이미지를 최대한 효율적으로 만들 수 있습니다.

프로젝트의 루트 디렉터리에서 Dockerfile을 만듭니다.

  1. nano Dockerfile

Docker 이미지는 서로 위에 빌드되는 일련의 계층화된 이미지를 사용하여 생성됩니다. 첫 번째 단계는 애플리케이션 빌드의 시작점을 형성할 애플리케이션의 기본 이미지를 추가하는 것입니다.

Docker 허브 노드 이미지 페이지를 사용할 수 있습니다.

다음 FROM 명령어를 추가하여 애플리케이션의 기본 이미지를 설정합니다.

FROM node:10-alpine

이 이미지에는 Node.js 및 npm이 포함되어 있습니다. 각 Dockerfile은 FROM 명령어로 시작해야 합니다.

기본적으로 Docker 노드 이미지에는 애플리케이션 컨테이너를 루트로 실행하지 않도록 하는 데 사용할 수 있는 루트가 아닌 노드 사용자가 포함됩니다. 컨테이너를 루트로 실행하지 않고 모범 사례 가이드로 권장되는 보안 사례입니다.

컨테이너에서 애플리케이션 코드에 대한 권한을 미세 조정하려면 app 디렉터리와 함께 /home/nodenode_modules 하위 디렉터리를 만듭니다. 이러한 디렉터리를 만들면 올바른 권한을 갖게 됩니다. 이는 npm install을 사용하여 컨테이너에 로컬 노드 모듈을 만들 때 중요합니다. 이러한 디렉토리를 생성하는 것 외에도 소유권을 노드 사용자로 설정하십시오.

...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

통합 RUN 명령의 유틸리티에 대한 자세한 내용은 컨테이너 계층 관리 방법에 대한 이 토론을 참조하십시오.

다음으로 애플리케이션의 작업 디렉터리를 /home/node/app로 설정합니다.

...
WORKDIR /home/node/app

WORKDIR이 설정되지 않은 경우 Docker는 기본적으로 하나를 생성하므로 명시적으로 설정하는 것이 좋습니다.

다음으로 package.jsonpackage-lock.json(npm 5+용) 파일을 복사합니다.

...
COPY package*.json ./

npm install을 실행하거나 애플리케이션 코드를 복사하기 전에 이 COPY 명령을 추가하면 Docker의 캐싱 메커니즘을 활용할 수 있습니다. 빌드의 각 단계에서 Docker는 특정 명령에 대해 캐시된 계층이 있는지 확인합니다. package.json을 변경하면 이 레이어가 다시 빌드되지만 그렇지 않으면 이 지침을 통해 Docker가 기존 이미지 레이어를 사용하고 노드 모듈 재설치를 건너뛸 수 있습니다.

node_modules 디렉터리의 콘텐츠를 포함하여 루트가 아닌 노드 사용자가 모든 애플리케이션 파일을 소유하도록 하려면 npm install을 실행하기 전에 사용자를 노드로 전환합니다.

...
USER node

프로젝트 종속성을 복사하고 사용자를 전환한 후 npm install을 실행합니다.

...
RUN npm install

다음으로 컨테이너의 애플리케이션 디렉터리에 대한 적절한 권한이 있는 애플리케이션 코드를 복사합니다.

...
COPY --chown=node:node . .

이렇게 하면 루트가 아닌 노드 사용자가 애플리케이션 파일을 소유하게 됩니다.

마지막으로 컨테이너에서 포트 8080을 노출하고 애플리케이션을 시작합니다.

...
EXPOSE 8080

CMD [ "node", "app.js" ]

EXPOSE는 포트를 게시하지 않지만 대신 런타임에 게시될 컨테이너의 포트를 문서화하는 방법으로 작동합니다. CMD는 응용 프로그램을 시작하는 명령을 실행합니다. 이 경우에는 node app.js입니다.

참고: 각 Dockerfile에는 하나의 CMD 명령어만 있어야 합니다. 둘 이상 포함하면 마지막 항목만 적용됩니다.

Dockerfile로 할 수 있는 일이 많습니다. 전체 지침 목록은 Docker의 Dockerfile 참조 문서를 참조하세요.

다음은 완전한 Dockerfile입니다.


FROM node:10-alpine

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

WORKDIR /home/node/app

COPY package*.json ./

USER node

RUN npm install

COPY --chown=node:node . .

EXPOSE 8080

CMD [ "node", "app.js" ]

편집을 마치면 파일을 저장하고 닫습니다.

애플리케이션 이미지를 빌드하기 전에 .gitignore 파일을 추가하세요. .dockerignore는 프로젝트 디렉터리의 어떤 파일과 디렉터리를 컨테이너로 복사하면 안 되는지 지정합니다.

.dockerignore 파일을 엽니다.

  1. nano .dockerignore

파일 내에서 로컬 노드 모듈, npm 로그, Dockerfile 및 .dockerignore 파일을 추가합니다.

node_modules
npm-debug.log
Dockerfile
.dockerignore

Git으로 작업하는 경우 .git 디렉토리와 .gitignore 파일도 추가해야 합니다.

완료되면 파일을 저장하고 닫습니다.

이제 docker build 명령을 사용하여 애플리케이션 이미지를 빌드할 준비가 되었습니다. docker build와 함께 -t 플래그를 사용하면 기억하기 쉬운 이름으로 이미지에 태그를 지정할 수 있습니다. 이미지를 Docker Hub로 푸시할 것이므로 태그에 Docker Hub 사용자 이름을 포함합니다. 이미지에 nodejs-image-demo 태그를 지정할 수 있지만 원하는 이름으로 교체해도 됩니다. your_dockerhub_username도 자신의 Docker Hub 사용자 이름으로 바꿔야 합니다.

  1. docker build -t your_dockerhub_username/nodejs-image-demo .

.는 빌드 컨텍스트가 현재 디렉토리임을 지정합니다.

이미지를 구축하는 데 약간의 시간이 걸립니다. 완료되면 이미지를 확인합니다.

  1. docker images
Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 73MB node 10-alpine f09e7c96b6de 13 monthss ago 82.7MB

이제 docker run을 사용하여 이 이미지로 컨테이너를 생성할 수 있습니다. 이 명령에는 세 가지 플래그가 포함됩니다.

  • -p: 컨테이너의 포트를 게시하고 호스트의 포트에 매핑합니다. 호스트에서 포트 80을 사용할 수 있지만 해당 포트에서 실행 중인 다른 프로세스가 있는 경우 필요에 따라 자유롭게 수정할 수 있습니다. 작동 방식에 대한 자세한 내용은 포트 바인딩에 대한 Docker 문서에서 이 토론을 참조하세요.
  • -d: 백그라운드에서 컨테이너를 실행합니다.
  • --name: 이를 통해 컨테이너에 기억하기 쉬운 이름을 지정할 수 있습니다.

다음 명령어를 실행하여 컨테이너를 빌드합니다.

  1. docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

컨테이너가 실행되면 docker ps를 사용하여 실행 중인 컨테이너 목록을 검사할 수 있습니다.

  1. docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "docker-entrypoint.s…" 13 seconds ago Up 12 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp nodejs-image-demo

컨테이너가 실행 중이면 이제 브라우저에서 http://your_server_ip로 이동하여 애플리케이션을 방문할 수 있습니다.

이제 애플리케이션용 이미지를 만들었으므로 나중에 사용할 수 있도록 Docker Hub에 푸시할 수 있습니다.

4단계 - 리포지토리를 사용하여 이미지 작업

Docker Hub와 같은 레지스트리에 애플리케이션 이미지를 푸시하면 나중에 컨테이너를 빌드하고 확장할 때 사용할 수 있습니다. 이것이 어떻게 작동하는지 보여주기 위해 애플리케이션 이미지를 리포지토리에 푸시한 다음 이미지를 사용하여 컨테이너를 다시 만듭니다.

이미지를 푸시하는 첫 번째 단계는 전제 조건에서 만든 Docker Hub 계정에 로그인하는 것입니다.

  1. docker login -u your_dockerhub_username

메시지가 표시되면 Docker Hub 계정 암호를 입력합니다. 이 방법으로 로그인하면 Docker Hub 자격 증명을 사용하여 사용자의 홈 디렉터리에 ~/.docker/config.json 파일이 생성됩니다.

이제 이전에 만든 your_dockerhub_username/nodejs-image-demo 태그를 사용하여 애플리케이션 이미지를 Docker Hub에 푸시할 수 있습니다.

  1. docker push your_dockerhub_username/nodejs-image-demo

현재 애플리케이션 컨테이너와 이미지를 삭제하고 리포지토리의 이미지로 다시 빌드하여 이미지 레지스트리의 유틸리티를 테스트해 보겠습니다.

먼저 실행 중인 컨테이너를 나열합니다.

  1. docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:80->8080/tcp, :::80->8080/tcp nodejs-image-demo

출력에 나열된 CONTAINER ID를 사용하여 실행 중인 애플리케이션 컨테이너를 중지합니다. 아래 강조표시된 ID를 자신의 컨테이너 ID로 바꾸십시오.

  1. docker stop e50ad27074a7

-a 플래그를 사용하여 모든 이미지를 나열하십시오.

  1. docker images -a

다음은 nodeyour_dockerhub_username/nodejs-image-demo와 함께 출력됩니다. > 빌드의 이미지 및 기타 이미지:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 73MB <none> <none> 2e3267d9ac02 4 minutes ago 72.9MB <none> <none> 8352b41730b9 4 minutes ago 73MB <none> <none> 5d58b92823cb 4 minutes ago 73MB <none> <none> 3f1e35d7062a 4 minutes ago 73MB <none> <none> 02176311e4d0 4 minutes ago 73MB <none> <none> 8e84b33edcda 4 minutes ago 70.7MB <none> <none> 6a5ed70f86f2 4 minutes ago 70.7MB <none> <none> 776b2637d3c1 4 minutes ago 70.7MB node 10-alpine f09e7c96b6de 13 months ago 82.7MB

다음 명령을 사용하여 중지된 컨테이너와 사용되지 않거나 매달린 이미지를 포함한 모든 이미지를 제거합니다.

docker system prune -a

중지된 컨테이너와 이미지를 제거할 것인지 확인하는 메시지가 출력에 표시되면 y를 입력합니다. 이렇게 하면 빌드 캐시도 제거됩니다.

이제 애플리케이션 이미지를 실행하는 컨테이너와 이미지 자체를 모두 제거했습니다. Docker 컨테이너, 이미지 및 볼륨 제거에 대한 자세한 내용은 Docker 이미지, 컨테이너 및 볼륨 제거 방법을 참조하십시오.

모든 이미지와 컨테이너가 삭제되었으므로 이제 Docker Hub에서 애플리케이션 이미지를 가져올 수 있습니다.

  1. docker pull your_dockerhub_username/nodejs-image-demo

이미지를 다시 한 번 나열합니다.

  1. docker images

애플리케이션 이미지가 표시됩니다.

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 73MB

이제 3단계의 명령을 사용하여 컨테이너를 다시 빌드할 수 있습니다.

  1. docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

실행 중인 컨테이너를 나열합니다.

  1. docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp nodejs-image-demo

실행 중인 애플리케이션을 보려면 http://your_server_ip를 다시 한 번 방문하십시오.

결론

이 자습서에서는 Express 및 Bootstrap을 사용하여 정적 웹 애플리케이션과 이 애플리케이션에 대한 Docker 이미지를 만들었습니다. 이 이미지를 사용하여 컨테이너를 만들고 이미지를 Docker Hub에 푸시했습니다. 거기에서 이미지와 컨테이너를 제거하고 Docker Hub 리포지토리를 사용하여 다시 만들 수 있습니다.

Docker Compose 및 Docker Machine과 같은 도구를 사용하여 다중 컨테이너 설정을 만드는 방법에 대해 자세히 알아보려면 다음 가이드를 참조하세요.

  • Ubuntu 18.04에 Docker Compose를 설치하는 방법
  • Ubuntu 18.04에서 Docker 머신으로 원격 Docker 호스트를 프로비저닝하고 관리하는 방법

컨테이너 데이터 작업에 대한 일반적인 팁은 다음을 참조하세요.

  • Docker 컨테이너 간에 데이터를 공유하는 방법.
  • Docker 컨테이너와 호스트 간에 데이터를 공유하는 방법.

다른 Docker 관련 항목에 관심이 있는 경우 전체 Docker 자습서 라이브러리를 참조하십시오.