目录
一、Docker 简介与安装
1.1 三大核心概念
| 概念 | 解释 | 类比 |
|---|---|---|
| 镜像 (Image) | 只读的容器模板,包含运行环境和程序 | 类似安装光盘 / ISO 文件 |
| 容器 (Container) | 镜像运行后的实例,可读写,相互隔离 | 类似运行中的虚拟机 |
| 仓库 (Registry) | 存储和分发镜像的服务,默认是 Docker Hub | 类似 GitHub,存放镜像 |
一句话流程: 从仓库
pull镜像 →run启动成容器 → 容器里运行程序
1.2 安装 Docker(Linux)
Ubuntu / Debian — 官方一键脚本(推荐)
# 下载并执行官方安装脚本
curl -fsSL https://get.docker.com | bash
# 国内服务器推荐用阿里云源(速度更快)
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
Ubuntu / Debian — 手动 apt 安装
# 1. 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# 2. 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 3. 添加 Docker 软件源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# 4. 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
CentOS / RHEL
# 1. 安装 yum-utils
sudo yum install -y yum-utils
# 2. 添加 Docker 源(阿里云)
sudo yum-config-manager --add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 安装 Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
1.3 启动服务与验证
# 启动 Docker 服务
sudo systemctl start docker
# 设置开机自启
sudo systemctl enable docker
# 验证安装是否成功
docker --version
docker run hello-world
1.4 配置国内镜像加速源
Docker Hub 在国内访问慢,配置加速源可大幅提升镜像拉取速度。
# 编辑或创建 daemon.json
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
EOF
# 重启 Docker 使配置生效
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证加速源是否生效
docker info | grep -A5 "Registry Mirrors"
1.5 免 sudo 使用 Docker(可选)
# 将当前用户加入 docker 组
sudo usermod -aG docker $USER
# 重新登录后生效(或执行以下命令立即生效)
newgrp docker
# 验证
docker ps
二、核心命令速查
2.1 镜像管理
# 搜索镜像
docker search ubuntu
# 拉取镜像(默认 latest 标签)
docker pull ubuntu
docker pull ubuntu:20.04 # 指定版本
# 查看本地所有镜像
docker images
docker image ls
# 删除镜像
docker rmi ubuntu:20.04
docker rmi <镜像ID>
# 强制删除(即使有容器依赖)
docker rmi -f ubuntu:20.04
# 给镜像打标签
docker tag ubuntu:20.04 myubuntu:v1
# 保存镜像到文件(离线传输用)
docker save -o ubuntu.tar ubuntu:20.04
# 从文件加载镜像
docker load -i ubuntu.tar
# 查看镜像详细信息
docker inspect ubuntu:20.04
2.2 容器管理
# 运行容器(核心命令,参数见下方详解)
docker run ubuntu:20.04
# 查看运行中的容器
docker ps
# 查看所有容器(含已停止的)
docker ps -a
# 启动 / 停止 / 重启容器
docker start <容器ID或名称>
docker stop <容器ID或名称>
docker restart <容器ID或名称>
# 删除容器(必须先停止)
docker rm <容器ID或名称>
# 强制删除运行中的容器
docker rm -f <容器ID或名称>
# 进入运行中的容器
docker exec -it <容器ID或名称> /bin/bash
docker exec -it <容器ID或名称> /bin/sh # 部分镜像没有 bash
# 查看容器日志
docker logs <容器ID或名称>
docker logs -f <容器ID或名称> # 实时跟踪日志(类似 tail -f)
docker logs --tail 100 <容器ID或名称> # 只看最后 100 行
# 查看容器详细信息(IP、挂载、环境变量等)
docker inspect <容器ID或名称>
# 查看容器资源占用
docker stats
# 从主机复制文件到容器
docker cp ./文件 <容器名>:/容器内路径
# 从容器复制文件到主机
docker cp <容器名>:/容器内路径 ./本地路径
2.3 docker run 参数详解
docker run [参数] 镜像名 [命令]
| 参数 | 说明 | 示例 |
|---|---|---|
-d | 后台运行(detached 模式) | docker run -d nginx |
-p 宿主机端口:容器端口 | 端口映射 | -p 8080:80 |
--name 名称 | 指定容器名称 | --name myapp |
-e KEY=VALUE | 设置环境变量 | -e MYSQL_ROOT_PASSWORD=123456 |
-v 宿主机路径:容器路径 | 挂载数据卷 | -v /data:/var/www/html |
--rm | 容器退出后自动删除 | 适合一次性测试 |
-it | 交互模式(进入终端) | docker run -it ubuntu bash |
--network 网络名 | 指定容器网络 | --network mynet |
--restart always | 崩溃或重启后自动重启容器 | 适合服务容器 |
常用组合示例:
# 后台运行 + 端口映射 + 自定义名称
docker run -d -p 8080:80 --name mynginx nginx
# 交互式进入 Ubuntu 容器
docker run -it --rm ubuntu:20.04 /bin/bash
# 后台运行 + 挂载目录 + 环境变量
docker run -d \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=root123 \
-v /mydata/mysql:/var/lib/mysql \
--name mysql8 \
mysql:8.0
2.4 网络管理
# 查看所有网络
docker network ls
# 创建自定义网络(容器间可通过名称互相访问)
docker network create mynet
# 查看网络详情
docker network inspect mynet
# 将容器连接到网络
docker network connect mynet <容器名>
# 删除网络
docker network rm mynet
2.5 数据卷管理
# 查看所有数据卷
docker volume ls
# 创建数据卷
docker volume create mydata
# 查看数据卷详情
docker volume inspect mydata
# 删除数据卷
docker volume rm mydata
2.6 系统清理
# 删除所有停止的容器
docker container prune
# 删除所有未使用的镜像
docker image prune
# 一键清理(停止容器、未使用镜像、网络、缓存)
docker system prune
# 更彻底的清理(含未使用的数据卷)
docker system prune -a --volumes
三、漏洞环境拉取与本地测试全流程
适用于:CTF 靶机、渗透测试练习、漏洞复现
3.1 推荐靶场来源
| 靶场 | 地址 | 说明 |
|---|---|---|
| Vulhub | https://github.com/vulhub/vulhub | 最全面的漏洞环境库,基于 docker-compose |
| DVWA | docker pull vulnerables/web-dvwa | Web 安全综合练习平台 |
| WebGoat | docker pull webgoat/goat-and-wolf | OWASP 官方靶场 |
| Pikachu | 搜索 pikachu | 中文漏洞练习平台 |
| Metasploitable2 | docker pull tleemcjr/metasploitable2 | 经典综合靶机 |
3.2 Vulhub 靶场完整使用流程(最重要)
Vulhub 收录了 CVE 漏洞的复现环境,每个漏洞一个目录,一条命令启动。
第一步:安装依赖并克隆仓库
# 安装 git(如未安装)
sudo apt install -y git # Ubuntu
sudo yum install -y git # CentOS
# 克隆 Vulhub(国内用 gitee 镜像更快)
git clone https://github.com/vulhub/vulhub.git
# 国内加速(gitee 镜像)
git clone https://gitee.com/vulhub/vulhub.git
第二步:进入目标漏洞目录
cd vulhub
# 目录结构:漏洞类型/具体漏洞/
ls
# 常见目录:log4j2、struts2、thinkphp、fastjson、shiro、weblogic 等
# 进入具体漏洞(以 Log4j2 CVE-2021-44228 为例)
cd log4j/CVE-2021-44228
ls
# 会看到 docker-compose.yml 和 README.md
第三步:阅读 README
cat README.md
# README 里有漏洞说明、启动步骤、利用方法,必看!
第四步:启动漏洞环境
# 后台启动(自动拉取所需镜像)
docker-compose up -d
# 查看容器状态
docker-compose ps
# 查看日志(启动失败时排查用)
docker-compose logs -f
第五步:访问与测试
# 查看端口映射(对应 docker-compose.yml 里的 ports 配置)
docker-compose ps
# 通常通过浏览器或工具访问
# http://你的IP:映射端口
# 查看容器IP(若需要)
docker inspect <容器名> | grep IPAddress
第六步:测试完成,销毁环境
# 停止并删除容器和网络(保留镜像)
docker-compose down
# 同时删除数据卷(彻底清理)
docker-compose down -v
# 同时删除镜像(节省磁盘)
docker-compose down --rmi all
3.3 单容器靶场示例 — DVWA
# 拉取镜像
docker pull vulnerables/web-dvwa
# 启动容器(映射到本机 8888 端口)
docker run -d -p 8888:80 --name dvwa vulnerables/web-dvwa
# 访问
# http://127.0.0.1:8888
# 默认账号:admin / password
# 停止与删除
docker stop dvwa
docker rm dvwa
3.4 端口映射说明
docker run -p 宿主机端口:容器内端口
# 示例
-p 8080:80 # 访问本机 8080 → 容器内 80
-p 127.0.0.1:8080:80 # 只允许本机访问(安全,防止外部扫描)
-p 0.0.0.0:8080:80 # 允许所有 IP 访问
# 查看端口占用(启动失败时检查)
ss -tlnp | grep 8080
3.5 查看日志排查问题
# 查看容器实时日志
docker logs -f <容器名>
# 只看最后 50 行
docker logs --tail 50 <容器名>
# 查看 compose 编排中指定服务的日志
docker-compose logs -f web
3.6 完整清理流程
# 方式一:清理单个容器环境
docker stop <容器名>
docker rm <容器名>
docker rmi <镜像名>
# 方式二:清理 compose 环境(在 compose 文件目录下执行)
docker-compose down --rmi all -v
# 方式三:清理所有停止容器 + 无用镜像(节省空间)
docker system prune -a
四、docker-compose 完整教程
docker-compose 用于定义和运行多容器应用,一个 YAML 文件管理所有服务。
4.1 安装 docker-compose
方式一:二进制安装(推荐,最新版)
# 查看最新版本号:https://github.com/docker/compose/releases
VERSION="v2.27.0"
# 下载(国内用 ghproxy 加速)
sudo curl -L "https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
# 加速下载(国内推荐)
sudo curl -L "https://ghproxy.com/https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证
docker-compose --version
方式二:pip 安装
pip3 install docker-compose
docker-compose --version
注意:新版 Docker 已内置
docker compose(无连字符),功能相同,两种写法均可使用。
4.2 docker-compose.yml 文件结构详解
version: "3.8" # compose 文件格式版本
services: # 定义各个服务(容器)
web: # 服务名称(自定义)
image: nginx:latest # 使用的镜像
# 或者用 build 构建自定义镜像:
# build: . # 从当前目录 Dockerfile 构建
# build:
# context: ./app
# dockerfile: Dockerfile.prod
ports:
- "8080:80" # 宿主机端口:容器端口
volumes:
- ./html:/usr/share/nginx/html # 挂载目录
- mydata:/var/lib/data # 使用命名数据卷
environment:
- NGINX_ENV=production # 设置环境变量
- DB_HOST=db # 可以用服务名互相访问
networks:
- mynet # 加入自定义网络
depends_on:
- db # 等待 db 服务先启动
restart: always # 自动重启策略
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: "root123"
MYSQL_DATABASE: "mydb"
volumes:
- dbdata:/var/lib/mysql
volumes: # 声明命名数据卷
mydata:
dbdata:
networks: # 声明自定义网络
mynet:
driver: bridge
4.3 docker-compose 常用命令
# 在 docker-compose.yml 所在目录执行以下命令
# 启动所有服务(后台运行)
docker-compose up -d
# 启动并重新构建镜像
docker-compose up -d --build
# 停止并删除容器、网络(保留数据卷和镜像)
docker-compose down
# 停止并删除容器、网络、数据卷
docker-compose down -v
# 停止并删除容器、网络、镜像
docker-compose down --rmi all
# 查看服务状态
docker-compose ps
# 查看所有服务日志(实时)
docker-compose logs -f
# 查看指定服务日志
docker-compose logs -f web
# 进入指定服务的容器
docker-compose exec web /bin/bash
docker-compose exec db mysql -uroot -p
# 重启指定服务
docker-compose restart web
# 停止所有服务(不删除容器)
docker-compose stop
# 拉取最新镜像
docker-compose pull
# 查看服务配置
docker-compose config
4.4 Vulhub 的 docker-compose.yml 示例解读
以 Struts2 S2-045 为例(vulhub/struts2/s2-045/docker-compose.yml):
version: '2'
services:
struts2:
image: vulhub/struts2:2.3.30 # 使用官方漏洞镜像
ports:
- "8080:8080" # 映射 8080 端口供访问
使用步骤:
cd vulhub/struts2/s2-045
docker-compose up -d # 启动
# 访问 http://你的IP:8080
docker-compose down # 销毁
4.5 服务依赖启动说明
depends_on:
- db
- redis
注意:
depends_on只保证 db 容器启动后才启动 web,但不保证 db 服务完全就绪(如 MySQL 初始化需要时间)。 如果遇到连接失败,可在应用代码中加重试逻辑,或配合healthcheck使用。
五、Dockerfile 编写入门
Dockerfile 是构建自定义镜像的脚本文件,描述”如何一步步搭建环境”。
5.1 常用指令说明
| 指令 | 说明 | 示例 |
|---|---|---|
FROM | 指定基础镜像(第一条必须是它) | FROM ubuntu:20.04 |
RUN | 构建时执行命令 | RUN apt install -y curl |
COPY | 复制本地文件到镜像 | COPY ./app /app |
ADD | 类似 COPY,但支持解压 tar | ADD app.tar.gz /app |
WORKDIR | 设置工作目录(相当于 cd) | WORKDIR /app |
EXPOSE | 声明容器监听的端口(仅文档用途) | EXPOSE 8080 |
ENV | 设置环境变量 | ENV PATH="/app:$PATH" |
CMD | 容器启动时执行的默认命令 | CMD ["python", "app.py"] |
ENTRYPOINT | 容器入口命令(不可被覆盖) | ENTRYPOINT ["nginx"] |
ARG | 构建时传入的变量 | ARG VERSION=1.0 |
VOLUME | 声明挂载点 | VOLUME ["/data"] |
5.2 构建命令
# 基本构建(. 表示 Dockerfile 在当前目录)
docker build -t 镜像名:标签 .
# 示例
docker build -t mytool:v1.0 .
# 指定 Dockerfile 文件路径
docker build -f ./Dockerfile.prod -t myapp:prod .
# 构建时传入参数
docker build --build-arg VERSION=2.0 -t myapp:v2 .
# 查看构建结果
docker images | grep mytool
5.3 示例:构建自定义 Python 渗透工具镜像
目录结构:
mypentest/
├── Dockerfile
├── requirements.txt
└── scan.py
requirements.txt:
requests
beautifulsoup4
python-nmap
Dockerfile:
FROM python:3.11-slim
# 设置工作目录
WORKDIR /app
# 先复制依赖文件(利用层缓存:依赖不变时跳过安装步骤)
COPY requirements.txt .
# 安装依赖(合并 RUN 减少层数;清理缓存减小镜像体积)
RUN pip install --no-cache-dir -r requirements.txt \
&& apt-get update \
&& apt-get install -y --no-install-recommends nmap \
&& rm -rf /var/lib/apt/lists/*
# 复制程序文件
COPY scan.py .
# 声明端口(文档用途)
EXPOSE 8080
# 启动命令
CMD ["python", "scan.py"]
构建与运行:
cd mypentest
# 构建镜像
docker build -t mypentest:v1 .
# 运行容器
docker run -it --rm mypentest:v1
# 挂载当前目录(方便修改代码后直接测试)
docker run -it --rm -v $(pwd):/app mypentest:v1 python scan.py
5.4 层缓存优化技巧
# 好的写法:依赖文件先 COPY,代码文件后 COPY
# 依赖不变时,pip install 这层会直接使用缓存
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . . # 代码改了只重建这层之后的步骤
# 差的写法:全部 COPY 后再安装,每次代码修改都要重新 pip install
COPY . .
RUN pip install -r requirements.txt
# 多条 RUN 合并成一条,减少镜像层数
RUN apt update && \
apt install -y curl wget git && \
rm -rf /var/lib/apt/lists/*
六、常见问题与排错
6.1 容器启动失败
# 查看退出原因
docker logs <容器名>
docker-compose logs <服务名>
# 查看容器退出码
docker inspect <容器名> | grep "ExitCode"
# ExitCode: 0 = 正常退出
# ExitCode: 1 = 程序错误
# ExitCode: 137 = 被 kill -9 杀死(OOM 内存不足)
6.2 端口冲突(端口已被占用)
报错: Bind for 0.0.0.0:8080 failed: port is already allocated
# 查看端口占用情况
ss -tlnp | grep 8080
lsof -i :8080
# 方法一:换一个宿主机端口
docker run -p 9090:80 nginx # 改用 9090
# 方法二:停止占用端口的服务
sudo systemctl stop apache2 # 示例:停止 Apache
6.3 镜像拉取超时 / 失败
# 报错:timeout / connection refused / TLS handshake timeout
# 方法一:检查加速源是否配置(见 1.4 节)
cat /etc/docker/daemon.json
# 方法二:重启 Docker
sudo systemctl restart docker
# 方法三:手动指定加速源拉取
docker pull docker.mirrors.ustc.edu.cn/library/ubuntu:20.04
# 方法四:使用代理(如有)
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
EOF
sudo systemctl daemon-reload && sudo systemctl restart docker
6.4 权限问题
报错: permission denied while trying to connect to the Docker daemon socket
# 将用户加入 docker 组
sudo usermod -aG docker $USER
# 重新激活组权限(无需重启)
newgrp docker
# 验证
docker ps
6.5 磁盘空间不足
# 查看 Docker 占用磁盘情况
docker system df
# 清理无用资源(停止的容器、无标签镜像、未使用网络)
docker system prune
# 彻底清理(含未被使用的镜像和数据卷)
docker system prune -a --volumes
6.6 常用快捷操作
# 删除所有停止的容器
docker rm $(docker ps -aq -f status=exited)
# 删除所有无标签(<none>)的镜像
docker rmi $(docker images -q -f dangling=true)
# 进入最近一个运行中的容器
docker exec -it $(docker ps -q | head -1) /bin/bash
# 查看容器 IP 地址
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <容器名>
附录:命令速记卡
docker pull 镜像名 # 拉取镜像
docker images # 查看镜像列表
docker run -d -p 本地:容器 --name 名字 镜像 # 启动容器
docker ps / ps -a # 查看容器(运行中/全部)
docker exec -it 容器 /bin/bash # 进入容器
docker logs -f 容器 # 实时查看日志
docker stop 容器 # 停止容器
docker rm 容器 # 删除容器
docker rmi 镜像 # 删除镜像
docker-compose up -d # 启动编排服务
docker-compose down # 停止并删除编排服务
docker-compose logs -f 服务名 # 查看编排服务日志
docker system prune # 清理无用资源
发表回复