Files
docker_practice/05_container/5.2_daemon.md
2026-02-21 17:39:37 -08:00

6.3 KiB
Raw Blame History

5.2 后台运行

在生产环境中,我们通常需要容器持续运行,不受终端关闭的影响。本节将深入讲解如何让容器在后台运行,以及理解容器生命周期的核心概念。

核心概念:前台 vs 后台

当你在终端运行一个程序时,有两种模式:

  • 前台运行:程序占用当前终端,输出直接显示,关闭终端程序就停止
  • 后台运行:程序在后台执行,不占用终端,终端关闭也不影响程序

Docker 容器默认是 前台运行 的。使用 -d (detach) 参数可以让容器在后台运行。

基本使用

本节涵盖了相关内容与详细描述,主要探讨以下几个方面:

前台运行 (默认)

运行以下命令:

$ docker run ubuntu:24.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
hello world

容器会把输出的结果 (STDOUT) 打印到宿主机上面。此时:

  • 终端被占用,无法执行其他命令
  • Ctrl+C 会终止容器
  • 关闭终端窗口,容器也会停止

后台运行 (使用 -d 参数)

运行以下命令:

$ docker run -d ubuntu:24.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a

使用 -d 参数后:

  • 容器在后台运行
  • 返回容器的完整 ID
  • 终端立即释放,可以继续执行其他命令
  • 输出不会直接显示 (需要用 docker logs 查看)

深入理解:容器为什么会 “立即退出”?

这是初学者最常遇到的困惑。 理解这个问题,你就理解了 Docker 的核心设计理念。

很多人尝试这样启动容器:

$ docker run -d ubuntu:24.04

然后用 docker ps 查看,发现容器根本不在运行!这是为什么?

核心原理:容器的生命周期与主进程绑定

如下代码块所示,展示了相关示例:

flowchart TD
    subgraph Lifecycle ["Docker 容器的生命周期 = 容器内 PID 1 进程的生命周期"]
        direction LR
        Start["主进程启动"] --> Run["容器运行"]
        Exit["主进程退出"] --> Stop["容器停止"]
    end

当你运行 docker run -d ubuntu:24.04 时:

  1. 容器启动
  2. 没有指定命令,默认执行 /bin/bash
  3. 但没有交互式终端 (没有 -it 参数)bash 发现没有输入源
  4. bash 立即退出
  5. 主进程退出,容器停止

关键理解

  • -d 参数 不是 让容器 “一直运行”
  • -d 参数是让容器 “在后台运行”,能运行多久取决于主进程

常见的 “立即退出” 场景

相关信息如下表:

场景 原因 解决方案
docker run -d ubuntu 默认 bash 无输入立即退出 指定长期运行的命令
docker run -d nginx 后改了配置 配置错误导致 nginx 启动失败 查看 docker logs
自定义镜像容器启动即退 Dockerfile 的 CMD 执行完毕 确保 CMD 是前台进程

查看后台容器

本节涵盖了相关内容与详细描述,主要探讨以下几个方面:

查看运行中的容器

运行以下命令:

$ docker container ls
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES
77b2dc01fe0f  ubuntu:24.04  /bin/sh -c 'while tr  2 minutes ago  Up 1 minute        agitated_wright

查看容器输出日志

运行以下命令:

$ docker container logs 77b2dc01fe0f
hello world
hello world
hello world
...

实时查看日志 (类似 tail -f)

$ docker container logs -f 77b2dc01fe0f

查看已停止的容器

运行以下命令:

$ docker container ls -a

加上 -a 参数可以看到所有容器,包括已停止的。这对于调试 “容器启动即退出” 的问题非常有用。

最佳实践

本节涵盖了相关内容与详细描述,主要探讨以下几个方面:

1。长期运行的服务使用 -d

运行以下命令:

## Web 服务器

$ docker run -d -p 80:80 nginx

## 数据库

$ docker run -d -p 3306:3306 mysql:8

## 缓存服务

$ docker run -d -p 6379:6379 redis

2。调试时先用前台模式

当容器启动有问题时,去掉 -d 参数 可以直接看到输出和错误:

## 有问题的容器,先前台运行看看发生了什么

$ docker run myimage:latest

3。使用 --rm 自动清理

对于一次性任务,使用 --rm 参数让容器退出后自动删除:

$ docker run --rm ubuntu:24.04 echo "Hello, World!"
Hello, World!
## 容器执行完后自动删除

...

4。配合日志查看

运行以下命令:

## 后台启动

$ docker run -d --name myapp myimage:latest

## 查看最近 100 行日志

$ docker logs --tail 100 myapp

## 实时跟踪日志

$ docker logs -f myapp

## 查看带时间戳的日志

$ docker logs -t myapp

常见问题排查

本节涵盖了相关内容与详细描述,主要探讨以下几个方面:

Q容器启动后立即退出

  1. 查看退出状态码

    $ docker ps -a --filter "name=mycontainer"
    # 查看 STATUS 列,如 "Exited (1)" 表示异常退出
    
    
  2. 查看容器日志

    $ docker logs mycontainer
    
  3. 以交互模式调试

    $ docker run -it myimage:latest /bin/sh
    # 进入容器手动执行命令,查找问题
    
    

Q容器在后台运行但无法访问服务

  1. 检查端口映射

    $ docker port mycontainer
    
  2. 检查容器内服务状态

    $ docker exec mycontainer ps aux
    

Q如何让已经在后台运行的容器回到前台

使用 docker attach

$ docker attach mycontainer

注意attach 会连接到容器的主进程。如果主进程不是交互式的,你可能只能看到输出。使用 Ctrl+P Ctrl+Q 可以安全退出而不停止容器。

延伸阅读