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
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
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
这里,是容器名称(,,或)。
完成后,在终端中按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://docs.docker.com/engine/install/ubuntu/
©xgqfrms 2012-2020
www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/13582561.html
未经授权禁止转载,违者必究!