第3章:Docker 容器 - 动态的运行实例

第3章:Docker 容器 - 动态的运行实例

我们已经成功地使用 Dockerfile 为我们的 Node.js 应用构建了一个名为 my-app:1.0 的镜像。现在,这张"图纸"已经备好,是时候根据它来建造一所能对外提供服务的"房子"------也就是运行一个容器了。

本章,我们将深入学习 docker run 命令的各种强大参数,并掌握管理容器整个生命周期的核心技能。

3.1 [实战] 将我们的 Web 应用以容器形式运行起来

还记得我们在 Dockerfile 里用 EXPOSE 8080 指令声明了容器会监听 8080 端口吗?这就像是在房间里装了一部电话,分机号是8080,但外界并不知道总机号码,还是打不进来。

我们需要做一个端口映射 (Port Mapping) ,把主机(你的电脑)的一个端口,映射到容器的这个 8080 端口上。这样,所有访问你电脑特定端口的流量,都会被 Docker 自动转发到容器内部。

在命令行中执行以下命令:

bash 复制代码
docker run -p 4000:8080 my-app:1.0
  • docker run: 运行容器的命令。
  • -p 4000:8080: 这就是端口映射的关键。-p--publish 的缩写。它的格式是 <host_port>:<container_port>。这条命令的意思是,将主机的 4000 端口,映射到容器的 8080 端口。
  • my-app:1.0: 指定我们要运行哪个镜像。

命令执行后,你会看到和 node app.js 一样的输出 Running on http://0.0.0.0:8080。但这次,它是在一个隔离的容器环境中运行的!

现在,打开你的浏览器,访问 http://localhost:4000

你应该能看到页面上显示出 "Hello, Docker World! This is our first image."。

成功了! 你已经通过主机的端口,访问到了容器内部运行的 Web 服务。

但是,你会发现你的命令行窗口被这个容器的日志占用了,你无法再输入其他命令。要停掉它,你只能按 Ctrl + C。有没有办法让它在后台安静地运行呢?

3.2 docker run 命令的高级用法

docker run 是最核心的命令,它有许多强大的选项,可以让我们更灵活地控制容器。

后台运行 (Detached Mode)

要让容器在后台运行,我们只需要添加 -d--detach 参数。

我们先按 Ctrl + C 停掉刚才的容器,然后执行新命令:

bash 复制代码
docker run -d -p 4000:8080 my-app:1.0

这次,命令执行后,它不会打印应用日志,而是直接输出一长串十六进制的字符串。这个字符串是这个容器的唯一ID。你的命令行也立刻恢复了正常。

现在,再次访问 http://localhost:4000,你会发现应用依然在正常运行。

给容器起个名字

每次都用那一长串的ID来操作容器,实在太不方便了。我们可以用 --name 参数在启动时给容器起一个好记的名字。

bash 复制代码
# 先停掉并删除之前的容器,因为名字不能重复
# (我们会在 3.3 节详细讲解 stop 和 rm 命令)
docker stop <container_id>
docker rm <container_id>

# 启动一个有名字的容器
docker run -d -p 4000:8080 --name web-server my-app:1.0

现在,我们就可以用 web-server 这个名字来代替那串长长的ID了。

3.3 容器的生命周期管理

容器启动后,我们还需要对它进行管理,比如查看状态、停止、重启或删除。

  • 查看正在运行的容器:

    bash 复制代码
    docker ps
    # 或者 docker container ls

    这个命令会列出所有正在运行的容器,以及它们的基本信息,如容器ID、所用镜像、启动命令、创建时间、状态、端口映射和容器名。

  • 查看所有容器(包括已停止的):

    bash 复制代码
    docker ps -a

    你会看到一些 Exited 状态的容器,这些是你之前用 Ctrl + C 停掉或者运行出错的容器。

  • 停止一个容器:

    bash 复制代码
    # 使用名字或ID的前几位都可以
    docker stop web-server

    stop 命令会向容器发送一个信号,让它优雅地停止。

  • 启动一个已停止的容器:

    bash 复制代码
    docker start web-server
  • 删除一个容器 : 注意: 只有停止状态的容器才能被删除。

    bash 复制代码
    docker rm web-server

    如果你想强制删除一个正在运行的容器,可以加上 -f 参数:docker rm -f web-server

  • 查看容器日志: 对于后台运行的容器,我们如何看到它的输出呢?

    bash 复制代码
    docker logs web-server

    如果你想实时跟踪日志(像 tail -f 一样),可以加上 -f 参数:docker logs -f web-server

