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 无法正常显示的问题

Terminal window
# 查看是否存在 docker 用户组
grep docker /etc/group
# 若不存在 docker 用户组则创建
sudo groupadd docker
# 将非 root 用户添加到 docker 用户组
sudo usermod -aG docker <用户名>
Terminal window
# 这里的镜像名字为 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

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

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

curl 不能访问中转网址。

docker <命令> —help

Usage: docker search [OPTIONS] TERM
Terminal window
docker search <镜像名称>
Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Terminal window
docker pull <镜像名称>:[镜像版本]
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
Terminal window
docker images
Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
Terminal window
docker rmi <镜像ID>
docker rmi <镜像名称>:[镜像版本]
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Terminal window
docker commit -m "镜像信息" <容器名称> <镜像名称>:[镜像版本]
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
Terminal window
docker save -o <打包名称.tar> <镜像名称>:[镜像版本]
Usage: docker load [OPTIONS]
Terminal window
docker load -i <打包名称.tar>
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Terminal window
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]
Terminal window
docker ps
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
Terminal window
docker stop
Usage: docker start [OPTIONS] CONTAINER [CONTAINER...]
Terminal window
docker start
Usage: docker restart [OPTIONS] CONTAINER [CONTAINER...]
Terminal window
docker restart
Usage: docker stats [OPTIONS] [CONTAINER...]
Terminal window
docker stats
Usage: docker logs [OPTIONS] CONTAINER
Terminal window
docker logs
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Terminal window
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...]
Terminal window
docker rm <容器名称>
Terminal window
# 后台启动容器挂载本地目录
docker run -d -v <本地目录>:<容器目录> --name <容器名称> <镜像名称>

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

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

Terminal window
# 自动创建卷
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。

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

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

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

Terminal window

同步主机与容器的文件。

docker run -v 卷名/内部目录

Terminal window
docker volume create <卷名>
Terminal window
docker volume inspect <卷名>
Terminal window
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