docker怎么学,一篇文档教会你
之前我录个docker的零基础教程,是23年5月份的时候

那个时候docker换个国内源就可以正常拉取镜像了
但是24年之后,受到众所周知的原因,所有的国内docker源都不行了
所以大大增加了入门难度
再加上内容有点浅显了,本课程再加点内容,并且前期尽量讲的通俗易懂
docker能干啥
试想一个场景,你开在windows上开发的一个web项目
好巧不巧,你是用python开发的,然后部署到服务器的时候,先是费劲的安装mysql,redis,nginx这些中间件,然后跑python项目,发现死活跑不起来,要不就提示少包,要不就提示函数不存在,咋回事呢?
使用docker之后,以后安装mysql、redis、es、nginx这些中间件这些就只需要一条命令即可
并且以后做的项目,项目部署也只需要一两条命令即可,大大方便了开发安装、部署流程
能看到这个文档的,我相信大家应该很焦虑啊,网上说啥的都有,什么docker不行了,现在都是k8s了,podman未来要取代docker等等
我反正就一句话,该学学,该用用,真的淘汰了就去拥抱新变化
我之前也学了jQuery,还用django写了前后端不分离的网站
但是也不妨碍我现在又学了go,用前后端分离的技术写网站
什么是docker
docker是一个用Go语言实现的开源项目,可以让我们方便的创建和使用容器,docker将程序以及程序所有的依赖都打包到docker container,这样你的程序可以在任何环境都会有一致的表现
我一直觉得没有docker,各个中间件的安装将会变得非常困难,比如安装mysql、es、nginx这些,因为不同的系统安装流程还不太一样
现在有了docker之后,只需要写个命令,只要我能跑起来,你运行这个命令也就能跑起来,和操作系统没关系
docker安装
本课程统一都使用linux/centos7系统安装docker,并且在此系统上进行docker的使用
# 删除之前的docker残留yum -y remove docker* yum install -y yum-utils yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce docker-ce-cli containerd.io -y # 启动dockersystemctl start docker # 开机启动systemctl enable docker
不太建议在windows上使用docker,一是windows上使用docker性能不太好,二是有细微的差异(比如host网络),三是实际部署的系统都是linux系统
yum用不了的,记得换源
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo yum clean all yum makecache
docker设置代理
从2024年开始,中国境内就不能在通过docker换国内源下载镜像了
这一点确实劝退了很多人
如果不会魔法的同学,可以使用腾讯云的服务器,腾讯云有docker私有源,可以下载镜像
也可以买一个境外、国外的服务器,也可以直接拉取docker镜像
真要随心所欲的拉取镜像,最好的方法还是学会魔法,以及配置docker代理
当然,本课程只能教你如何配置docker代理
创建 /etc/systemd/system/docker.service.d/http-proxy.conf 配置文件 [Service]Environment="HTTP_PROXY=http://192.168.80.1:7890"Environment="HTTPS_PROXY=http://192.168.80.1:7890"然后重新加载配置并重启服务: systemctl daemon-reload systemctl restart docker 然后检查加载的配置: systemctl show docker --property Environment
记得代理软件要开启内网访问
docker快速使用
大家是怎么安装mysql的呢?
原生安装?
翻遍官网找安装文件,又要配置密码,也要配置访问策略,太麻烦
使用docker,直接一条命令
docker run -itd -p 3306:3306 --name=mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
然后用你的mysql客户端,就可以连上你的mysql了,爽死
好了,我相信docker应该勾起了你的学习兴趣了,那么课程正式开始!
如果访问不了,大概率是端口没开
firewall-cmd --list-ports firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --reload
docker镜像
学习docker,从镜像开始
上面我提到的mysql、redis等,在dockerhub上就会有大佬或者官方把这些中间件制作成docker镜像
我们只需要使用docker pull 镜像名 就可以下载到我们本地了
镜像的基本操作
# 拉取镜像docker pull image_name:tag # 不写tag,默认是latest# 检索镜像docker search image_name:tag # 列表docker images # 删除镜像docker rmi image_id
docker容器
可以理解为一个非常精简的操作系统
在这个操作系统上,只部署了你需要的服务,也就是你对应的镜像
比如nginx的镜像,它运行的容器,就表示这个操作系统里面只有nginx这个软件服务
比如mysql的镜像,它运行的容器,就表示这个操作系统里面只有mysql这个软件服务
容器是 Docker 最核心的概念,本质是基于镜像运行的隔离进程—— 它复用宿主机内核,通过 Namespace、Cgroups 等技术实现资源隔离(网络、文件系统、进程)和限制(CPU、内存),比虚拟机更轻量、启动更快。
容器列表
# 查看正在运行中的容器docker ps # 查看所有容器docker ps -a # 只获取容器iddocker ps -a -q # 指定输出的内容docker ps -a --format "table {{.ID}}\t{{.Names}}"
运行容器
docker run [选项] <镜像名:标签> [容器启动参数]
选项
--name
表示为启动的容器起个名字,这个名字在宿主机上唯一 -t
为docker分配一个伪终端并绑定到容器的标准输入上 -i
是让容器的标准输入保持打开状态 -v
目录映射,实现数据的持久化,冒号前面表示宿主机的目录,后面是容器内目录。目录不存在会自动生成。 -p
端口映射,宿主机端口:容器端口 -e
表示要设置环境变量 -d
表示要以分离模式(也就是后台模式)启动容器,这样执行后会返回容器ID,不会进入交互界面。如果想要进入交互界面需要-i 和-t参数。 --restart
表示容器重启策略 --privileged
表示是否使用特权模式,设置–privileged=true提升系统执行权限。设置为true后,容器内的root用户才是真正的root权限,否则只是一个普通用户。
容器运行
以mysql为例
# 后台运行 并且 暴露端口 -p 宿主机端口:容器内端口docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 mysql:5.7 # 传递环境变量 配置数据库名docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=blog mysql:5.7 # 数据挂载 重启mysql,数据也不会丢失 -v 宿主机路径:容器内路径docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -v ./mysql_data:/var/lib/mysql mysql:5.7 # 限制 1G 内存、1 个 CPU 核心,超出内存时容器自动终止docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 --memory 1G --cpus 1 mysql:5.7 # 容器重启策略:always(总是重启,除非手动停止)docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 --restart always mysql:5.7 #on-failure[:max-retries]:仅在容器退出码非 0 时重启(可指定最大重试次数);#always:总是重启(包括手动停止后重启 Docker 服务时);#unless-stopped:除非手动停止,否则一直重启。
容器操作
# 停止容器docker stop docker_id # 启动容器docker start docker_id # 重启容器docker restart docker_id # 删除没有运行的容器docker rm docker_id # 删除运行中的容器docker rm -f docker_id # 停止所有容器docker stop $(docker ps -a -q)# 删除所有容器docker rm -f $(docker ps -a -q)
查看日志
# 查看这个容器的全部日志docker logs <容器名称> # 持续查看日志docker logs -f <容器名称> # 持续查看前10条日志docker logs -f -n 10 <容器名称> # 持续查看前10条日志 老版本dockerdocker logs -f --tail=10 <容器名称>
进入容器
容器本质是隔离的进程,进入容器 本质是在该隔离进程的 Namespace(命名空间)中启动一个新的终端进程(如 sh、bash),从而可以查看容器内文件、执行命令、调试 Go 程序(如查看进程、日志、修改配置)。
关键前提:只有运行中的容器才能进入
docker exec -it <容器名/容器ID> <容器内执行的命令>
端口映射
Docker 容器默认有独立的网络命名空间(隔离的网络环境),容器内的 mysql 服务监听的端口(如 3306)仅能在容器内访问。端口映射通过 Docker 的 iptables 规则,将「宿主机的端口」与「容器内的端口」建立映射关系,外部请求访问宿主机端口时,会被转发到容器内对应的端口,从而实现外部访问mysql 服务。
类比:容器是一个 “独立房间”,mysql服务在房间内的3306 端口提供服务;端口映射相当于在房间门上贴了一个 “门牌号(宿主机端口 3306)”,外部访客按门牌号敲门,会被引导到房间内的 3306 端口。
# 宿主机 3306 端口 → 容器 3306 端口(外部通过 http://宿主机IP:3306 访问)docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 mysql:5.7 # 宿主机随机端口 → 容器 3306 端口docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306 mysql:5.7 # 仅 192.168.80.185 这个网卡的 3306 端口映射到容器 3306docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 192.168.80.185.100:3306:3306 mysql:5.7 # 映射 多个端口docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -p 3306:3306 mysql:5.7
容器内的 服务必须监听
0.0.0.0(而非127.0.0.1),否则仅容器内可访问,外部无法通过端口映射访问(核心避坑点)。
比如 go的web服务
// 错误:仅容器内可访问http.ListenAndServe("127.0.0.1:8080", nil) // 正确:外部可通过端口映射访问http.ListenAndServe(":8080", nil) // 等价于 0.0.0.0:8080
目录映射
容器的文件系统是 “临时层”—— 基于镜像的只读层创建可写层,容器删除后,可写层的文件(如日志、配置修改、数据库数据)会丢失。目录映射(也叫 “挂载”)通过将「宿主机的目录 / 文件」与「容器内的目录 / 文件」建立关联,实现:
-
数据持久化:程序写入的日志、数据存储到宿主机,容器删除后数据不丢失; -
文件共享:宿主机修改配置文件,容器内实时生效(无需重启容器); -
避免镜像膨胀:无需将大文件(如日志、数据库)打包到镜像中。
Docker 支持两种目录映射方式:绑定挂载(Bind Mount) 和 数据卷(Volume),Go 场景中前者用于配置文件 / 日志,后者用于重要数据(如数据库)。
绑定挂载
直接将宿主机的自定义目录 / 文件挂载到容器,适合需要手动修改、查看的场景(如配置文件、日志目录)。
docker run -v <宿主机路径>:<容器内路径>[:权限] <镜像名> # ro:只读(容器内只能读取,不能修改宿主机文件);# rw:读写(默认,容器内可修改宿主机文件)。
# 宿主机 ./mysql_data 目录 → 容器 /var/lib/mysql 目录(读写权限)docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -v ./mysql_data:/var/lib/mysql mysql:5.7 # 目录映射之后,删除容器再执行运行命令,数据依然还在# 宿主机 ./xxx.txt 文件 → 容器 /etc/mysql/xxx.txt 文件(只读权限,防止容器修改)docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -v ./xxx.txt:/xxx.txt:ro mysql:5.7
要注意,直接用vi、vim修改文件,很可能是不会同步的,因为vi编辑是创建一个新文件然后把老文件删掉,再把新文件替换的方式,会打破docker的同步机制
数据卷(Volume)
Docker 管理的持久化存储
数据卷是 Docker 专门创建的持久化目录(存储在宿主机 /var/lib/docker/volumes/ 下),由 Docker 自动管理,无需手动维护宿主机路径,适合存储重要数据
核心优势
-
跨平台兼容性好(Docker 统一管理路径,不受宿主机目录结构影响); -
支持权限控制、数据卷备份 / 恢复; -
可在多个容器间共享数据(如多个服务共享同一个数据卷)。
# 创建名为 mysql_data 的数据卷docker volume create mysql_data # 数据卷 mysql_data → 容器 /var/lib/mysql 目录docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -v mysql_data:/var/lib/mysql mysql:5.7 # 查看所有数据卷docker volume ls # 查看数据卷详情(如存储路径)docker volume inspect mysql_data # 删除数据卷(需先解绑所有容器)docker volume rm mysql_data # 清理所有未使用的卷docker volume prune
容器常见问题
容器启动就报错?
-
先docker logs看日志,如果日志有错误输出,基本上就知道怎么去解决 -
没有日志?docker run … sh 重新跑这个容器,肯定能跑起来,跑起来进容器手动执行本来的启动命令,看看是什么反应
容器启动后,容器里面挂载目录下的原有文件消失
宿主机挂载目录为空,会覆盖容器内目录的原有文件(Docker 挂载规则:宿主机目录优先级高于容器内目录);
宿主机挂载的文件变成了目录?
Docker 挂载的「源路径」如果在宿主机上不存在,Docker 会默认创建一个「目录」而非「文件」—— 哪怕你在容器内的目标路径写的是文件,也会被这个新建的目录覆盖,最终容器内看到的就是目录,而非预期的文件。
镜像构建
上面的docker镜像和docker容器学完之后,可以覆盖你50%的docker应用场景了
针对一些复杂的操作,比如部署go项目、python这些自己的项目
又或者在一些基础镜像的基础上,安装一些软件
那就得写Dockerfile文件了
先看部署go项目的dockerfile示例
# 注释:指定基础镜像(必填,所有指令的起点)FROMgolang:alpineASbuilder# 设置环境变量ENV CGO_ENABLED 0ENV GOPROXY https://goproxy.cn,directRUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories# 设置工作目录WORKDIR/build# 复制文件ADD go.mod .COPY go.sum .ADD main.go .# 执行命令RUN go build -o mainFROMalpineWORKDIR/app# 维护者信息LABEL maintainer="fengfeng@xx.com"LABEL version="1.0"LABEL description="A demo Docker image for go app"# 元数据可通过 docker inspect <镜像名> 便于镜像管理# 多阶段构建COPY --from=builder /build/main /appRUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositoriesRUN apk add bash# 容器启动时执行的命令(必填,仅最后一个生效)CMD ["./main"]# 暴露端口(仅声明,不实际映射,用于文档说明)EXPOSE8080
构建命令
# 完整命令docker build -f Dockerfile -t demo-app:v1.0 . # 可省略-fdocker build -t demo-app:v1.0 .
构建上下文
docker build 最后一个参数(如 .、/home/user/project)指定的路径,就是「构建上下文」。Docker 客户端会将该路径下的所有文件 / 目录打包,发送给 Docker 守护进程(daemon),供 Dockerfile 中的 COPY/ADD 指令读取文件。
需要额外了解的
COPY和ADD
将本地文件 / 目录复制到镜像的指定路径,核心区别:ADD 支持自动解压压缩包、下载 URL 文件(不推荐,建议用 RUN wget 替代)。
# 复制本地 项目的所有文件到 到镜像的 /app 目录COPY . .# ADD 自动解压本地压缩包到镜像(如 tar.gz、zip)ADD . /app/
RUN、CMD和ENTRYPOINT
run:在镜像构建过程中执行命令(如安装依赖、解压文件、创建目录),执行结果会被固化到镜像的分层中。
两种格式
# Shell 格式:安装 nginx(合并命令减少镜像分层)RUN apt update && apt install -y nginx && rm -rf /var/lib/apt/lists/*# Exec 格式:创建目录(无 Shell 环境,不支持变量替换)RUN["mkdir", "-p", "/app/logs"]
cmd:默认启动命令,可被 docker run 后面的参数覆盖;
ENTRYPOINT:入口命令,docker run 后面的参数会作为其参数追加,不可覆盖(除非用 --entrypoint 参数强制替换)。
# ENTRYPOINT:固定启动命令ENTRYPOINT ["./main"]# CMD:默认启动参数# 这里默认指定 --env=dev 和 --port=8080,运行时可替换CMD ["--env", "dev", "--port", "8080"]
docker网络
Docker 网络是实现容器间、容器与外部(宿主机 / 互联网)通信的核心组件,其本质是通过 Linux 网络命名空间(Network Namespace) 实现容器网络隔离,再通过桥接、路由、端口映射等技术打通通信通道。
安装 Docker 后,会自动创建 3 个默认网络
docker network ls NETWORK ID NAME DRIVER SCOPE abc123xyz bridge bridge local # 默认桥接网络def456uvw host host local # 主机模式网络ghi789rst none null local # 无网络模式
桥接网络
容器启动时,Docker 自动分配:
-
独立 IP(如 172.17.0.2、172.17.0.3,子网默认 172.17.0.0/16); -
网关(宿主机 docker0 网桥 IP,如 172.17.0.1);
容器间通过 IP 通信,外部通过端口映射(-p)访问容器内的服务。
局限性:
-
默认桥接网络不支持 容器名解析(只能通过 IP 通信); -
所有默认桥接模式的容器在同一网段,隔离性较差(适合单服务,不适合多服务集群)。
自建桥接网络
手动创建的桥接网络,相比默认 bridge 有 2 个核心优势:
-
支持 容器名解析(容器间可通过容器名作为主机名通信,无需记 IP); -
网络隔离(不同自定义网络的容器无法通信,安全性更高)。
# 创建名为 go-microservice 的自定义桥接网络docker network create go-microservice # 启动依赖容器(Redis)并加入网络docker run -d --name redis --network go-microservice redis:alpine # 另一个容器也加入这个网络docker run -d --name go-server --network go-microservice -p 8081:8080 go-demo:1.0 # 然后在这个容器里面,就可以直接容器名访问对应的ip
自定义容器网络网段和容器ip
# 创建网段为 172.20.0.0/16、网关为 172.20.0.1 的自定义网络docker network create --subnet 172.20.0.0/16 --gateway 172.20.0.1 go-fixed-ip-network # 查看网络详情(确认网段和网关)docker network inspect go-fixed-ip-network # 指定固定 IP 172.18.0.10(需在自定义网络子网内)docker run -d --name go-server --network go-fixed-ip-network --ip 172.20.0.10 go-demo:1.0
主机模式
容器共享宿主机的网络命名空间,意味着:
-
容器没有独立 IP,直接使用宿主机的 IP; -
容器内的端口直接暴露在宿主机上(无需 "-p"端口映射); -
容器内的网络配置(如路由、DNS)与宿主机完全一致。
局限性
-
端口冲突风险:容器内端口与宿主机 / 其他容器端口冲突会导致启动失败; -
安全性较低:容器直接暴露在宿主机网络,无隔离性; -
跨平台不兼容:Windows/Mac 系统上 host 模式有兼容性限制(推荐仅在 Linux 上使用)。
# 启动 Go 容器,使用 host 模式,监听宿主机 8080 端口docker run -d --name go-server --net=host go-demo:1.0 --port 8080
docker compose
Docker Compose 是 Docker 官方提供的多容器应用编排工具,核心作用是通过一个统一的配置文件(默认 docker-compose.yml)定义、管理多个关联的 Docker 容器,实现「一键启动 / 停止 / 销毁」整个应用集群,解决了手动逐个操作容器(如网络配置、依赖顺序、端口映射)的繁琐问题。
当你的应用依赖多个服务时(比如:Web 服务 + 数据库 + 缓存 + 消息队列),手动操作会面临以下痛点:
-
需逐个运行 docker run命令,参数冗长(端口、网络、数据卷、环境变量等); -
需手动维护容器间的网络连通(如让 Web 容器访问 DB 容器); -
容器启动顺序有依赖(必须先启动 DB,再启动 Web); -
服务扩容、重启、日志查看需逐个操作。
而 Docker Compose 可以:
-
用一个 YAML 文件声明所有服务配置; -
一键启动 / 停止所有服务( docker-compose up/down); -
自动创建独立网络,让容器间通过服务名互通; -
维护容器依赖关系、数据卷持久化、环境变量隔离; -
统一查看所有服务日志、扩容服务实例。
基本结构
# 版本声明(推荐 v3,兼容 Docker 17.06+)version: '3'# 定义所有服务(核心模块,每个服务对应一个容器)services: 服务1名称: # 镜像(必填):来自 Docker Hub 或自定义镜像image: 镜像名:标签# 容器名称(可选,默认自动生成)container_name: 容器名# 端口映射(可选):主机端口:容器端口ports: - "主机端口1:容器端口1" - "主机端口2:容器端口2"# 环境变量(可选):两种写法environment: - 键=值 # 直接写 - 键2=值2env_file: # 从文件读取(优先级低于 environment) - .env# 数据卷(可选):持久化数据或挂载主机目录volumes: - 主机目录:容器目录 # 绑定挂载 - 数据卷名称:容器目录 # 命名数据卷# 依赖服务(可选):启动顺序(先启动依赖的服务)depends_on: - 服务2名称 - 服务3名称# 网络(可选):指定服务加入的网络networks: - 自定义网络名# 重启策略(可选):容器退出后的重启规则restart: always # 可选:no/on-failure/unless-stopped# 定义网络(可选,默认会创建一个默认网络)networks: 自定义网络名: driver: bridge # 网络驱动(默认 bridge,支持 overlay 等)# 定义数据卷(可选,用于持久化服务数据)volumes: 数据卷名称: driver: local # 数据卷驱动(默认 local)
示例
# 版本声明(推荐 v3,兼容 Docker 17.06+)version: '3'# 定义所有服务(核心模块,每个服务对应一个容器)services: web: # 镜像(必填):来自 Docker Hub 或自定义镜像image: web:v1# 容器名称(可选,默认自动生成)# container_name: 容器名# 端口映射(可选):主机端口:容器端口ports: - "8081:8080"# 环境变量(可选):两种写法environment: - xxx=dev # 直接写# 网络(可选):指定服务加入的网络networks: - xx_net# 重启策略(可选):容器退出后的重启规则restart: always # 可选:no/on-failure/unless-stoppedweb1: image: web:v1ports: - "8082:8080"networks: - xx_netrestart: always# 定义网络(可选,默认会创建一个默认网络)networks: xx_net: driver: bridge # 网络驱动(默认 bridge,支持 overlay 等)
常用命令
# 后台启动所有服务docker compose up -d # 查看 web 服务的实时日志docker compose logs -f web # 进入 db 服务容器(如 MySQL)docker compose exec db bash # 停止所有服务(保留容器和数据卷)docker compose stop # 停止并删除所有服务、网络、容器(保留数据卷)docker compose down # 停止并删除所有(包括数据卷)docker compose down -v
实战:go+mysql部署
services: blog: image: web:v3networks: - blogrestart: alwaysvolumes: - ./settings.yaml:/app/settings.yamldepends_on: - mysqlmysql: image: mysql:5.7environment: - MYSQL_ROOT_PASSWORD=123456 - MYSQL_DATABASE=blogvolumes: - ./mysql_data:/var/lib/mysqlnetworks: - blogrestart: always# 定义网络(可选,默认会创建一个默认网络)networks: blog: driver: bridge # 网络驱动(默认 bridge,支持 overlay 等)
go语言对接docker api
有些情况下,需要通过代码实现对容器的操作
比如获取容器列表,获取镜像列表,创建容器,删除容器
packagemainimport ( "context""fmt""github.com/docker/docker/api/types/container""github.com/docker/docker/api/types/image""github.com/docker/go-connections/nat""log""github.com/docker/docker/client") varcli*client.Clientfuncinit() { // 初始化 Docker 客户端(使用默认端点)// 如需自定义端点(如远程 Docker 服务),可通过 client.WithHost("tcp://192.168.1.100:2375") 指定_cli, err:=client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) iferr!=nil { log.Fatalf("创建 Docker 客户端失败:%v", err) } //defer cli.Close() // 退出时关闭客户端连接fmt.Println("Docker 客户端连接成功!") cli = _cli} funcimageList() { list, _:=cli.ImageList(context.Background(), image.ListOptions{}) for_, summary:=rangelist { fmt.Printf("%s %s\n", summary.ID[7:19], summary.RepoTags) } } funccontainerList() { list, _:=cli.ContainerList(context.Background(), container.ListOptions{}) for_, summary:=rangelist { fmt.Println(summary.ID[7:19], summary.Names, summary.State, summary.Image) } } //func (cli *Client) ContainerCreate(// ctx context.Context, // 上下文(控制超时、取消等)// config *container.Config, // 容器核心配置(对应之前你问的 Config 结构体)// hostConfig *container.HostConfig, // 主机资源配置(与宿主机交互相关)// networkingConfig *network.NetworkingConfig, // 网络配置(容器网络栈、端口映射等)// platform *ocispec.Platform, // 目标平台(跨架构场景用,如 arm64/amd64)// containerName string // 容器名称(可选,如不指定则自动生成)//) (container.CreateResponse, error)funccontainerCreate() { response, err:=cli.ContainerCreate( context.Background(), &container.Config{ AttachStdin: true, AttachStdout: true, OpenStdin: true, StdinOnce: true, Image: "alpine:latest", Cmd: []string{"sh"}, }, &container.HostConfig{ PortBindings: nat.PortMap{ "80": []nat.PortBinding{ { HostIP: "0.0.0.0", HostPort: "80", }, }, }, }, nil, nil, "alpine", ) iferr!=nil { fmt.Println("创建容器失败", err) return } fmt.Println("容器创建成功", response.ID) err = cli.ContainerStart(context.Background(), response.ID, container.StartOptions{}) iferr!=nil { fmt.Println("容器启动失败", err) return } fmt.Println("容器启动成功") } funcmain() { containerCreate() }
docker自建仓库
在内网环境下,如果很多服务器都需要下载镜像,每个都去配置docker代理会不太方便
所以更多时候可以在一个服务器集中存镜像,在那个服务器上运行docker registry服务,创建一个docker镜像仓库
其他服务器就可以直接拉取这个机器的镜像
docker pull registry
修改配置文件
Docker 官方默认要求镜像仓库(Registry)必须使用 HTTPS 协议 通信(保证传输加密和身份验证)。但实际场景中,很多企业 / 个人会搭建 私有镜像仓库(比如用 Docker 官方的 registry 镜像搭建),这类私有仓库可能因成本 / 环境限制,只开启 HTTP 协议(未配置 HTTPS 证书)。
insecure-registries(中文:“不安全的仓库”):告诉 Docker 「以下仓库是可信的,允许用 HTTP 协议通信,无需验证 HTTPS 证书」。
vim /etc/docker/daemon.json {"insecure-registries": ["192.168.80.185:5000"]}systemctl restart docker
运行registry服务
docker run -itd -v /data/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:latest
上传镜像
# 给镜像打tagdocker tag alpine:latest 192.168.80.185:5000/alpine:latest # 上传到私有仓库docker push 192.168.80.185:5000/alpine:latest
拉取镜像
要配置insecure-registries
docker pull 192.168.80.185:5000/alpine
夜雨聆风