Docker容器化Node.js应用操作教程

 更新时间:2025年12月12日 09:22:48   作者:宋冠巡  
本文介绍了如何使用Docker容器化一个简单的Node.js应用,从编写代码到运行容器,详细讲解了Docker的核心操作,包括构建镜像和运行容器,感兴趣的朋友跟随小编一起看看吧

从零开始:用Docker容器化你的第一个Node.js应用

1. 引言

在现代软件开发中,Docker已成为不可或缺的工具。它通过容器化技术,将应用及其依赖环境打包在一起,实现了“一次构建,处处运行”的梦想。今天,我将带大家完成一个完整的Docker实践:容器化一个简单的Node.js应用,从编写代码到运行容器,一步步掌握Docker的核心操作。

2. 项目准备

首先,我们创建一个简单的Node.js项目,仅包含两个文件:

2.1. 应用代码 (index.js)

console.log("你好,世界!")

这是一个最简单的Node.js程序,输出一句问候语。

2.2. Docker镜像定义文件 (Dockerfile)

让我们解析一下这个Dockerfile:

  • FROM node:14-alpine:指定基础镜像为Node.js 14的Alpine Linux版本,这是一个轻量级的Linux发行版
  • COPY index.js /index.js:将本地的index.js文件复制到容器内的根目录
  • CMD node /index.js:设置容器启动时默认执行的命令

3. 构建Docker镜像

有了Dockerfile,我们就可以创建自定义的Docker镜像了。

3.1. 构建命令

docker build -t hello-docker .

这个命令的含义是:

  • docker build:启动镜像构建过程
  • -t hello-docker:为镜像打上标签(名称),便于后续引用
  • .:使用当前目录作为构建上下文,Docker会查找当前目录下的Dockerfile

3.2. 构建日志

PS E:\hello-world\hello-docker> docker build -t hello-docker .
[+] Building 369.5s (7/7) FINISHED                                                                            docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                          0.1s
 => => transferring dockerfile: 103B                                                                                          0.0s
 => [internal] load metadata for docker.io/library/node:14-alpine                                                           263.8s
 => [internal] load .dockerignore                                                                                             0.0s
 => => transferring context: 2B                                                                                               0.0s
 => [internal] load build context                                                                                             0.1s
 => => transferring context: 29B                                                                                              0.0s
 => [1/2] FROM docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33     103.1s
 => => resolve docker.io/library/node:14-alpine@sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33       0.1s
 => => sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33 1.43kB / 1.43kB                                0.0s
 => => sha256:4e84c956cd276af9ed14a8b2939a734364c2b0042485e90e1b97175e73dfd548 1.16kB / 1.16kB                                0.0s
 => => sha256:0dac3dc27b1ad570e6c3a7f7cd29e88e7130ff0cad31b2ec5a0f222fbe971bdb 6.44kB / 6.44kB                                0.0s 
 => => sha256:0dac3dc27b1ad570e6c3a7f7cd29e88e7130ff0cad31b2ec5a0f222fbe971bdb 6.44kB / 6.44kB                                0.0s 
 => => sha256:f56be85fc22e46face30e2c3de3f7fe7c15f8fd7c4e5add29d7f64b87abdaa09 3.37MB / 3.37MB                               63.4s 
 => => sha256:8f665685b215c7daf9164545f1bbdd74d800af77d0d267db31fe0345c0c8fb8b 37.17MB / 37.17MB                             90.6s 
 => => sha256:e5fca6c395a62ec277102af9e5283f6edb43b3e4f20f798e3ce7e425be226ba6 2.37MB / 2.37MB                               52.7s 
 => => sha256:561cb69653d56a9725be56e02128e4e96fb434a8b4b4decf2bdeb479a225feaf 448B / 448B                                   95.7s 
 => => extracting sha256:f56be85fc22e46face30e2c3de3f7fe7c15f8fd7c4e5add29d7f64b87abdaa09                                     0.6s 
 => => extracting sha256:8f665685b215c7daf9164545f1bbdd74d800af77d0d267db31fe0345c0c8fb8b                                    11.2s 
 => => extracting sha256:e5fca6c395a62ec277102af9e5283f6edb43b3e4f20f798e3ce7e425be226ba6                                     0.3s 
 => => extracting sha256:561cb69653d56a9725be56e02128e4e96fb434a8b4b4decf2bdeb479a225feaf                                     0.0s 
 => [2/2] COPY index.js /index.js                                                                                             2.0s 
 => exporting to image                                                                                                        0.2s 
 => => exporting layers                                                                                                       0.1s 
 => => writing image sha256:be987f77136525684c13002b3a8d43cc6cd4d62986f7997128b51946aad6d03c                                  0.0s 
 => => naming to docker.io/library/hello-docker                                                                               0.0s 
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/pnwg2u6n5xocvatlj87a6v6fj
 1 warning found (use docker --debug to expand):
 - JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 3)

3.3. 构建过程解析

  1. Docker首先下载基础镜像node:14-alpine(如果本地不存在)
  2. 然后执行COPY指令,将index.js文件复制到镜像中
  3. 最后设置默认的启动命令
  4. 构建完成后,生成了一个ID为be987f771365的新镜像

