xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

Docker in Action

Docker in Action

如何安装Docker

Docker Docs上提供了在Linux上安装最新版本Docker的说明。
您也可以使用官方存储库,尽管这些存储库可能具有较旧的版本。

Ubuntu

$ sudo apt-get update

$ sudo apt-get remove docker docker-engine docker.io

$ sudo apt install docker.io

$ sudo systemctl start docker

$ sudo systemctl enable docker

如何启动数据库容器

在终端中输入以下命令以启动MongoDB容器:

$ docker run -d --rm --name mongodb -p 27017:27017 --mount "src=mongodata,target=/data/db" mongo:4

现在,任何MongoDB客户端都可以连接(无需用户ID或密码)。或者,从另一个终端直接连接到容器外壳: localhost:27017

$ docker exec -it mongodb sh

启动MongoDB命令行:

$ mongo

https://docs.docker.com/engine/reference/commandline/run/

然后运行任何数据库命令。例如:

use test;
db.apps.insertOne({ name: 'Docker' });
db.apps.find();
键入以退出MongoDB客户端,然后再次退出外壳。 exit exit

列出正在运行的容器,其中包括:

docker container ls
要停止并除去MongoDB容器,请输入:

docker container stop mongodb
同样,您可以使用以下命令启动MySQL 8容器:

docker run -d --rm --name mysql -p 3306:3306 --mount "src=mysqldata,target=/var/lib/mysql" -e MYSQL_ROOT_PASSWORD=mysecret mysql:8
一旦启动(可能需要几分钟),请使用任何MySQL客户端使用用户ID 和密码进行连接。例如: localhost:3306 root mysecret

docker exec -it mysql sh
mysql -u root -pmysecret
MySQL容器可以通过以下方式停止:

docker container stop mysql

如何启动Node.js容器

在Docker容器中运行Node.js应用程序提供了比主机PC更一致的环境。
假设我们要对一个简单的Express.js应用程序进行Docker化,该应用程序在浏览至时显示一条消息。起始文件: http://localhost:3000/

package.json


{
  "name": "docker-test",
  "version": "1.0.0",
  "description": "Docker test",
  "main": "index.js",
  "scripts": {
    "start": "node ./index.js",
    "debug": "nodemon --inspect ./index.js"
  },
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.2"
  }
}

nodemon.json

{
  "script": "./index.js",
  "ext": "js",
  "ignore": [
    ".git/",
    "node_modules/"
  ],
  "legacyWatch": true,
  "delay": 200,
  "verbose": true
}

(请注意,它使用了较旧的文件监视过程,在大多数设备上更可靠。) legacyWatch

index.js

'use strict';
const
  port = 3000,
  express = require('express'),
  app = express();
app.get('/', (req, res) => {
  res.send('Hello from Docker!');
});
app.listen(port, () =>
  console.log(`server running on port ${port}`)
);

可以从Docker Hub中选择合适的Node.js映像。一般来说:

大多数图片很大,需要下载100MB以上
alpine 映像具有5MB的最小下载量,但可能无法提供您的应用程序所需的某些操作系统相关性
slim 映像是主要Linux映像的简化版本,这可能是一个合理的实用选择
在这种情况下,我们可以使用-带有最新LTS(偶数编号)版本的Node.js的最小映像。 lts-alpine

A 定义了为应用程序创建映像所需的构建步骤。可以使用各种命令,包括: Dockerfile

Docker文件

FROM node:lts-alpine
ENV HOME=/home/node/app
ENV NODE_ENV=production
RUN mkdir -p $HOME && chown -R node:node $HOME
WORKDIR $HOME
USER node
COPY --chown=node:node package*.json $HOME/
RUN npm i && npm cache clean --force
COPY --chown=node:node . .
EXPOSE 3000
CMD npm start
本示例假定一个生产环境。但是,在开发过程中,我们将覆盖Docker命令行和Docker Compose中的一些设置。

还创建一个文件,以确保非必需文件不会复制到映像中: .dockerignore

.dockerignore

.git
.gitignore
.config
.npm
.vscode
node_modules
要在项目根目录内构建名为的新映像,请输入: nodetest

docker image build -t nodetest .
命令末尾的时间段至关重要!使用,如果你没有名字构建文件“ ”。 -f Dockerfile

Docker在每个构建步骤中创建一个单独的(隐藏)映像(输入以查看所有映像)。这样可以更有效地进行更改。例如,修改端口是瞬时的,因为之前的构建步骤都不需要更改。但是,使用其他映像将需要完全重建。 docker image ls -a EXPOSE FROM

因此,应将Dockerfile命令的更改顺序从最小可能更改为最可能。在这种情况下:

设置了起始图像和环境变量。
创建主目录,并授予用户所有权。 node
定义了工作目录和用户。
package.json 从主机复制并安装了npm依赖项。
其余应用程序文件从主机复制。
端口3000在主机上暴露。
npm start 被执行。
现在可以从该图像启动名为的交互式容器: nodeapp

