保姆级 Docker 入门教程

文章目录

保姆级 Docker 入门教程:镜像、容器、Dockerfile 一次讲明白

本文从一个真实项目(用 Docker 打包一个 Qt + OpenCV 的开发环境)出发,讲清楚 Docker 最核心的概念和操作,跟着做一遍你就能上手。

一、Docker 到底是什么?

一句话:Docker 是一个能把"软件 + 它依赖的所有东西"打包成一个标准"盒子"的工具,这个盒子在任何机器上都能原样运行。

打个比方:

  • 以前装环境,就像请钟点工到你家打扫------每个人家里都得单独打扫一遍,还容易漏。
  • Docker 就像盖样板房------照着一份"装修清单"(Dockerfile)在工厂造出标准样板房(镜像),谁要住就复制一间(容器),你原来的房子(真机)不受影响。

它的好处就一句:"我电脑上能跑,你电脑上也能跑",因为环境是打包好的、完全一致的。

二、三个核心概念(最重要)

1. 镜像(Image)

一个只读的模板 ,等于"程序 + 依赖 + 配置"打成的包,像装系统用的 .iso 快照。

用 docker build 从 Dockerfile 生成。

2. 容器(Container)

镜像运行起来的那个实例,是可读写的。一个镜像能同时跑出很多个互不干扰的容器。

类比:镜像 = 类(class),容器 = 对象(object);或者镜像 = 安装包,容器 = 正在跑的那个进程。

3. 仓库(Registry)

存镜像的地方。公共的是 Docker Hub,公司内部一般用 Harbor 这类私有仓库。

三、安装 Docker

Windows(Docker Desktop + WSL2)

  1. 管理员 PowerShell 运行 wsl --install(可能要重启)
  2. 去 docker.com 下载 Docker Desktop 安装包,安装时保持默认勾选 WSL2
  3. 装完启动 Docker Desktop,等左下角鲸鱼图标变绿
  4. 验证:PowerShell 里跑 docker version,能看到 Client 和 Server 两段就成功了

Linux(Ubuntu/Debian)

bash 复制代码
sudo apt update
sudo apt install -y docker.io
sudo docker run hello-world   # 看到 "Hello from Docker!" 就成功了

国内加速 :如果 docker run hello-world 卡住报 registry-1.docker.io 超时,是访问 Docker Hub 被墙了。配镜像加速器:

bash 复制代码
sudo tee /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": ["https://docker.m.daocloud.io"]
}
EOF
sudo systemctl restart docker

四、最常用的几个命令

命令 作用
docker run -it 镜像名 bash 启动一个容器并进入它的命令行
docker ps 查看正在运行的容器
docker ps -a 查看所有容器(含已停止的)
docker images 查看本地镜像
docker exec -it 容器名 bash 进入一个已在运行的容器
docker logs 容器名 看容器日志
docker rm 容器名 删除容器
docker rmi 镜像名 删除镜像
docker build -t 名字:标签 . 用 Dockerfile 构建镜像
docker pull 镜像名 拉取镜像

五、Dockerfile:把"装环境"写进文件

Dockerfile 本质就是一份**"在隔离环境里跑的安装脚本"**。你平时在 Linux 上手动装环境的命令,一条条写进去就行。

常用指令:

dockerfile 复制代码
FROM ubuntu:22.04              # 基于哪个基础镜像
ENV PATH="/opt/app/bin:$PATH"  # 设置环境变量
RUN apt-get install -y xxx     # 执行命令(装软件)
COPY 本地文件 容器内路径        # 复制文件进镜像
WORKDIR /workspaces            # 设置工作目录
USER vscode                    # 切换用户
CMD ["bash"]                   # 容器启动时执行的命令

多阶段构建(重点):一个 Dockerfile 里定义多个镜像,后面的可以基于前面的。作用是"编译阶段胖、运行阶段瘦":

dockerfile 复制代码
FROM ubuntu:22.04 AS base      # 第一阶段:装重依赖
RUN apt-get install -y 一大堆依赖...

FROM base AS develop           # 第二阶段:在 base 上再加工
USER vscode
WORKDIR /workspaces/xxx

六、实战:一个 Qt 6.9.2 + OpenCV 的多阶段 Dockerfile

这是我真实项目里写的开发环境镜像,两个阶段:

dockerfile 复制代码
# ===== base:安装重依赖 =====
FROM ubuntu:22.04 AS base

ENV DEBIAN_FRONTEND=noninteractive \
    QT_VERSION=6.9.2 \
    QT_PATH=/opt/qt/6.9.2/gcc_64
