docker 学习笔记
docker 安装
Linux 安装
在 https://get.docker.com/ 中获取到如下命令并执行
- curl -fsSL https://get.docker.com -o install-docker.sh
- sudo sh install-docker.sh
以下是针对 Alibaba Cloud Linux 3 的完整安装步骤:
首先,为你的系统添加阿里云镜像站提供的 Docker 软件源。
- sudo dnf config-manager --add-repo=https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
这一步是为了确保 Alibaba Cloud Linux 3 能正确识别并使用上一步添加的 CentOS 8 源。
- sudo dnf -y install dnf-plugin-releasever-adapter --repo alinux3-plus
正式安装 Docker
- sudo dnf -y install docker-ce --nobest
安装完成后使用 docker -v 查看版本
Windows 安装
Windows 搜索"启用或关闭 windows "功能,win10 勾选"virtual machine platform",win11 勾选"Hyper-V"功能,以及"适用于 Linux 的 Windows 子系统"
重启后会自动弹窗安装"适用于 Linux 的 Windows 子系统",也可以手动安装(wsl --update --web-download)
下载地址:
https://www.docker.com/products/docker-desktop/
到改地址下载对应的安装包即可
官方镜像仓库:
docker 使用
修改 docker 镜像站
执行 sudo vi /etc/docker/daemon.json,修改文件中内容如下
{
"registry-mirrors":[
"https://docker.m.daocloud.io",
"https://docker.1panel.live",
"https://hub.rat.dev"
]
}
修改完成后执行 sudo service docker restart
Windows 桌面版设置中 Docker Engine 里追加配置
docker pull 从仓库拉取镜像
docker pull docker.io/library/nginx:latest
- docker.io 仓库地址,如果是官方仓库可以省略
- library 命名空间(作者名),如果是官方可以省略
- nginx 镜像名称
- latest 镜像的 tag (版本号),不指定默认latest版本
简化后:docker pull nginx
表示从官方仓库中下载latest版本的nginx镜像
docker push 上传镜像
docker push user/镜像名称:tag
表示推送到 user 用户的仓库
docker run 使用镜像创建容器并启动
docker run nginx 使用镜像创建容器并启动ngnix
docker ps 查看运行的容器进程状况
docker ps -a 查看所有容器进程状况,
常用参数:
- --name 给容器定义名称,不能重复,没有的时候容器会自动创建随机名
- -d 后台启动运行
- -p 端口绑定,宿主机端口:容器内端口(-p 80:80)
- -v 文件绑定,宿主机文件(命名卷):容器内文件(因为容器每次关闭会把容器内文件删除),绑定后,容器内文件修改会影响宿主机文件,宿主机文件修改也会影响容器内文件,以便数据持久化保存,也可以使用docker创建一个存储空间(命名卷:docker volume create 卷名称),使用命名卷挂载,命名卷第一次使用的时候会把容器内的内容同步到命名卷里,直接绑定宿主机文件则不会同步。
- -e 给容器中传递环境变量(如:-e VAR=test)
- -it 可以进入容器内操作
- -rm 但容器停止的时候删除容器
- --restart 指定容器停止时的重启策略。always:无论容器之前是什么状态,只要Docker一启动,就会无条件地把这个容器也启动起来;unless-stopped:在Docker启动时,会检查容器在被停止前是否处于"运行"状态。如果是,则启动它;如果容器是被你手动停止的,则不会自动启动
- --network 网络名称:指定容器加入该网络
docker run 是从镜像创建容器,每次运行都会创建一个新的容器。如果不想创建新的容器可以使用以下命令:
- docker start 容器id或容器名称
- docker stop 容器id或容器名称
查看容器的信息:
- docker inspect 容器id或名称
只创建容器不启动:
- docker create 容器id或名称
查看容器日志:
- docker logs 容器id或名称(加上-f可以查看实时信息)
docker volume 命名卷操作
- docker volume create 卷名称:创建命名卷
- docker 卷名称 inspect: 查看创建的卷位置
- docker volume list: 查看所有创建的卷
- docker volume rm 卷名称:删除命名卷
- docker volume prune -a:删除所有没有任何容器在使用的卷
docker images 查看下载的镜像
docker rmi 删除镜像
docker rm 删除容器
docker exec
docker exec 容器id或名称 Linux命令:可以再容器内部执行Linux命令
docker exec it 容器id或名称 /bin/sh:进入容器内部获得一个交互式的命令行环境,类似于一个独立的操作系统
docker 镜像制作
Dockerfile
Dockerfile 是一个文本文件,包含了一系列指令。Docker 会按顺序执行这些指令,最终构建出一个自定义的镜像。可以将它看作是一份镜像的"配方"或"源代码"。指令按层级结构书写,因为在使用文件制作镜像的时候有缓存机制,依次从下往上执行,如果没有变动就用缓存,如果有变动就把该层以上的全部重新构建,所有变动越频繁的操作放在越上层,可减少构建时间。
构建指令
docker build -t 镜像名称:标签 构建目录
Dockerfile 核心指令
基础信息与初始化:
- FROM:指定基础镜像。这是 Dockerfile 的第一条有效指令,一切构建都基于此。(FROM ubuntu:22.04)
- ARG:定义构建参数。仅在构建过程中有效,构建结束后不会保留在镜像中。(ARG VERSION=latest)
复制与添加文件:
- COPY:复制文件或目录。从构建上下文(通常是项目目录)复制到镜像内。(COPY ./app /usr/src/app)
- ADD:功能更丰富的复制。除了 COPY 的功能,还能自动解压 .tar 压缩包,并支持从 URL 下载文件。如无特殊需求,应优先使用 COPY,因为它行为更透明。(ADD https://example.com/file.tar.gz /tmp/)
执行命令:
- RUN:构建时执行的命令。用于安装软件包、下载依赖、创建目录等,其结果是会被固化到新镜像层中。(RUN apt-get update && apt-get install -y nginx,
RUN npm install) - CMD:容器启动时执行的命令。可以被 docker run 后面的命令覆盖。一个 Dockerfile 只能有一个 CMD,如果有多个,只有最后一个生效。(CMD "node", "app.js")
- ENTRYPOINT:容器启动时的固定命令。与 CMD 不同,它提供的命令不容易被覆盖。通常将 ENTRYPOINT 设为固定的可执行文件,CMD 则用来提供其默认参数。(ENTRYPOINT "python")
环境与配置:
- ENV:设置环境变量。这个变量在构建过程和容器运行时都有效,可以被 RUN、CMD 等指令使用。(ENV NODE_ENV=production)
- WORKDIR:设置工作目录。如果目录不存在,会自动创建。后续的 RUN、CMD、ENTRYPOINT、COPY、ADD 指令都会在此目录下执行。(WORKDIR /app)
- USER:指定用户。用于切换运行容器的用户,以减少 root 权限带来的安全风险。(USER node)
- EXPOSE:声明端口。它只是一个元数据文档,告诉使用者容器会监听哪个端口,但不会自动映射端口。(EXPOSE 80)
其他与元数据;
- VOLUME:定义匿名卷。用于声明容器中的某个目录应该被挂载,以实现数据持久化或共享。(VOLUME /data)
- LABEL:添加元数据。为镜像添加键值对形式的说明信息,便于管理和检索。(LABEL version="1.0")
- HEALTHCHECK:容器健康检查。告诉 Docker 如何检查容器是否工作正常(HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1)
CMD 和 ENTRYPOINT 易混淆命令深度对比:
它们的核心区别在于命令能否被覆盖:
- ENTRYPOINT:设定容器启动时的"主命令",这个主命令很难被覆盖。
- CMD:设定容器启动时的"默认参数",这些参数很容易被覆盖。
| 组合形式 | 示例 | 运行 docker run my-image 实际执行 | 运行 docker run my-image --help 实际执行 |
|---|---|---|---|
| 仅有 CMD | CMD "python", "app.py" | python app.py | --help (因为覆盖了 python app.py) |
| 仅有 ENTRYPOINT | ENTRYPOINT "python" | python | python --help |
| 组合使用 (最佳实践) | ENTRYPOINT "python" CMD "app.py" | python app.py | python --help (只替换了 app.py 这个参数) |
Dockerfile 简单例子
FORM 基础镜像
WORKDIT /app // 设置容器内app目录为工作目录
COPY . . // 把DOckerfile文件所在的目录复制到app目录
RUN npm install // 安装依赖
EXPOSE 8080 // 声明端口,告诉使用者容器会监听哪个端口
ENTRYPOINT ["node"] // 执行主程序
CMD ["test.js"]
docker 网络
- docker network list:查看 docker 的所有网络
- docker network rm:删除创建的网络
Bridge:桥接模式
docker 默认网络模式,docker 容器内部可以通过容器ip地址互相访问,可以通过 docker network create 网络名称 来创建子网,容器启动时(--network)指定容器加入不同的子网,同一个子网的容器可以互相通信(也可以直接使用容器名称进行通信),不同子网的容器则不可以通信。
Host 模式
docker 容器直接共享宿主机的网络,容器直接使用宿主机的ip地址,而且无需使用-p进行端口映射,容器的端口直接运行在宿主机的端口
None 模式
不联网模式
docker compose
docker compose 是一个用于定义和运行多容器 Docker 应用的工具。简单来说,你不需要手动敲一串冗长的 docker run 命令来启动每个容器,只需在一个 docker-compose.yml 配置文件中把所有容器的参数(镜像、端口、卷、环境变量等)写好,然后执行一条命令就能全部启动和管理。
docker compose 会为每一个 compose 文件自动创建一个子网,同一个 compose 里定义的容器会自动加入该子网。
核心文件:docker-compose.yml
yaml
# 指定 Compose 文件格式版本(目前主流使用 v3)
version: '3.8'
# 定义要启动的所有服务(容器)
services:
# 服务1:Web 应用
web:
build: . # 使用当前目录的 Dockerfile 构建镜像
ports:
- "8080:80" # 端口映射:宿主机:容器内
environment: # 环境变量
- NODE_ENV=production
depends_on: # 依赖关系(等待 db 启动后再启动 web)
- db
restart: unless-stopped
# 服务2:数据库
db:
image: mysql:8.0 # 直接从仓库拉取镜像
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: secret123
MYSQL_DATABASE: myapp
volumes:
- db_data:/var/lib/mysql # 数据持久化(挂载卷)
# 定义命名的卷(用于持久化数据)
volumes:
db_data:
可以使用 .env 环境变量文件:在项目根目录创建 .env 文件,写入 MYSQL_ROOT_USER=user,在 docker-compose.yml 中直接用
docker compose 默认使用当前目录下的 docker-compose.yaml 文件,而且默认用当前文件夹的名字作为项目名。
常用命令
docker compose up -d
- p(--project-name):显式指定项目名称
- f:指定使用的配置文件
- up:创建并启动所有容器。-d 表示后台运行
- down:停止并删除所有容器、网络。加 -v 会同时删除匿名卷(慎用)。
- ps:列出当前项目下所有容器的状态。
- logs:查看容器的运行日志。-f 可实时追踪。
- exec:进入正在运行的容器执行命令(调试常用)。
- build:重新构建服务镜像(不启动)。
- restart:重启指定的服务。
- start:启动现有容器
- stop:停止现有容器
- config:验证 docker-compose.yml 的格式是否正确