Skip to content

Docker 学习笔记

https://docs.docker.com/

创建自己的开发镜像

https://docs.docker.com/desktop/install/windows-install/

https://docs.docker.com/desktop/setup/install/linux/

将非 root 用户添加到 Docker 用户组

Section titled “将非 root 用户添加到 Docker 用户组”

可以解决桌面端 docker 无法正常显示的问题

# 查看是否存在 docker 用户组
grep docker /etc/group
# 若不存在 docker 用户组则创建
sudo groupadd docker
# 将非 root 用户添加到 docker 用户组
sudo usermod -aG docker <用户>
# 这里的镜像名字为 ubuntu
docker run --network host -it --name myenv <镜像名称>
# 可以共享 USB 设备的启动方式
docker run -it --privileged --device=/dev/bus/usb --network host --name myenv <镜像名称>

运行容器时使用 --network host 选项,这样容器会直接使用主机的网络,包含 VPN 的配置。

--privileged 打开超级用户权限。

--device=/dev/bus/usb 挂载 USB 设备。

-it 以交互窗口运行容器。

--name myenv 设置容器名称为 myenv

# 这里的容器名字为 myenv
docker start <容器ID或名称>
docker exec -it <容器ID或名称> bash
# 检查生成的 index.html 文件即可
wget www.google.com

墙会阻止 ping 接受网址发回的响应数据。

curl 不能访问中转网址。

docker <命令> —help

Usage:  docker search [OPTIONS] TERM
docker search <镜像名>
Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]
docker pull <镜像名>:[镜像版本]
Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]
docker images
Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]
docker rmi <镜像ID>
docker rmi <镜像名>:[镜像版本]
Usage:  docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker commit -m "镜像信息" <容器名> <镜像名>:[镜像版本]
Usage:  docker save [OPTIONS] IMAGE [IMAGE...]
docker save -o <打包名称.tar> <镜像名>:[镜像版本]
Usage:  docker load [OPTIONS]
docker load -i <打包名称.tar>
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
参数说明示例
核心参数-d (—detach)后台运行容器docker run -d nginx
-it交互式运行(组合 -i STDIN 和 -t TTY)docker run -it ubuntu /bin/bash
—name指定容器名称docker run —name my_nginx nginx
—rm容器退出后自动删除docker run —rm alpine echo “hello”
设备挂载—device挂载设备文件到容器中(默认权限rwm)docker run —device=<主机设备路径>:<容器内路径>[:权限] …
网络相关-p (—publish)端口映射(主机:容器)docker run -p 8080:80 nginx
—network指定网络模式docker run —network=host nginx
—add-host添加自定义主机名解析docker run —add-host=test:127.0.0.1 alpine
资源限制-m (—memory)内存限制docker run -m 512m alpine
—cpusCPU 核心数限制docker run —cpus=1.5 nginx
—shm-size共享内存大小docker run —shm-size=1g redis
卷挂载-v (—volume)挂载主机目录到容器docker run -v /data:/app nginx
—mount更灵活的挂载方式docker run —mount type=bind,src=/data,dst=/app nginx
权限与安全—privileged赋予容器特权模式docker run —privileged ubuntu
-u (—user)指定运行用户docker run -u 1000 alpine
—cap-add添加 Linux 能力docker run —cap-add=SYS_ADMIN alpine
环境变量-e (—env)设置环境变量docker run -e MY_VAR=123 alpine
—env-file从文件读取环境变量docker run —env-file=.env nginx
其他常用—restart重启策略(如 always)docker run —restart=always nginx
-w (—workdir)设置容器工作目录docker run -w /app alpine pwd
—entrypoint覆盖镜像默认入口docker run —entrypoint=/bin/sh nginx
  • 使用 --privileged 会降低安全性,仅在需要时使用。
  • -v--mount 区别:后者支持更多选项(如只读挂载)。
  • 生产环境建议明确设置资源限制(-m, --cpus)。