ENV PATH="${QT_PATH}/bin:${PATH}"

RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential gcc-12 g++-12 cmake ninja-build git \
        ca-certificates python3 python3-pip \
        libopencv-dev \
        libgl1-mesa-dev libxkbcommon-x11-0 libxcb-cursor0 \
        libxcb-shm0 libxcb-glx0 libxcb-xinput0 libxcb-util1 libglib2.0-0 \
        libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 \
        libxcb-render-util0 libxcb-shape0 libxcb-sync1 libxcb-xfixes0 libxcb-xkb1 \
        libx11-xcb1 libxrender1 libxi6 libxkbcommon0 \
        libfontconfig1 libdbus-1-3 libgl1 libegl1 \
    && rm -rf /var/lib/apt/lists/*

# g++-12 设为默认编译器
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 \
    && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100 \
    && update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 100

# 用 aqtinstall 装 Qt 6.9.2(装到 /opt/qt/6.9.2/gcc_64)
RUN pip3 install --no-cache-dir aqtinstall \
    && python3 -m aqt install-qt linux desktop "${QT_VERSION}" linux_gcc_64 --outputdir /opt/qt

# ===== develop:在 base 上加开发入口 =====
FROM base AS develop
RUN useradd -m -s /bin/bash vscode || true
USER vscode
WORKDIR /workspaces/rov-station

构建和验证:

bash 复制代码
docker build --target base -t rov-station-base .       # 构建 base
docker build --target develop -t rov-station-develop . # 构建 develop

# 验证环境
docker run --rm rov-station-base qmake -v      # 应报 6.9.2
docker run --rm rov-station-base g++ --version  # 应报 12.x
docker run --rm rov-station-develop whoami      # 应输出 vscode

七、网络模式和卷(两个高频概念)

网络模式

  • bridge(默认) :容器有独立的内网 IP,用 -p 主机端口:容器端口 映射端口。
  • host :容器直接复用宿主机的网络和 IP。当你的程序要用 UDP 跟外部设备通信、或设备要往"你的 IP"回包时,一定要用 host,因为 bridge 会 NAT 成另一个 IP,对方回不来。
bash 复制代码
docker run --network host 镜像名

卷挂载

把宿主机目录挂进容器,实现数据共享:

bash 复制代码
docker run -v 宿主机路径:容器路径 镜像名

八、新手最容易踩的坑

  1. 构建上下文太大 :在 ~ 这种大目录里 docker build,Docker 会把整个目录打包上传(动辄几 GB)。永远在一个专门的目录里 build,并且配 .dockerignore 排除不要的文件。

  2. .dockerignore :类似 .gitignore,告诉 Docker 构建时哪些文件别传:

    .git
    build/
    *.log

  3. GUI 程序在容器里跑不起来 :报 qt.qpa.xcb: could not connect to display 是缺 DISPLAY 和 xcb 库。跑 GUI 要 X11 转发(-e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix),并装齐 xcb 依赖(用 ldd .../libqxcb.so | grep "not found" 检查)。

总结

  • 镜像 = 打包好的环境模板,容器 = 跑起来的实例,Dockerfile = 自动搭环境的脚本。
  • 装一次、写一次,以后任何人一条命令得到一模一样的环境,这就是 Docker 的价值。
  • 多阶段构建、host 网络、.dockerignore 这三个点,是实际项目里最常用的。
相关推荐
vipxieliang6 小时前
Docker vs Podman vs containerd:容器运行时全景
docker·容器
vipxieliang6 小时前
数据持久化方案:卷、挂载、权限与备份恢复
docker·容器
vipxieliang6 小时前
Compose 生产级配置:从 demo 到可上线
docker
vipxieliang6 小时前
容器原理揭秘:namespace、cgroup 与镜像分层
docker·容器
wzq11_6667 小时前
Kubernetes集群——基础篇(基础知识与搭建步骤一遍过!!!)
java·容器·kubernetes
java_logo9 小时前
Docker 部署 dockurr/windows:轻松搭建浏览器可控 Windows 虚拟机
运维·windows·docker·容器·虚拟机·kvm·轩辕镜像
谢亮_vipxieliang10 小时前
私有镜像仓库:Registry、Harbor 与镜像同步实战
网络·docker·容器
努力努力再努力wz11 小时前
【边缘计算入门系列】从“在哪里算”到“怎么算”:一文建立边缘计算、算子、计算图与 Tensor 的底层心智模型
人工智能·docker·边缘计算
江湖有缘12 小时前
3款开源IT工具箱整理合集,可Docker一键部署!
docker·容器·开源