docker run -it --rm --name nodeapp -p 3000:3000 nodetest
在浏览器中打开http:// localhost:3000 /以查看“来自Docker的Hello!”。

容器以生产模式运行。您对容器(或另一个应用程序文件)所做的任何更改都不会生效,直到您停止容器,重建映像并启动另一个容器。 index.js

为了使开发更加实用,请使用Ctrl/ Cmd+ 停止容器,C然后使用以下命令开始一个新容器:

docker run -it --rm --name nodeapp -p 3000:3000 -e NODE_ENV=development -v $PWD:/home/node/app --entrypoint '/bin/sh' nodetest -c 'npm i && npm run debug'

$ PWD和Windows
$PWD 是对Linux和macOS上当前文件夹的引用。Windows Powershell或Windows中不提供此功能。使用Linux正斜杠表示法将其替换为完整的项目路径,例如。 cmd /c/projects/nodetest

该命令执行以下操作:

它将环境变量更改为 NODE_ENV development
它将主机的项目目录安装到容器中的应用程序路径
它将启动命令更改为启动外壳 /bin/sh
它传递给该Shell以安装依赖项并运行脚本(启动nodemon) -c 'npm i && npm run debug' debug
该代码可以修改,Web服务器将自动重新启动。除非您安装其他模块(使用来访问Shell ),否则无需重建映像或重新启动容器。 index.js docker exec -it nodeapp shDocker文件

FROM node:lts-alpine
ENV HOME=/home/node/app
ENV NODE_ENV=production
RUN mkdir -p $HOME && chown -R node:node $HOME
WORKDIR $HOME
USER node
COPY --chown=node:node package*.json $HOME/
RUN npm i && npm cache clean --force
COPY --chown=node:node . .
EXPOSE 3000
CMD npm start

本示例假定一个生产环境。但是,在开发过程中,我们将覆盖Docker命令行和Docker Compose中的一些设置。

还创建一个文件,以确保非必需文件不会复制到映像中: .dockerignore

.dockerignore

# .dockerignore
.git
.gitignore
.config
.npm
.vscode
node_modules

要在项目根目录内构建名为的新映像,请输入: nodetest

$ docker image build -t nodetest .

命令末尾的时间段至关重要!使用,如果你没有名字构建文件“ ”。 -f Dockerfile

Docker在每个构建步骤中创建一个单独的(隐藏)映像(输入以查看所有映像)。这样可以更有效地进行更改。例如,修改端口是瞬时的,因为之前的构建步骤都不需要更改。但是,使用其他映像将需要完全重建。 docker image ls -a EXPOSE FROM

因此,应将Dockerfile命令的更改顺序从最小可能更改为最可能。在这种情况下:

设置了起始图像和环境变量。
创建主目录,并授予用户所有权。 node
定义了工作目录和用户。
package.json 从主机复制并安装了npm依赖项。
其余应用程序文件从主机复制。
端口3000在主机上暴露。

npm start 被执行。
现在可以从该图像启动名为的交互式容器: nodeapp


$ docker run -it --rm --name nodeapp -p 3000:3000 nodetest

在浏览器中打开 http:// localhost:3000 以查看“来自Docker的Hello!”。

容器以生产模式运行。您对容器(或另一个应用程序文件)所做的任何更改都不会生效,直到您停止容器,重建映像并启动另一个容器。 index.js

为了使开发更加实用,请使用Ctrl/ Cmd+ 停止容器,C然后使用以下命令开始一个新容器:


$ docker run -it --rm --name nodeapp -p 3000:3000 -e NODE_ENV=development -v $PWD:/home/node/app --entrypoint '/bin/sh' nodetest -c 'npm i && npm run debug'

$ PWD和Windows
$PWD 是对Linux和macOS上当前文件夹的引用。
Windows Powershell或Windows中不提供此功能。
使用Linux正斜杠表示法将其替换为完整的项目路径,例如。 cmd /c/projects/nodetest

该命令执行以下操作:

它将环境变量更改为 NODE_ENV development
它将主机的项目目录安装到容器中的应用程序路径
它将启动命令更改为启动外壳 /bin/sh
它传递给该Shell以安装依赖项并运行脚本(启动nodemon) -c 'npm i && npm run debug' debug
该代码可以修改,Web服务器将自动重新启动。除非您安装其他模块(使用来访问Shell ),否则无需重建映像或重新启动容器。 index.js docker exec -it nodeapp sh

在开发过程中使用Docker Compose

单独启动Docker容器很麻烦,尤其是当命令是如此复杂时!幸运的是,Docker Compose可以在一个命令中快速有效地管理任意数量的容器。

假设我们要在Docker网络中以开发模式启动三个容器: localnet

名为的MySQL数据库容器将数据保存到名为的Docker卷中并公开端口3306。 mysql mysqldata
名为PHP Adminer的数据库客户端将Web应用程序公开在端口8080上。 adminer
上面定义的Node.js Express应用程序运行nodemon并在端口3000上公开该Web应用程序。

在项目文件夹中创建一个包含以下内容的文件(选项卡很重要): docker-compose.yml