这里Docker给出了一个有用的警告:建议使用JSON格式的CMD指令来避免信号处理问题。虽然不影响当前使用,但在生产环境中需要注意这一点。

4. 查看本地镜像

构建完成后,我们可以查看本地已有的Docker镜像:

docker images

日志输出:

PS E:\hello-world\hello-docker> docker images
REPOSITORY                       TAG       IMAGE ID       CREATED         SIZE  
hello-docker                     latest    be987f771365   8 minutes ago   119MB 
hello-world                      latest    74cc54e27dc4   10 months ago   10.1kB
hub.oepkgs.net/openeuler/nginx   <none>    1d992e662bfc   13 months ago   747MB

输出显示我们刚刚创建的hello-docker镜像大小为119MB,相比基础镜像已经很小了。同时可以看到系统中还有其他镜像,比如经典的hello-world测试镜像。

5. 运行容器

镜像只是静态的模板,要运行应用需要从镜像创建容器:

docker run hello-docker

日志输出:

PS E:\hello-world\hello-docker> docker run hello-docker
你好,世界!

执行后,终端立即输出了"你好,世界!"。这意味着:

  1. Docker从hello-docker镜像创建了一个新容器
  2. 容器内执行了node /index.js命令
  3. Node.js解释器执行了我们的代码,输出结果到终端
  4. 程序执行完毕,容器自动停止

6. 查看容器

PS E:\hello-world\hello-docker> docker ps   
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
PS E:\hello-world\hello-docker> 
PS E:\hello-world\hello-docker> docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS                      PORTS     NAMES
9fadd3ad3798   hello-docker   "docker-entrypoint.s…"   54 seconds ago   Exited (0) 52 seconds ago             affectionate_burnell

运行docker ps查看当前正在运行的容器,发现没有结果。这是因为我们的应用执行完就退出了,容器也随之停止。

但使用docker ps -a查看所有容器(包括已停止的),可以看到刚刚运行的容器:

  • 状态为"Exited (0)",表示正常退出
  • 54秒前创建,52秒前退出
  • 有一个随机生成的名字"affectionate_burnell"

这就是容器与虚拟机的关键区别之一:容器是为了运行特定进程而存在的,当进程结束,容器的使命也就完成了。

7. 实践总结

通过这个简单的实践,我们完成了Docker的核心工作流:

  1. 编写应用代码 → 2. 定义Dockerfile → 3. 构建镜像 → 4. 运行容器

在这个过程中,我们学到了几个关键点:

  • 镜像与容器的关系:镜像是静态的模板,容器是镜像的运行实例
  • 分层构建:Docker镜像采用分层结构,每一条指令都会创建一个新的层
  • 轻量级特性:容器随内部进程的结束而停止,资源占用更高效
  • 环境一致性:无论在哪里运行,容器内部环境都完全相同

到此这篇关于Docker容器化Node.js应用教程的文章就介绍到这了,更多相关docker容器化node.js内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • docker在Centos上做DNS服务器的配置全过程

    docker在Centos上做DNS服务器的配置全过程

    这篇文章主要介绍了docker在Centos上做DNS服务器的配置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • 解决docker拉取镜像报错:error pulling image configuration:(kafka)

    解决docker拉取镜像报错:error pulling image configurat

    在使用Docker拉取Kafka镜像时可能会遇到"error pulling image configuration"的错误,这可以通过编辑Docker配置文件并重启Docker服务来解决,具体步骤包括:1. 编辑Docker配置文件;2. 使用命令systemctl restart docker重启Docker服务
    2024-11-11
  • 给运行中的docker容器添加新的端口

    给运行中的docker容器添加新的端口

    今天小编就为大家分享一篇关于给运行中的docker容器添加新的端口,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • docker compose自定义网络实现固定容器ip地址

    docker compose自定义网络实现固定容器ip地址

    这篇文章主要介绍了docker compose自定义网络实现固定容器ip地址,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • docker构建的镜像的三种方式小结

    docker构建的镜像的三种方式小结

    这篇文章主要为大家详细介绍了docker中构建的镜像的三种方式,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-04-04
  • 使用docker-compose连接到宿主机网络

    使用docker-compose连接到宿主机网络

    这篇文章主要介绍了使用docker-compose连接到宿主机网络,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • docker部署firefox浏览器实现远程访问

    docker部署firefox浏览器实现远程访问

    在使用docker时,默认情况下只能在本地进行访问,本文就来介绍一下docker部署firefox浏览器实现远程访问,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • 将Docker镜像从服务器A迁移到服务器B的三种方法

    将Docker镜像从服务器A迁移到服务器B的三种方法

    这篇文章主要介绍了将postgres:15镜像从服务器A传到服务器B的三种方法:推荐使用Docker Save和Load,通过DockerHub或私有仓库中转,适用于内网环境,每种方法涉及保存/传输/加载或推送步骤,注意权限及网络条件,需要的朋友可以参考下
    2025-06-06
  • docker连接spring boot和mysql容器方法介绍

    docker连接spring boot和mysql容器方法介绍

    这篇文章主要介绍了docker连接spring boot和mysql容器方法介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • docker之点到点的容器网络的配置

    docker之点到点的容器网络的配置

    本篇文章主要介绍了docker之点到点的容器网络的配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03

最新评论