3.4 如何"进入"一个正在运行的容器?(exec)

有时候,我们需要进入容器内部,去看看文件系统,或者执行一些临时的调试命令。docker exec 命令就是为此而生的。

docker exec 允许你在一个正在运行的容器内,执行一个新命令。

最常见的用法是启动一个交互式的 shell(比如 bashsh):

bash 复制代码
# 确保你的 web-server 容器正在运行
docker start web-server

# -it 参数是关键:
# -i (interactive): 保持标准输入打开,允许你进行交互
# -t (tty): 分配一个伪终端
docker exec -it web-server /bin/sh

执行后,你会发现你的命令行提示符变了,类似 /usr/src/app #。这表示你已经成功进入了 web-server 容器的内部,并且当前位于我们在 Dockerfile 中设置的 WORKDIR

现在,你可以像在普通 Linux 环境中一样操作了:

  • 输入 ls -l,你会看到我们的 app.js, package.json 等文件。
  • 输入 cat app.js,可以查看应用代码。
  • 输入 ps aux,可以看到正在运行的 node app.js 进程。

要退出容器,只需输入 exit 或按 Ctrl + D

3.5 本章小结 & 避坑指南

你现在已经完全掌握了如何驾驭一个 Docker 容器。

  • 本章回顾

    • 我们学会了使用 -p 参数进行端口映射,让外部可以访问容器内的服务。
    • 我们学会了使用 -d--name 参数,让容器后台运行 并拥有一个自定义的名字
    • 我们掌握了容器的生命周期管理 命令:ps, start, stop, rm, logs
    • 我们学会了使用 docker exec 这个强大的工具,进入容器内部进行调试。
  • 避坑指南:端口冲突怎么办?

    • 问题 :执行 docker run -p 4000:8080 ... 时,报错 Error starting userland proxy: listen tcp4 0.0.0.0:4000: bind: address already in use
    • 原因 :这个错误明确地告诉你,你主机上的 4000 端口已经被其他程序占用了。Docker 无法监听一个已经被占用的端口。
    • 排查
      1. 你是不是已经启动了一个一模一样的容器,忘了关?用 docker ps 检查一下。
      2. 你电脑上是不是有其他开发工具(比如另一个Web服务)也正在使用 4000 端口?
    • 解决
      1. 停掉占用端口的那个容器或程序。

      2. 更简单的方法是 :换一个主机的端口号!比如,改成 5000

        bash 复制代码
        docker run -d -p 5000:8080 --name web-server-2 my-app:1.0

        现在,你就可以通过 http://localhost:5000 来访问了。 核心要点 :容器内的端口(8080)是由 Dockerfile 决定的,通常不轻易改变。而主机的端口,你可以根据实际情况随意选择一个未被占用的即可。

我们的应用已经能跑起来了,但还有一个致命问题:如果容器被删除了,应用产生的所有数据(比如用户上传的文件、数据库记录)都会丢失。下一章,我们将学习如何解决这个问题,为容器装上"记忆硬盘"------数据卷。

相关推荐
m0_7197592237 分钟前
Docker 常用命令
docker
风清再凯1 小时前
05-k8s网络
网络·容器·kubernetes
西柚小萌新2 小时前
【Bug:docker】--Docker国内镜像源加载失败
docker·容器·bug
爱宇阳4 小时前
GitLab Docker Compose 迁移教程
docker·容器·gitlab
●VON6 小时前
重生之我在大学自学鸿蒙开发第五天-《实战篇》
学习·华为·云原生·harmonyos·鸿蒙
冲上云霄的Jayden6 小时前
ubuntu 22一步步 安装docker和配置使用国内源
linux·ubuntu·docker·国内源
javpy7 小时前
docker部署nacos报错 ‘env NACOS_AUTH_TOKEN must be set with Base64 String.‘
linux·docker·centos
舰长1159 小时前
k8s 持久化存储方案-NFS
云原生·容器·kubernetes
心态特好11 小时前
详解云原生!!
云原生
hweiyu0011 小时前
Linux运维实战:云原生设计与实施Docker&K8S(视频教程)
linux·运维·云原生