docker/docker-compose笔记

目录

  1. Docker 简介与安装
  2. 核心命令速查
  3. 漏洞环境拉取与本地测试全流程
  4. docker-compose 完整教程
  5. Dockerfile 编写入门
  6. 常见问题与排错

一、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 推荐靶场来源

靶场地址说明
Vulhubhttps://github.com/vulhub/vulhub最全面的漏洞环境库,基于 docker-compose
DVWAdocker pull vulnerables/web-dvwaWeb 安全综合练习平台
WebGoatdocker pull webgoat/goat-and-wolfOWASP 官方靶场
Pikachu搜索 pikachu中文漏洞练习平台
Metasploitable2docker 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,但支持解压 tarADD 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           # 清理无用资源

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注