Usage:  docker ps [OPTIONS]
docker ps
Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker stop
Usage:  docker start [OPTIONS] CONTAINER [CONTAINER...]
docker start
Usage:  docker restart [OPTIONS] CONTAINER [CONTAINER...]
docker restart
Usage:  docker stats [OPTIONS] [CONTAINER...]
docker stats
Usage:  docker logs [OPTIONS] CONTAINER
docker logs
Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec
参数说明示例
核心参数-it交互式进入容器(组合 -i 和 -t)docker exec -it nginx bash
-u (—user)指定执行命令的用户docker exec -u root nginx whoami
-w (—workdir)设置命令的工作目录docker exec -w /app nginx pwd
后台执行-d (—detach)后台运行命令(不占用终端)docker exec -d nginx tail -f /var/log/nginx/access.log
环境变量-e (—env)设置临时环境变量docker exec -e DEBUG=1 nginx env
—env-file从文件读取环境变量docker exec —env-file=.env nginx env
权限控制—privileged赋予命令特权权限docker exec —privileged nginx ip addr
  • 容器必须处于运行状态(先通过 docker ps 确认)。
  • 命令中涉及特殊字符(如 $)需用引号或转义(如 sh -c)。
  • 生产环境中谨慎使用 --privileged
Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]
docker rm <容器名>
# 后台启动容器挂载本地目录
docker run -d -v <本地目>:<容器目> --name <容器名> <镜像名>

卷名不已 ./ 位置符号开头

卷映射本地文件位置在 /var/lib/docker/volumes

# 自动创建卷
docker run -d -v <>:<容器目> --name <容器名> <镜像名>
# 主动创建卷
docker volume creat <>
# 查看卷
docker volume ls
# 查看卷详情
docker volume inspect <>

调用 Dockerfile 构建镜像,并管理多个容器的生命周期。

命令作用
docker`` ``compose up启动所有服务(-d 后台运行)
docker`` ``compose down停止并删除所有容器
docker`` ``compose build重新构建镜像
docker`` ``compose logs查看日志(-f 实时跟踪)
docker`` ``compose ps查看运行中的容器

定义单个容器的构建规则。

Usage: docker buildx build [OPTIONS] PATH | URL | -

# -t:指定镜像名称和标签
# . :Dockerfile 所在目录
docker build -t my-image:latest .

Docker Compose 使用 YAML 格式(通常是 docker-compose.yml 文件)来定义和编排多容器应用。

services:定义容器(镜像、端口、卷、网络等)。

volumes:管理持久化存储。

networks:控制容器间通信。

devices:挂载硬件设备(嵌入式开发关键)。

version: "3.8"  # 指定 Compose 文件版本(推荐 3.8+)
services:       # 定义所有服务(容器)
  service1:     # 服务名称(自定义)
    image: nginx  # 使用现成的镜像
    ports:
      - "80:80"
  service2:
    build: .     # 使用 Dockerfile 构建镜像
    volumes:
      - ./data:/app/data
volumes:        # 定义数据卷(持久化存储)
  my-volume:
networks:       # 定义网络
  my-network:
字段作用示例
image指定镜像名称image: nginx:alpine
build基于 Dockerfile 构建镜像build: ./dirbuild: context: ./dir dockerfile: Dockerfile.dev
ports端口映射(宿主机:容器ports: - "8080:80"
volumes挂载宿主机目录或卷到容器volumes: - ./app:/app
environment设置环境变量environment: - DB_HOST=db
env_file从文件加载环境变量env_file: .env
depends_on定义服务依赖顺序depends_on: - db
restart容器退出时重启策略restart: always
networks加入自定义网络networks: - my-network
devices挂载宿主机设备(如串口)devices: - "/dev/ttyUSB0:/dev/ttyUSB0"

用于持久化存储:

volumes:
  db-data:  # 自定义卷名(由 Docker 管理)
  app-data:
    driver: local  # 使用本地驱动

挂载示例

services:
  db:
    image: postgres
    volumes:
      - db-data:/var/lib/postgresql/data  # 使用命名卷
      - ./config:/etc/postgresql         # 挂载主机目录

自定义容器间通信网络:

networks:
  my-network:
    driver: bridge  # 默认驱动
    ipam:
      config:
        - subnet: "172.20.0.0/24"  # 指定子网

服务中使用

services:
  web:
    networks:
      - my-network
  db:
    networks:
      - my-network
version: "3.8"
services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - redis
  redis:
    image: redis:alpine
version: "3.8"
services:
  embedded-app:
    build: .
    devices:
      - "/dev/ttyUSB0:/dev/ttyUSB0"  # 挂载串口
    environment:
      - SERIAL_PORT=/dev/ttyUSB0
    volumes:
      - ./firmware:/app/firmware  # 挂载代码目录
version: "3.8"
services:
  db:
    image: mysql
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - backend
  api:
    build: ./api
    networks:
      - backend
      - frontend
volumes:
  db-data:
networks:
  backend:
  frontend:

Dockerfile 是构建镜像的“配方”,专注于单个容器的环境定义。

与 Compose 协作:Dockerfile 构建镜像,Compose 管理运行时。

Dockerfile 是一个文本文件,包含一系列指令,用于定义如何构建 Docker 镜像。它描述了镜像的基础环境、依赖安装、文件复制、启动命令等。

# 注释行(以 # 开头)
FROM base-image:tag      # 指定基础镜像(必须)
RUN command              # 执行命令(安装软件、配置环境)
COPY src dest            # 复制文件/目录到镜像
WORKDIR /path            # 设置工作目录
EXPOSE port              # 声明容器运行时监听的端口
CMD ["executable", "arg1", "arg2"]  # 容器启动时运行的默认命令
指令作用示例
FROM指定基础镜像(必须第一个指令)FROM ubuntu:20.04
RUN执行命令(安装软件、配置环境)RUN apt-get update && apt-get install -y python3
COPY复制本地文件到镜像(推荐)COPY ./app /app
ADD类似 COPY,但支持自动解压和远程 URL(慎用)ADD https://example.com/file.tar.gz /tmp
WORKDIR设置工作目录(后续指令的默认路径)WORKDIR /app
ENV设置环境变量ENV PYTHONPATH=/app
ARG定义构建时的变量(docker build --build-arg 传入)ARG USER=admin
EXPOSE声明容器运行时监听的端口(实际映射需在 docker run 或 Compose 中指定)EXPOSE 80
CMD容器启动时的默认命令(可被 docker run 覆盖)CMD ["python", "app.py"]
ENTRYPOINT类似 CMD,但不可被覆盖(通常与 CMD 结合使用)ENTRYPOINT ["python"] + CMD ["app.py"]
VOLUME声明数据卷挂载点(实际挂载需在 docker run 或 Compose 中指定)VOLUME /data
USER指定运行命令的用户(避免 root 权限)USER nobody
LABEL添加元数据(如作者、版本)LABEL maintainer="your@email.com"
# 基于 Python 官方镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 声明环境变量
ENV FLASK_APP=app.py

# 暴露端口(Flask 默认 5000)
EXPOSE 5000

# 启动命令
CMD ["flask", "run", "--host=0.0.0.0"]

示例 2:嵌入式开发(交叉编译环境)

Section titled “示例 2:嵌入式开发(交叉编译环境)”
# 使用 ARM 交叉编译工具链镜像
FROM arm-none-eabi-gcc:latest

# 安装额外工具
RUN apt-get update && apt-get install -y \
    minicom \
    screen \
    && rm -rf /var/lib/apt/lists/*

# 设置串口访问权限(Linux dialout 组)
RUN usermod -aG dialout developer

# 复制项目代码
COPY ./firmware /firmware
WORKDIR /firmware

# 默认编译命令
CMD ["make", "all"]

img

img

附加 Visual Studio Code 后会自动打开一个在该容器中的窗口。

默认情况下进入容器时用户为 root 不需要使用 sudo。

apt update && apt upgrade -y
  • cmake
apt install cmake -y
  • python
apt install python3 -y
  • DTC
apt install device-tree-compiler -y
  • usbutils
apt install usbutils -y
  • wget
  • sudo
# docker commit -m <提交信息> <容器ID或名称> <导出的镜像名>:<TAG>
docker commit -m "commit info" myenv myenv:v1.0
docker save -o myenv.tar myenv:v1.0
docker load -i myenv.tar

挂载主机的文件系统到 docker 容器。

docker run -v /外部目录/内部目录

同步主机与容器的文件。

docker run -v 卷名/内部目录

docker volume create <卷名>
docker volume inspect <卷名>
docker run -it --privileged --device=/dev/bus/usb --network host --name myenv <镜像名称>

WSL

镜像挂载 USB 的方式与 WSL 相同。

主机需已经存在 SSH 密钥对

https://geek-docs.com/git/git-questions/203_git_how_to_pass_local_machines_ssh_key_to_docker_container.html