version: '3'
services:
  mysql:
    environment:
      - MYSQL_ROOT_PASSWORD=mysecret
    image: mysql:8
    container_name: mysql
    volumes:
      - mysqldata:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - localnet
  adminer:
    image: adminer
    container_name: adminer
    depends_on:
      - mysql
    ports:
      - "8080:8080"
    networks:
      - localnet
  nodejs:
    environment:
      - NODE_ENV=development
    build:
      context: ./
      dockerfile: Dockerfile
    container_name: nodejs
    depends_on:
      - mysql
    command: /bin/sh -c 'npm i && npm run debug'
    volumes:
      - ./:/home/node/app
    ports:
      - "3000:3000"
    networks:
      - localnet
volumes:
  mysqldata:
networks:
  localnet:

Docker Compose配置可以使用许多命令,但是此示例为上述Docker开发CLI命令设置了类似的选项。笔记:

该设置使用Docker卷,同时挂载主机的文件系统(Docker Compose允许在任何OS上引用相对路径)。 mysql volumes node volumes
depends_on 定义启动依赖性。在这种情况下,并启动后推出。 adminer nodejs mysql
在继续之前,请确保已停止所有正在运行的容器。还建议通过运行以下命令删除现有的映像,容器和网络,以确保系统是干净的:

docker system prune -af
现在可以通过输入以下命令启动所有三个容器:

docker-compose up
而已。第一次运行将花费一些时间下载和构建图像,但是所有消息都将记录到终端。

您现在可以在http:// localhost:3000 /上访问Node.js Web服务。修改后,Nodemon将重新启动应用程序。 index.js

您可以使用任何MySQL客户端连接到的数据库。或者,在浏览器中的http:// localhost:8080 /中打开Adminer,然后使用凭据访问数据库: localhost:3306

系统:MySQL
服务器:mysql
用户名:root
密码:mysecret
可以使用以下命令从另一个终端访问任何容器外壳:

docker-compose exec sh
这里,是容器名称(,,或)。 nodejs mysql adminer

完成后,在终端中按Ctrl/ Cmd+ ,所有三个容器将正常关闭并自行移除。随后的运行几乎是瞬时的。C docker-compose docker-compose up

在生产中使用Docker Compose

可以在生产中使用类似的Docker Compose配置。主要区别:

应用程序应在生产模式下运行(我们的默认设置)。 Dockerfile
不需要诸如Adminer之类的开发应用程序。(诚​​然,它们可以在实时服务器上使用,但是它们会增加安全性和人为错误风险!)
为了提高安全性,仅需在Docker网络中而不是主机上公开MySQL之类的端口。使用更强的密码或文件也可能会有所帮助! 3306 .env
可以添加容器和类似的生产选项。 restart
创建一个用于生产的新Docker Compose文件,即: docker-compose-production.yml

version: '3'
services:
  mysql:
    environment:
      - MYSQL_ROOT_PASSWORD=mysecret
    image: mysql:8
    container_name: mysql
    volumes:
      - mysqldata:/var/lib/mysql
    ports:
      - "3306"
    networks:
      - localnet
    restart: on-failure
  nodejs:
    build:
      context: ./
      dockerfile: Dockerfile
    container_name: nodejs
    depends_on:
      - mysql
    ports:
      - "3000:3000"
    restart: on-failure
volumes:
  mysqldata:
networks:
  localnet:

Docker容器现在可以作为实时服务器上的后台服务启动:

docker-compose -f .\docker-compose-production.yml up -d
理想情况下,您还需要前端Web服务器(例如NGINX)充当Node.js应用程序的支持SSL的反向代理,但可以将其安装在主机上或作为另一个容器安装。

要停止容器,请输入:

docker-compose stop

打扫干净

Docker会占用大量磁盘空间:输入以查看使用情况统计信息。 docker system df

要清理停止的容器并悬挂当前未与容器关联的图像,卷和网络,请输入:

docker system prune
添加以删除图像,或也包括容器和网络。 -a -af

可以使用删除所有卷,但切记备份所需的任何数据! docker volume prune -f

下一步
Docker是一个复杂的话题,但是本指南涵盖了Node.js开发的基本知识。但是,尽管上面的示例启动了Node.js和数据库容器,但该应用程序在任何时候都不会访问或使用数据库!

这是第5章的主题。您将发现:

为什么Web应用程序需要数据库
SQL和NoSQL数据库提供的区别和好处
如何使用MongoDB,MySQL和Sequelize ORM编写Node.js应用程序。

https://www.sitepoint.com/premium/books/your-first-week-with-node-js-2nd-edition/read/12/k8o6l5m3

Docker Desktop

https://docs.docker.com/docker-for-mac/install/

https://hub.docker.com/editions/community/docker-ce-desktop-mac/

refs

https://hub.docker.com/_/node

https://docs.docker.com/engine/install/ubuntu/



©xgqfrms 2012-2020

www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


posted @ 2020-08-29 16:19  xgqfrms  阅读(326)  评论(3编辑  收藏  举报