---
url: https://eoht.net/fe/docker/container.md
description: 用完整示例了解 Docker 容器生命周期，区分 run、start 和 exec，并配置文件复制、Tomcat 端口映射和容器网络。
---

# Docker 容器操作：创建、进入、复制文件与端口映射 {#docker-container-operations}

示例在已安装 Docker Engine、能够连接 daemon 的终端运行。镜像标签会随上游更新，实际项目应选择兼容版本，需复现时固定镜像摘要。

## 查看 docker run 命令，创建并启动容器 {#create-and-start-container-with-docker-run}

```bash
docker run --help
```

基本形式为 `docker run [选项] 镜像 [命令]`。`run` 每次创建新容器，`start` 启动已有容器，`exec` 在运行中的容器内执行额外命令。

| 参数 | 用途 |
| --- | --- |
| `-i` | 保持标准输入打开 |
| `-t` | 分配伪终端，通常与 `-i` 一起用于交互 shell |
| `-d` | 后台运行 |
| `--name` | 指定容器名称，名称在同一 daemon 中不能重复 |
| `-v` | 挂载目录或卷 |
| `-p` | 发布端口，格式如 `127.0.0.1:8080:8080` |

## 创建容器，并进入命令行 {#create-container-and-open-shell}

```bash
docker run -it --name shell-demo debian:bookworm-slim /bin/bash
```

这会创建名为 `shell-demo` 的容器，并把 Bash 作为其主进程。

### 退出 {#exit-container-shell}

在容器内执行：

```bash
exit
```

此示例的主进程结束，容器随之停止，但容器本身仍保留。

### 退出之后，重新进入容器 {#reenter-container-shell}

在宿主机重新启动并连接原有容器：

```bash
docker start -ai shell-demo
```

若容器本来就在运行，可从另一个宿主机终端执行 `docker exec -it shell-demo /bin/bash`。不要再次用同名 `docker run`，否则会发生名称冲突。

## 宿主机与 Docker 容器的文件传递 {#copy-files-between-host-and-container}

以下命令均在宿主机执行，容器运行或停止时都可以复制文件：

```bash
printf 'hello from host\n' > test.txt
docker cp ./test.txt shell-demo:/tmp/test.txt
```

### 从容器复制文件到宿主机 {#copy-files-from-container-to-host}

```bash
docker cp shell-demo:/tmp/test.txt ./test-from-container.txt
cat ./test-from-container.txt
```

读取到刚写入的文本，才说明本例复制结果符合预期。目标文件已存在时会被覆盖，实际使用前应确认路径。

## 访问 Tomcat {#access-tomcat-container}

在宿主机准备应用目录，再启动独立的服务容器：

```bash
mkdir -p ./webapps
docker run -d --name myTomcat \
  -p 127.0.0.1:8080:8080 \
  -v "$(pwd)/webapps:/usr/local/tomcat/webapps" \
  tomcat:10.1
docker logs myTomcat
```

将与 Tomcat 10.1 兼容的 WAR 包放入宿主机 `webapps` 目录；例如 `demo.war` 部署后从宿主机访问 `http://127.0.0.1:8080/demo/`。空应用目录访问 `/` 返回 404 并不等于容器未启动，应结合日志和应用路径检查。

这里仅发布到宿主机回环地址。在远程 VPS 上使用时可通过 SSH 转发访问；若要对外提供服务，应明确设置监听地址、反向代理与访问控制。容器中的 8080 与宿主机映射端口必须对应。

## 容器之间的关联 {#link-docker-containers}

新项目使用用户自定义网络，通过容器名解析服务地址，无需旧式 `--link`。下面是独立的 DNS / 网络演示，不会安装数据库：

```bash
docker network create demo-net
docker run -d --name demo-peer --network demo-net alpine:3.22 sleep 3600
docker run --rm --network demo-net alpine:3.22 ping -c 2 demo-peer
```

第二个容器能解析并收到 `demo-peer` 的响应，说明本例网络通信成立。真实应用仍需使用服务实际监听的端口和认证信息；共享网络不等于应用已经配置成功。

参考：[docker run](https://docs.docker.com/reference/cli/docker/container/run/)、[docker cp](https://docs.docker.com/reference/cli/docker/container/cp/)、[用户自定义 bridge 网络](https://docs.docker.com/engine/network/drivers/bridge/)。
