介绍
Node.js 是一个 JavaScript 运行时环境,近年来因其在构建服务器端应用程序方面的应用而变得流行起来。.
本教程演示如何通过 Docker、Docker Hub 和 Docker Compose 将 Node.js 应用程序部署到云服务器。.
先决条件
- 本教程假设您的本地系统已安装 Docker。如果您尚未安装,可以参考官方文档中的安装说明。.
- 您还需要一台运行 Linux 发行版的云服务器,最好是 Ubuntu 24.04。如果您使用的是其他发行版,则在服务器上安装 Docker 时可能需要遵循特定的说明。.
- 某些步骤还需要一个 Docker Hub 帐户(免费)来上传应用程序的 Docker 镜像。.
- 如果您之前没有任何 Docker 使用经验,也没关系,本教程非常基础,只解释我们正在做的事情背后的核心概念。.
- 你需要一个可以部署的Node.js应用程序。.
关于 Docker
如果您刚开始接触 Docker,这里有一些值得回顾的术语,以确保我们理解一致。.
- 镜像:在 Docker 中,镜像是指文件系统的«快照»或模板,其中包含运行应用程序所需的一切。.
- 容器:这些是应用程序的实际运行实例。它们是通过获取模板(镜像)并将其转换为可以启动且具有状态的实例而创建的。.
- 层是构成 Docker 镜像的基本元素。每一层都构建在其他层之上,从而实现了层缓存功能。这意味着,当镜像中的某一层发生更改时,无需重新构建或加载镜像中的所有层。.
- 镜像仓库是上传(推送)镜像的地方,您可以将镜像提供给所有人或拥有访问权限的用户。在本教程中,我们将使用 Docker Hub,但 GCP、AWS、Azure、GitHub 等也提供了其他选择。.
步骤 1 – 创建 Dockerfile
在 Node.js 项目的根目录下创建一个名为 Dockerfile 的文件,并添加以下内容:
FROM node:20.17
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
EXPOSE 8080
CMD [ "node", "src/index.js" ]Dockerfile 文件用于存放 Docker 构建镜像的指令。每条指令都代表创建一个镜像层,该层是对镜像文件系统的修改。.
在这种情况下,我们从一个模板(有时也称为基础镜像)开始构建镜像,在本例中,该模板是 node:20.17。这是 Docker 公司提供的官方镜像,您可以在这里找到更多相关信息。.
下一步将 NODE_ENV 环境变量设置为 production。这样做的主要目的是避免在运行后续的 npm install 命令时安装开发包,但通常也能为您可能依赖的模块带来更好的优化。.
使用 WORKDIR 命令,我们将当前目录移动到 /app,而 /app 目录又将成为执行以下指令的目录。.
`COPY*.json` 命令会将 package.json 和 package-lock.json 文件复制到 Docker 镜像文件系统的 `/app` 文件夹中。请注意,末尾的点号是必需的,用于指示当前目录。.
现在我们使用 RUN 指令,通过 npm ci 命令安装生产依赖项(ci 代表 clean install,专为自动化环境设计)。.
需要注意的是,到目前为止,我们只是将 package*.json 文件复制到构建目录中,而不是整个项目目录。这样一来,我们就可以利用 Docker 层缓存,从而在依赖包未更改的情况下无需重新构建即可使用这些层。.
下面这行代码(COPY . .)会复制图像中剩余的文件。.
我们还可以指定要从容器中暴露特定的网络端口,以便 Web 应用程序可以访问它。请注意,EXPOSE 指令实际上并不会暴露端口:正如文档所述,它«充当镜像构建者和容器运行者之间的一种文档,用于指定要发布的端口»。 .
最后一条指令指定了 Docker 在容器启动时应使用的执行应用程序的命令。在本例中,我们假设应用程序的入口点是 index.js 文件。.
通常来说,最好在 Dockerfile 旁边创建一个名为 .dockerignore 的文件。这样可以确保在运行 COPY 命令时,不会将计算机上的无用文件复制到镜像中:
.git
Dockerfile
node_modules在这种情况下,我们不希望像 git 或 node_modules 这样的目录的开发版本在我们构建的模板中可用。.
步骤 2 – 创建图像
现在我们有了 Dockerfile,就可以告诉 Docker 使用它来构建镜像了。.
执行此操作的基本命令如下所示,应在主项目文件夹中运行:
docker build -t myproject .
如果执行失败并出现错误“/bin/sh -c npm ci”,请将 Dockerfile 中的 npm ci 替换为 npm install,然后重试。.
`-t` 选项指定镜像名称,在本例中为 `myproject`。在行尾,您需要告诉 Docker 在当前目录中查找 Dockerfile 文件。.
注意:第一次运行构建时,需要一段时间,因为 Docker 需要下载基础镜像的所有层(在本例中为 Node.js 20.17)。.
由于我们计划将此镜像上传到在线 Docker Hub 注册表(以便从我们的服务器访问它),因此我们需要使用特定的命名约定来命名该镜像。.
所以上面的命令看起来会是这样:
docker build -t username/myproject:latest .
其中 username 是您的 Docker Hub 用户名,last 是镜像标签。一个镜像可以有多个标签,因此有时您会看到类似这样的工作流程:
docker build -t myproject .
docker tag myproject username/myproject:latest
docker tag myproject username/myproject:20240905这些命令会创建一个图像,然后给它添加 latest 和 20240904 这两个标签(本教程上次更新的日期)。.
Docker Hub 默认不会删除旧镜像,因此您可以保留所有已推送到镜像仓库的镜像历史记录。带有最新标签的镜像始终是最近构建的镜像,而较旧的镜像则会以日期作为标签。.
步骤 3 – 按下图像
现在我们已经有了镜像,接下来需要将其推送到镜像仓库。首先,运行以下命令以确保您的 Docker 实例已通过 Docker Hub 身份验证:
docker login
然后运行 docker push 命令,将带有所有标签的镜像上传。.
docker push username/myproject
如果你的应用程序很小,这个命令应该很快就能完成,因为它只需要上传与 Node.js 应用程序及其 JavaScript 依赖项相关的层。.
有了新版本的镜像后,需要再次运行推送命令,以确保它已上传到 Docker Hub。.
步骤 4 – 在 Ubuntu 24.04 上安装 Docker
现在我们可以开始在服务器上安装 Docker 和 Docker Compose 了。正如先决条件部分所述,这里假设您已经搭建好了一台 Ubuntu 24.04 服务器。.
首先,安装 Docker 需要一些系统依赖项,可以使用以下命令安装:
sudo apt-get update
sudo apt-get install ca-certificates curl现在添加官方 Docker GPG 密钥并配置自定义 apt 仓库:
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null最后,再次更新 apt 目录并安装 Docker 社区版:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin上述命令还会安装 Docker Compose,该工具可以大大简化容器及其生命周期的管理。.
最后一步有用的步骤是将当前 Ubuntu 用户添加到 docker 组,以便我们可以直接从该用户运行 Docker 命令。.
可以使用以下命令轻松完成此操作:
sudo gpasswd -a myuser docker
请运行以下命令,确保一切顺利:
docker --version
docker ps
docker compose version如果没有看到任何错误或警告,就可以继续了。.
步骤 5 – 使用 Docker Compose 运行容器
在服务器上创建一个名为 docker-compose.yml 的文件,并添加以下内容:
services:
myproject:
container_name: 'myproject'
image: 'username/myproject'
restart: unless-stopped这是一个非常基础的 Docker Compose 文件,它基于 Docker Hub 上的 myproject 镜像(用户名/镜像名)配置一个名为 myproject 的容器。如果不指定标签,则默认使用最后一个标签,但您也可以根据需要设置特定标签:
services:
myproject:
container_name: 'myproject'
image: 'username/myproject:20240904'
restart: unless-stopped最后,重启属性表明,除非手动停止,否则容器在发生故障时应自动重启。.
如果现在运行此 Compose 命令,Docker 镜像将被注销,您的应用程序应该就能运行了:
docker compose -f docker-compose.yml up
此命令会创建一个容器并运行它。容器的输出会被 Docker 捕获并显示在控制台中。按下 CTRL + C(或 CMD + C)并等待几秒钟,容器就会停止运行。.
如果一切顺利,现在就可以将容器作为“幽灵”运行,使其在后台持续运行直至被停止。这可以通过在命令中添加 -d 选项来实现:
docker compose -f docker-compose.yml up -d砰!打结了!(哦,我是认真的)
请务必快速浏览 Compose 文件参考文档,其中包含一些实用功能,例如在服务器和容器之间映射网络端口。以下是一个将外部端口 80 映射到内部端口 8080 的简单示例:
services:
myproject:
container_name: 'myproject'
image: 'username/myproject'
restart: unless-stopped
ports:
- '80:8080'步骤 6 – 安装新版本
假设你需要发布应用程序的更改。除非你启用了自动构建,否则你需要重复步骤 2 和 3,直到 Docker Hub 中出现新的镜像。.
然后,在您的服务器上,您需要手动拉取新镜像,如下所示:
docker compose -f docker-compose.yml pull
然后使用新镜像重启容器:
docker compose -f docker-compose.yml up -d --force-recreate
结果
太棒了,你成功了!以上就是使用 Docker、Docker Hub 和 Docker Compose 在 Ubuntu 24.04 上部署 Node.js 应用程序的基本介绍。.
我们了解了如何编写简单的 Dockerfile,如何构建镜像,如何推送镜像,以及如何将镜像部署到服务器。.
Docker 的功能远不止本教程所涵盖的,因此请务必查看 Docker 和 Docker Compose 文档,以了解更多相关概念和功能。.









