Docker完整技术汇总
Docker
背景引入
-
在实际开发过程中有三个环境,分别是:开发环境、测试环境以及生产环境,假设开发环境中开发人员用的是jdk8,而在测试环境中测试人员用的时jdk7,这就导致程序员开发完系统后将其打成jar包发给测试人员后,测试人员由于环境不同而导致无法运行。

-
此时如果开发人员将打好的jar包以及环境一起放到一个容器中,然后将容器发给测试人员,此时测试人员就不会因为环境不同而无法运行程序。这样也就规避了软件跨环境迁移问题

Docker架构

- 如图所示,Docker主要分为三部分
- Clients:客户端
- Docker客户端用来向Docker发送命令
- Docker客户端会随着Docker的安装而安装
- Hosts:Docker核心
- Registries:Docker远程仓库
- Clients:客户端
- 在Docker核心中有两部分:local host本机以及remote host远程机器
- Docker在本机安装完之后,会以deamon守护进程的形式存在(即会在后台运行的进程)
- 该守护进程中有两部分
- image:镜像
- container:容器
- 镜像均来源于Docker远程仓库,该仓库主要有两种
- 官方提供的仓库Docker Hub
- 自己搭建的私有仓库Private registry
Docker基础定义

-
Docker:Docker是一种容器技术,解决软件跨环境迁移问题
- 它可以帮助我们下载应用镜像,创建并运行镜像的容器。从而达到快速部署应用(即它可以让开发者打包他们的应用以及依赖包到一个轻量级的、可移植的容器中,然后发布到任意流行的Linux机器上)
-
镜像:将应用所需的系统函数库、依赖、配置等与应用一起打包得到的就是镜像
- Docker安装应用时会自动搜索并下载应用镜像(image)
- 镜像仓库:存储和管理镜像的平台,Docker官方维护了一个公共仓库:Docker Hub
- 注意:镜像可以让我们快速跨操作系统部署应用而忽略其运行环境、配置,是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖等
-
容器:Docker会在运行镜像时创建一个相互隔离环境,称为容器
- 容器使用的是沙箱机制,相互隔离,性能开销极低
-
镜像与容器的关系
- 它俩就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,而容器是镜像运行时的实体
- 容器可以被创建、启动、暂停、停止、删除等等
CentOS7安装Docker
-
Step1: 首先如果系统中已经存在旧的Docker,则先卸载:
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce -
Step2: 安装yum工具
yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken -
Step3: 配置Docker的yum源
yum-config-manager --add-repo \https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.reposed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repoyum makecache fast -
Step4: 安装Docker
yum install -y docker-ce -
Step5: Docker启动与校验
# 启动Docker systemctl start docker# 停止Docker systemctl stop docker# 重启 systemctl restart docker# 设置开机自启 systemctl enable docker# 执行docker ps命令,如果不报错,说明安装启动成功 docker ps
Docker配置镜像加速(以阿里云为例)
-
Step1: 创建目录
mkdir -p /etc/docker -
Step2: 访问阿里官网在首页的产品中,找到阿里云的容器镜像服务


-
Step3: 配置镜像加速


# 注意把其中的镜像加速地址改成你自己的 tee /etc/docker/daemon.json <<-'EOF' {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["https://st5sw75p.mirrorcgrs572.aliyuncs.com","https://docker.registry.cyou","https://docker-cf.registry.cyou","https://dockercf.jsdelivr.fyi","https://docker.jsdelivr.fyi","https://dockertest.jsdelivr.fyi","https://mirror.aliyuncs.com","https://dockerproxy.com","https://mirror.baidubce.com","https://docker.m.daocloud.io","https://docker.nju.edu.cn","https://docker.mirrors.sjtug.sjtu.edu.cn","https://docker.mirrors.ustc.edu.cn","https://mirror.iscas.ac.cn","https://docker.rainbond.cc"] } EOF -
Step4: 重新加载配置
systemctl daemon-reload -
Step5: 重启Docker
systemctl restart docker
问题

-
在使用yum安装时若包如图所示错误,则解决步骤如下
-
通过
vi /etc/yum.repos.d/CentOS-Base.repo打开文件CentOS-Base.repo,然后将文件中的镜像替换为阿里镜像,文件内容更改如下:# CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # If the mirrorlist= does not work for you, as a fall back you can try the # remarked out baseurl= line instead. # #[base] name=CentOS-$releasever - Base - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7#released updates [updates] name=CentOS-$releasever - Updates - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/http://mirrors.aliyuncs.com/centos/$releasever/updates/$basearch/http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7#additional packages that may be useful [extras] name=CentOS-$releasever - Extras - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7#additional packages that extend functionality of existing packages [centosplus] name=CentOS-$releasever - Plus - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/ gpgcheck=1 enabled=0 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7#contrib - packages by Centos Users [contrib] name=CentOS-$releasever - Contrib - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/http://mirrors.aliyuncs.com/centos/$releasever/contrib/$basearch/http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/ gpgcheck=1 enabled=0 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7 -
执行以下两个命令刷新重载即可
yum clean all yum makecache
-
Docker命令
Docker服务相关命令
| 服务相关命令 | 解释 |
|---|---|
systemctl start docker | 启动Docker服务 |
systemctl status docker | 查看已经启动的Docker服务的状态 |
systemctl stop docker | 停止Docker服务 |
systemctl restart docker | 重启Docker服务 |
systemctl enable docker | 设置Docker为开机自启动 |

Docker的Image镜像相关命令

注意:此处只列举常用镜像命令,其余可详见官方文档
| 命令 | 说明 | 文档地址 |
|---|---|---|
docker images | 查看本地镜像 | docker images |
docker search + 镜像名 | 查看Docker库是否有对镜像 | |
docker pull + 镜像名 | 拉取镜像 | docker pull |
docker push | 推送镜像到DockerRegistry | docker push |
docker rmi | 删除本地镜像 | docker rmi |
docker rmi f | 强制删除本地镜像 | |
docker build | 构建镜像。详见自定义镜像部分内容 |
-
docker images -q:只显示所有镜像的id -
docker search + 镜像名查看docker官方镜像时无法连接成功,但是可以直接docker pull + 镜像名来拉取镜像,原因:-
在现有版本中无法使用
docker search + 镜像名查看docker官方镜像,而是使用docker search register.liberx.info/镜像名来查看docker官方镜像,如图所示
-
-
docker pull从docker仓库拉取镜像时,若不加版本号则会下载最新版本,若想加版本号则形式为:docker pull 镜像名:版本号。相应版本号可在Docker hub官网查看
-
删除本地镜像时有两种方式:
- 删除指定镜像
docker rmi + Image ID(即镜像ID)- d
ocekr rmi + 镜像名:版本号- 一般不会加
:版本号,除非系统中有多个版本的镜像
- 一般不会加
- 删除所有镜像:
docker rmi 'docker images -q'
- 删除指定镜像
代码示例


Docker容器相关命令

此处只列举出常用命令,具体可详见官网或菜鸟教程
| 命令 | 说明 | 文档地址 |
|---|---|---|
docker run | 创建并运行容器 | docker run |
docker stop | 停止指定容器 | docker stop |
docker start | 启动指定容器(该容器已存在) | docker start |
docker restart | 重新启动容器 | docker restart |
docker ps | 查看正在运行的容器 | docker ps |
docker ps -a | 查看创建的所有容器(包括运行和未运行的) | |
docker ps -aq | 查看创建的所有容器的id(包括运行和未运行的) | |
docker rm +容器id或容器名 | 删除指定的未在运行的容器 | docs.docker.com |
docker rm -f +容器id或容器名 | 删除指定的正在运行的容器 | |
docker rm 'docker ps -aq' | 删除创建的所有未运行的容器 | |
docker rm -f 'docker ps -aq' | 删除创建的所有正在运行的容器 | |
docker logs | 查看容器运行日志 | docker logs |
docker exec -it 容器名 /bin/bash | 进入容器 | docker exec |
docker exec -it 容器名 bash | 进入容器 | |
docker save | 保存镜像到本地压缩文件 | docker save |
docker load -i 镜像压缩文件 | 加载本地压缩文件到镜像 | docker load |
docker inspect + 容器名 | 查看容器详细信息 | docker inspect |
docker update --restart=always [容器名/容器id] | 设置指定Docker容器开机自启 |
docker run创建并运行容器
常用配置参数
| 配置参数 | 解释 |
|---|---|
-i | 交互式操作容器 |
-t | 给容器分配一个终端 |
-d | 让容器后台运行 |
-p 宿主机端口:容器内端口 | 将宿主机(即Linux系统)端口映射到容器内的端口 |
-e | 配置容器内的进程运行时的参数(即配置环境变量) |
--name=自定义容器名或--name 自定义容器名 | 给容器命名 |
--alias 自定义容器别名 | 给容器设置别名 |
-v 宿主机目录或文件:容器内目录或文件 | 配置数据卷,具体可详见数据卷配置内容 |
-- network 网络名 | 将容器加入到 已创建 的网络中。 |
REPOSITORY:TAG | 即镜像名:版本号,若未指定版本号则默认为最新版本 |
-
若只用
-it则在进入容器然后使用exit退出容器后,该容器也会自动停止运行
-
若用
-id则不能直接在docker run后加/bin/bash来直接进入容器,需使用docker exec -it 容器名 /bin/bash或docker exec -it 容器名 bash进入容器创建完后会自动显示当前容器的id,如图所示,即
239d0287448eafe208a04a21a4b848c22a316bd39a5d7e5d02c12eb97d1e676f
-
-it与-id的区别-it创建的容器称为交互式容器,exit退出后就会结束运行- 交互式容器在创建时就可进入容器内
-id创建的容器为守护式容器,exit退出后仍然会在后台运行- 守护式容器必须通过
docker exec -it 容器名 /bin/bash或docker exec -it 容器名 bash进入容器
-
创建并运行容器时,默认进入的即是工作目录
-
-- network 网络名- 当使用docker run来创建并运行容器,同时将容器加入到对应的网络中时,若网络不存在,则必须使用网络相关命令先创建。具体创建过程可详见网络部分内容
- 当在Docker Compose中将对应服务加入到网络中时,网络可以不存在,因为Docker Compose会自动创建对应的网路。详见Docker Compose部分内容
docker ps
不在示例,可详见
docker run示例
docker ps:查看运行中容器,这个命令也可以加格式化访问,这样会更加清爽,如下所示docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
docker ps -a:查看所有容器(包括运行中的和未运行的)。这个命令也可以加格式化访问,这样会更加清爽,如下所示docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
设置命令别名
给常用Docker命令起别名,方便我们访问:
-
Step1: 通过
vi /root/.bashrc修改/root/.bashrc文件 输入完该命令后即可进入到.bashrc文件,如图所示,原有文件内容如下:
起完别名后
wq保存并退出
Step2: 执行命令source /root/.bashrc使别名生效即可
数据卷

-
数据卷是宿主机中的一个目录或文件,并且该目录或文件需要通过
-v参数来与容器内的目录或文件进行映射- 当容器中的目录与数据卷目录绑定之后,此时任意一方的修改都会立即同步
- 一个数据卷可以被多个容器同时挂载,可以此来实现容器间的数据交互
- 一个容器也可以被挂载多个数据卷
-
数据卷作用
- 实现容器数据的持久化,此时数据不会随着容器的删除而消失
- 实现外部机器与容器间的通信
- 实现容器之间的数据交换
-
注意
/var/lib/docker/volumes这个目录就是默认的存放所有容器数据卷的目录,其下会再根据数据卷名称创建新目录,格式为/数据卷名/_data
-
为什么不让容器目录直接指向宿主机目录呢?
- 因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。
- 但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。
不过,我们发现由于数据卷目录比较深,不好寻找,通常我们也允许让容器直接与宿主机目录挂载而不使用数据卷
数据卷相关命令
| 命令 | 说明 | 文档地址 |
|---|---|---|
docker volume create | 创建数据卷 | docker volume create |
docker volume ls | 查看所有数据卷 | docs.docker.com |
docker volume rm + 卷名 | 删除指定数据卷 | docs.docker.com |
docker volume inspect | 查看某个数据卷的详情。若加卷名则查询指定数据卷;若不加则查看所有数据卷 | docs.docker.com |
docker volume prune | 清除所有未使用的数据卷 | docker volume prune |
配置数据卷
容器与宿主机进行数据交换
- 用到的命令
- 创建并启动容器时,使用-v参数配置数据卷:
docker run ... -v 宿主机目录或文件:容器内目录或文件... - 注意:
- 目录或文件必须是绝对路径
- 若目录或文件不存在,会自动创建
- 可以挂载多个数据卷
- 宿主机目录
/root/...等同于~/...,而容器目录只能用/root/...
- 创建并启动容器时,使用-v参数配置数据卷:
以redis为例

容器间数据交换
-
有两种方式
- 方式一:多个容器挂载同一个数据卷
- 方式二:使用数据卷容器
- 注意:方式一不在演示,主要演示方式二
-
数据卷容器解释

- 假设现在有三个容器:c1、c2、c3,c3挂载了一个数据卷,然后将c1、c2分别挂载到c3容器上,此时就相当于c1、c2、c3挂载了同一个数据卷。这样就实现了容器间的通信,此时就算c3容器出了问题,c1、c2仍然可以通过数据卷进行通信
- c3就被称为数据卷容器
-
示例
-
Step1: 创建并启动名为c3的redis容器
docker run -id --name=c3 -v /volume redis注意:
挂载时并未指定宿主机的挂载目录(即此时宿主机为匿名数据卷),只指定了c3容器的目录,此时系统自动会去创建宿主机对应的挂载目录,如图所示

Name:数据卷名称。由于定义容器未设置容器名,这里的就是匿名卷自动生成的名字,一串hash值。Source:宿主机目录Destination: 容器内的目录
上述配置是将容器内的
/volume这个目录,与数据卷挂载。于是在宿主机中就有了/var/lib/docker/volumes/数据卷名称/_data这个目录。这就是匿名数据卷对应的目录,其使用方式与普通数据卷没有差别。 -
Step2: 创建并启动名为c1的redis容器,然后通过
--volumns-from 数据卷容器名来继承数据卷容器(即c3)docker run -id --name=c1 --volumns-from c3 redis -
Step3: 创建并启动名为c2的redis容器,然后通过
--volumns-from 数据卷容器名来继承数据卷容器(即c3)docker run -id --name=c2 --volumns-from c3 redis
-
挂载本地目录或文件
-
由
容器间数据交换的示例Step1可知数据卷的目录比较深,如果我们去操作数据卷目录会不太方便。所以我们也会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:# 挂载本地目录 -v 本地目录:容器内目录 # 挂载本地文件 -v 本地文件:容器内文件注意:
本地目录或文件必须以
/或./开头,如果直接以名字开头,则会被识别为数据卷名而非本地目录名。如下示例所示-v mysql:/var/lib/mysql:会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷-v ./mysql:/var/lib/mysql:会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录
Docker应用部署
-
从远程仓库拉取镜像的实现步骤
-
搜索对应应用的镜像并拉取应用镜像
注意:若本地有镜像压缩包,则直接将镜像压缩包上传到虚拟机中即可,此时就不需要该步骤了
-
创建容器,并进行端口映射
-
外部机器操作容器中的应用
-
-
外部机器是无法直接操作容器,因为
- 容器是隔离环境,外部容器与容器不互通;但是外部机器与宿主机是互通的,而宿主机又与容器互通,所以可以将宿主机的端口与容器端口进行一个映射,这样外部机器在访问宿主机对应端口时就相当于在访问容器。如图所示

MySQL部署

-
Step1: 查看Docker库是否有MySQL镜像并拉取镜像
docker search register.liberx.info/mysql docker pull mysql -
Step2: 创建mysql目录并进入到该目录下
mkdir ~/mysql cd ~/mysql -
Step3: 创建并运行容器,同时设置端口映射、目录映射等
docker run -id \--name mysql \-p 3307:3306 \-v $PWD/conf:/etc/mysql/conf.d \-v $PWD/logs:/logs \-v $PWD/data:/var/lib/mysql \-v $PWD/init:/docker-entrypoint-initdb.d \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123456 \mysql--name 自定义容器名:自定义容器名-p 宿主机端口:容器内端口:将宿主机的指定端口映射到容器内的指定端口-e KEY=VALUE:配置容器内进程运行时的一些参数(即配置环境变量)。KEY和VALUE都由容器内进程决定TZ=Asia/Shanghai:是设置时区;- M
YSQL_ROOT_PASSWORD=123456:初始化root用户的mysql密码
-v 宿主机目录或文件:容器内目录或文件:配置数据卷-v $PWD/conf:/etc/mysql/conf.d:配置目录挂载-v $PWD/logs:/logs:日志目录挂载-v $PWD/data:/var/lib/mysql:数据目录挂载- 存放MySQL数据库的所有数据文件,包括表的结构、数据、索引等信息
-v $PWD/init:/docker-entrypoint-initdb.d:初始化脚本挂载- MySQL 容器的启动过程中,如果该目录存在 SQL 脚本或其它初始化文件,MySQL 会自动执行这些文件。这通常用于在 MySQL 容器第一次启动时初始化数据库
$PWD代表当前目录(即mysql目录下)
-
Step4: 进入mysql容器内部
docker exec -it mysql /bin/bash -
Step5: 登录mysql
- 输入命令
mysql -uroot -p后输入密码即可登录
- 输入命令
-
步骤如图所示

-
之后就可以在外部机器中来连接该mysql容器并使用(此处以Navicat为例),步骤如图所示
-
Navicat创建连接

-
利用Navicat创建数据库(步骤略)
-
Tomcat部署
-
Step1: 查看Docker库是否有MySQL镜像并拉取镜像
docker search register.liberx.info/tomcat docker pull tomcat -
Step2: 创建mysql目录并进入到该目录下
mkdir ~/tomcat cd ~/tomcat -
Step3: 创建并运行容器,同时设置端口映射、目录映射等
docker run -id \--name tomcat \-p 8080:8080 \-v $PWD:/usr/local/tomcat/webapps \tomcat-v $PWD:/uer/local/tomcat/webapps:将容器当前目录挂载到容器的webapps中
-
Step4: 在Tomcat目录下创建一个test测试目录,并在该目录下创建文件index.html,文件代码如下
<h1>Tomcat访问成功</h1> -
Step5: 外部机器测试是否成功

Nginx部署
-
Step1: 查看Docker库是否有MySQL镜像并拉取镜像
docker search register.liberx.info/nginx docker pull nginx -
Step2: 创建nginx/conf目录并在该目录下创建nginx.conf文件
mkdir ~/nginx cd ~/nginx mkdir conf cd conf vim nginx.conf将以下命令复制到nginx.conf文件中
user nginx; worker_processes 1;error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;#gzip oninclude /etc/nginx/conf.d/*.conf } -
Step3: 返回到nginx目录下创建并运行容器,同时设置端口映射、目录映射等
docker run -id \--name=nginx \-p 80:80 \-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \-v $PWD/logs:/var/log/nginx \-v $PWD/html:/usr/share/nginx/html \nginx-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:配置文件挂载-v $PWD/logs:/var/log/nginx:日志目录挂载-v $PWD/html:/usr/share/nginx/html:静态资源目录挂载
-
Step4: 外部机器测试是否成功

-
配置文件内容解析
# 指定运行nginx 的用户,默认是 nginx 用户 user nginx; # 定义工作进程数,若为auto则表示自动根据 CPU 核心数调整 worker_processes 1; # 定义错误日志文件的位置和日志级别; warn 表示记录警告及更高级别的错误信息 error_log /var/log/nginx/error.log warn; # 定义 Nginx 启动后保存进程 ID 的文件路径,用于管理进程 pid /var/run/nginx.pid;# 事件块 events {# 每个工作进程允许的最大并发连接数worker_connections 1024; } # HTTP块 定义 Web 服务相关配置 http {# 引入外部文件 /etc/nginx/mime.types,定义各种文件的 MIME 类型include /etc/nginx/mime.types;# 设置默认 MIME 类型。当无法识别文件类型时,使用 application/octet-stream,即通用的二进制流default_type application/octet-stream;# 定义日志格式# $remote_addr:客户端 IP 地址# $remote_user:客户端认证的用户名# $time_local:本地时间# $request:客户端请求的完整内容# $status:HTTP 状态码# $body_bytes_sent:发送给客户端的响应体字节数# $http_referer:请求来源(Referer)# $http_user_agent:用户代理信息(如浏览器类型)# $http_x_forwarded_for:代理服务器传递的客户端真实 IP(如果存在)log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';# 指定访问日志的存储位置和日志格式(使用上面定义的 main)access_log /var/log/nginx/access.log main;# 开启高效文件传输sendfile on;# 提高文件传输性能#tcp_nopush on;# 定义 HTTP 长连接的超时时间(秒)。客户端连接超过该时间未发送请求时将断开。keepalive_timeout 65;# 开启HTTP响应的 Gzip 压缩以减少传输数据量#gzip on# 引入 /etc/nginx/conf.d/ 目录下的所有配置文件,支持多个虚拟主机include /etc/nginx/conf.d/*.conf }
Redis部署
-
Step1: 查看Docker库是否有MySQL镜像并拉取镜像
docker search register.liberx.info/redis docker pull redis -
Step2: 创建mysql目录并进入到该目录下
mkdir ~/redis cd ~/redis -
Step3: 创建并运行容器,同时设置端口映射、目录映射等
docker run -id \--name redis \-p 6380:6379 \redis-
若报如下错误则代表宿主机的6379端口号被占用,此时换个宿主机端口号即可
Error starting userland proxy: listen tcp4 0.0.0.0:6379: bind: address already in use.
-
-
Step4: 使用外部机器redis测试是否成功
注意:要进入到windows的redis目录下打开cmd命令窗口输入以下命令进行测试
redis-cli.exe -h 宿主机ip地址 -p nginx容器端口号
Docker自定义镜像
-
自定义镜像主要分为四步:
- 准备Linux运行环境(java项目并不需要完整的操作系统,仅仅是基础运行环境即可)
- 安装并配置JDK
- 拷贝jar包
- 配置启动脚本
上述步骤中的每一次操作其实都是在生产一些文件(系统运行环境、函数库、配置最终都是磁盘文件),所以镜像就是一堆文件的集合。
但需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer(层)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。
例如,第一步中需要的Linux运行环境,通用性就很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像 。然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示:

-
Docker镜像原理

-
用到的方法
命令 说明 文档地址 docker save保存镜像到本地压缩文件 docker save docker load -i 镜像压缩文件加载本地压缩文件到镜像 docker load docker inspect + 容器名查看容器详细信息 docker inspect
利用命名方式制作
- 通过指定容器创建自定义镜像:
docker commit 容器id 自定义镜像名称:自定义版本号 - 将自定义的镜像转为压缩文件:
docker save -o 自定义压缩文件名称 自定义镜像名称:自定义版本号 - 将自定义镜像转为的压缩文件转为另一个镜像:
docker load -i 压缩文件名称
注意:容器转为自定义的镜像后,目录挂载(即数据卷)中的内容不会添加到新的镜像中,若想要其中的内容,则可以在利用自定义的对象创建容器时配置数据卷就可以了
利用Dockerfile制作(自定义镜像)
由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考官方文档
- Dockerfile是一个记录镜像结构的文本文件,包含了一条条指令,每一条指令构建一层基于基础的镜像,最终构建出一个新的镜像
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境
- 对于测试人员:可以直接拿开发时所创建的镜像或者通过Dockerfile文件来创建一个新的镜像开始工作
- 对于运维人员:在部署时,可以实现应用的无缝移植
快速入门
需求:定义Dockerfile,发布SpringBoot项目到Docker容器中
本快速入门项目
DockerFileDemo的具体搭建可完全参考SpringBoot快速入门
-
Step1: 执行Maven构建指令
package来对该SpringBoot项目打包
-
Step2: 将该SpringBoot项目的jar包传到宿主机的root目录下

-
Step3: 利用
mkdir /root/docker-files(等同于mkdir ~/docker-files)命令在root目录下创建项目文件目录docker-files,来存放项目文件(如 JAR 包、Dockerfile 等)- 若命令为
mkdir ./docker-files或mkdir docker-files则必须保证当前所在目录为root目录,因为.表示在当前目录下创建
- 若命令为
-
Step4: 将该jar包移动到
docker-files目录下:mv DockerFileDemo-0.0.1-SNAPSHOT.jar ./docker-files/ -
Step5: 利用
vim ./docker-files/dockerFileDemo在docker-files目录下创建并编写该项目对应的dockerfile文件dockerFileDemo,该文件内容如下:# 指定基础镜像(即父镜像) FROM openjdk:21-jdk # 指明维护者/作者信息 LABEL maintainer="cgrs572 <Your.Name@example.com>" # 将对应jar包复制到即将要创建的镜像的app目录中 COPY DockerFileDemo-0.0.1-SNAPSHOT.jar /app/DockerFiledemo.jar # 指定容器创建时的默认命令 CMD ["java", "-jar", "/app/DockerFiledemo.jar"]- 指定的父镜像若在系统中不存在的话,后续构建自定义镜像时该父镜像也会被下载。只是说此时构建自定义镜像的时间可能会延长,可提前自行利用
docker pull 镜像名:版本号来将父镜像下载到宿主机中
- 指定的父镜像若在系统中不存在的话,后续构建自定义镜像时该父镜像也会被下载。只是说此时构建自定义镜像的时间可能会延长,可提前自行利用
-
Step6: 利用
cd /root/docker-files进入docker-files目录 -
Step7: 利用
docker build -f dockerfile文件路径 -t 自定义镜像名:版本号 对应的dockerfile文件所在目录来构建镜像- 由于博主已进入到docker-files目录,所以最终命令为:
docker build -f ./dockerFileDemo -t dockerfiledemcon .- 最后的
.表示当前路径
- 最后的
- 命令解析
-f:指定dockerfile文件及其路径-t:指定自定义镜像名及其版本号
- 由于博主已进入到docker-files目录,所以最终命令为:
-
Step8: 创建并运行容器
docker run -id -p 9000:8080 dockerfiledemcon -
Step9: 外部机器测试是否运行成功

利用Dockerfile制作(自定义官方镜像)
背景引入
本案例以CentOS7为例
-
Step1: 从远程镜像仓库拉取Centos7到本地:
docker pull centos:7- 若本地有centos7镜像则该步省略
-
Step2: 创建并运行centos容器并进入该容器中
docker run -it --name=c1 centos /bin/bash- 此处的命令可省略
/bin/bash,因为在官方的centos的dockerfile文件中的CMD命令已经指定了容器创建时的默认命令为/bin/bash
- 此处的命令可省略
-
Step3: cd到root目录下,然后执行
vim a.txt命令,最终截图如下
-
在以上示例中就存在问题
- 进入容器后默认进入的工作目录为
/ - 官方提供的centos镜像没有下载vim命令导致该命令不可用
- 因此为了更加方便,我们就可以来自定义镜像
- 进入容器后默认进入的工作目录为
快速入门

-
Step1: 利用
mkdir /root/docker-files(等同于mkdir ~/docker-files)命令在root目录下创建项目文件目录docker-files,来存放项目文件(如 JAR 包、Dockerfile 等)- 若命令为
mkdir ./docker-files或mkdir docker-files则必须保证当前所在目录为root目录,因为.表示在当前目录下创建
注意:由于在子当以镜像的示例中已创建该目录,所以该示例截图中不存在该步骤的命令
- 若命令为
-
Step2: 利用
vim ./docker-files/centosdockerFile在docker-files目录下创建并编写该项目对应的dockerfile文件centosdockerFile,该文件内容如下:# 指定基础镜像(即父镜像) FROM centos:7 # 指明维护者/作者信息 LABEL maintainer="cgrs572 <Your.Name@example.com>" # 指定在构建自定义镜像过程中执行的命令(即 利用RUN安装vim到自定义镜像中) RUN yum install -y vim # 设置后续指令的工作目录(即利用`WORKDIR`指定默认工作目录) WORKDIR /usr # 指定容器创建时的默认命令 CMD ["/bin/bash"]-
指定的父镜像若在系统中不存在的话,后续构建自定义镜像时该父镜像也会被下载。只是说此时构建自定义镜像的时间可能会延长,可提前自行利用
docker pull 镜像名:版本号来将父镜像下载到宿主机中 -
注意:若在构建自定义镜像源过程中yum无法下载则需要更换centos镜像的镜像源,此时dockerfile文件代码如下
# 指定基础镜像(即父镜像) FROM centos:7 # 指明维护者/作者信息 LABEL maintainer="cgrs572 <Your.Name@example.com>" # 更换yum 镜像源保证yum可以正常工作 RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && yum install -y vim # 指定在构建自定义镜像过程中执行的命令(即 利用RUN安装vim到自定义镜像中) RUN yum install -y vim # 设置后续指令的工作目录(即利用`WORKDIR`指定默认工作目录) WORKDIR /usr # 指定容器创建时的默认命令 CMD ["/bin/bash"]
-
-
Step3: 利用
cd /root/docker-files进入docker-files目录 -
Step4: 利用
docker build -f dockerfile文件路径 -t 自定义镜像名:版本号 对应的dockerfile文件所在目录来构建镜像- 由于博主已进入到docker-files目录,所以最终命令为:
docker build -f ./centosdockerFile -t centosdockerfile .- 最后的
.表示当前路径
- 最后的

- 由于博主已进入到docker-files目录,所以最终命令为:
-
Step5: 创建并运行容器
docker run -id -p 9000:8080 centosdockerfile,然后测试是否运行成功- 此时进容器后默认的工作目录为/usr
- 使用vim测试并未报错

DockerFile常用关键字
| Dockerfile 指令 | 解释 |
|---|---|
FROM | 指定基础镜像(即父镜像),用于后续的指令构建。即指定Dockerfile是基于哪个image构建的 |
MAINTAINER | 指明Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令) |
LABEL | 添加镜像的元数据,使用键值对的形式。 |
RUN | 指定在构建自定义镜像过程中执行的命令。 |
CMD | 指定容器创建时的默认命令。(可以被docker run时指定的命令覆盖) |
ENTRYPOINT | 设置容器创建时的主要命令。(不可被docker run时指定的命令覆盖) |
EXPOSE | 声明容器运行时监听的特定网络端口。 |
ENV | 在容器内部设置环境变量。 |
ADD | 将文件、目录或远程URL添加到镜像中。 |
COPY | 将文件或目录复制到镜像中。 |
VOLUME | 为容器创建挂载点或声明卷。 |
WORKDIR | 设置后续指令的工作目录。 |
USER | 指定后续指令的用户上下文。 |
ARG | 定义在构建过程中传递给构建器的变量,可使用 “docker build” 命令设置。 |
ONBUILD | 当该镜像被用作另一个构建过程的基础时,添加触发器。 |
STOPSIGNAL | 设置发送给容器以退出的系统调用信号。 |
HEALTHCHECK | 定义周期性检查容器健康状态的命令。 |
SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。 |
网络
背景引入
容器间互相访问方式步骤如下:
以MySQL镜像与自定义centos镜像为例
-
Step1:创建并运行项目MySQL镜像对应的容器以及自定义centos7镜像对应的容器(步骤略)
-
创建完成后使用
docker ps -a指令查看容器是否创建成功- MySQL镜像对应的容器名为mysql
- 自定义centos7镜像对应的容器名为centos01

-
-
Step2:使用
docker inspect 容器名指令来查看容器mysql的Networks.bridge.IPAddress属性(即ip地址)-
也可使用
format来过来结果直接得出ip地址:docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' 容器名 -
容器mysql的ip地址为172.17.0.2,如图所示

-
-
Step3:进入容器centos01中,利用
ping 172.17.0.2检测是否能够访问容器mysql注意:若该容器未启动则需要先利用
docker start 容器名/id将其启动,然后利用docker exec -it 容器id/容器名 /bin/bash进入
有图可知,只要知道对应容器的ip地址就可以实现容器间的互相访问
快速入门
由背景引入可知只要知道对应容器的ip地址就可以实现容器间的互相访问
但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时MySQL容器的IP发生变化,这就会导致连接会失败,所以通过ip地址来访问还是不可靠,所以就有了网络,步骤如下
-
Step1: 利用
docker network create 自定义网络名创建一个网络,博主创建的网络名为webb -
Step2: 利用
docker network ls查看所有网络,判断是否对应网络是否创建成功 -
Step3: 利用
docker network connect 容器要加入的网络名 要加入的容器 --alias 自定义容器别名来将mysql容器和centos01容器均加入创建的网络webb中 -
Step4: 进入容器centos01中,利用
ping 容器名或容器对应的别名检测是否能够访问容器mysql
网络相关命令
| 命令 | 说明 | 文档地址 |
|---|---|---|
| docker network create | 创建一个网络 | docker network create |
| docker network ls | 查看所有网络 | docs.docker.com |
| docker network rm | 删除指定网络 | docs.docker.com |
| docker network prune | 清除未使用的网络 | docs.docker.com |
| docker network connect | 使指定容器连接加入某网络 | docs.docker.com |
| docker network disconnect | 使指定容器连接离开某网络 | docker network disconnect |
| docker network inspect | 查看网络详细信息 | docker network inspect |
Docker Compose
我们部署一个简单的java项目,至少包含3个容器:
- MySQL
- Nginx
- Java项目
而稍微复杂的项目,其中还会有各种各样的其它中间件,需要部署的东西远不止3个。如果还像之前那样手动的逐一部署,就太麻烦了。
而Docker Compose就可以帮助我们实现多个相互关联的Docker容器的快速部署。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器。
- Docker Compose是一个编排多容器分布式部署的工具,提供命令集来管理容器化应用的完整开发周期,包括服务构建、启动和停止
- 使用步骤
- 利用Dockerfile定义运行环境镜像
- 使用docker-compose.yml定义组成应用的各个服务
- 运行
docker-compose up启动应用
Docker Compose安装
二进制包离线安装(推荐)
-
Step1:去Github下载对应版本的二进制文件

-
Step2:利用
cd /usr/local/bin进入到/usr/local/bin目录下,然后将二进制文件直接上传到该目录下
-
Step3:利用
mv oldName newName将文件docker-compose-linux-x86_64重命名为docker-composemv docker-compose-linux-x86_64 docker-compose -
Step4:添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose -
Step5:验证是否安装成功
docker-compose --version
-
卸载时,直接删除对应的二进制包即可
快速入门
需求:使用DockerCompose编排nginx+springboot项目
本示例以Docker自定义镜像的springboot项目为基准。在Docker自定义镜像中,已经构建了自定义了springboot项目对象的镜像,如图所示

-
Step1: 将对应的官方镜像从docker仓库拉取下来:
docker pull 镜像名:版本号 -
Step2: 自定义项目的镜像(本步骤略,可详见自定镜像的部分内容示例)
-
Step3: 利用
mkdir /root/docker-compose(等同于mkdir ~/docker-files)命令在root目录下创建项目文件目录docker-compose,来存放项目文件(如 JAR 包、Dockerfile 等)- 若命令为
mkdir ./docker-compose或mkdir docker-compose则必须保证当前所在目录为root目录,因为.表示在当前目录下创建
- 若命令为
-
Step4: 利用
cd docker-compose进入到docker-compose目录下,然后利用vim docker-compose.yml创建dockercompose文件docker-compose.yml,该文件代码如下# 指定dockercompose文件格式的版本 version: '3.8' # 定义服务 services:# 定义服务1:nagix服务---自定义服务名即可nginx:# image: 镜像名:版本号image: nginx# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- 80:80# 将指定服务链接到本服务中,后期在该服务创建的容器中可直接通过指定服务名来访问指定服务links:- app# 将本地目录或文件挂载到容器内的目录或文件volumes:- ./nginx/conf.d:/etc/nginx/conf.d# 定义服务2:app服务---自定义服务名即可app:# image: 镜像名:版本号image: dockerfiledemcon# 指定该服务对应的容器内部暴露的端口expose:- "8080"- 在dockercompose新版本中
version已被舍弃,不过最好还是加上 - 在dockercompose新版本中
links已被舍弃,先版本可以通过服务名称直接访问其他服务,而不需要显式地使用links,所以可删除
最终文件代码如下:
# 指定dockercompose文件格式的版本 version: '3.8' # 定义服务 services:# 定义服务1:nagix服务---自定义服务名即可nginx:# image: 镜像名:版本号image: nginx# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- 80:80# 将本地目录或文件挂载到容器内的目录或文件volumes:- ./nginx/conf.d:/etc/nginx/conf.d# 定义服务2:app服务---自定义服务名即可app:# image: 镜像名:版本号image: dockerfiledemcon# 自定义该服务创建的容器名称container_name: appcon# 在同一网络下暴露该服务对应的容器端口expose:- "8080" - 在dockercompose新版本中
-
Step5: 创建挂载的本地目录或文件
mkdir -p ./nginx/conf.d-p用来创建目录及其子目录
-
Step6: 利用
cd ./nginx/conf.d进入到conf.d目录下并在该目录下用vim nginx.conf创建并编写nginx配置文件nginx.conf文件,该文件代码如下解释:当服务器监听到 80 端口的请求时,
nginx会自动将请求转发到app服务的 8080 端口此时
nginx会充当一个反向代理服务器,将客户端的请求转发给后端服务(app服务)处理server {# 指定nginx服务器监听的端口listen 80;# 关闭访问日志记录access_log off;# 定义一个位置块,处理所有以/开头的请求location / {# 将请求代理到名为app服务的8080端口proxy_pass http://app:8080;} } -
Step7: 在~/docker-compose目录下使用
docker-compose up命令启动容器- 该命令若为
docker-compose up -d则代表后台启动

- 该命令若为
-
Step8: 测试访问,运行成功

注意
-
在使用Docker Compose来实现多个相互关联的Docker容器的快速部署时, 若不定义并指定网络,则Docker Compose会自动创建一个默认网络,以此来实现不同服务对应的容器均在同一个默认网络下,并能够通过服务名互相访问
-
在以上快速入门中就属于未定义并指定网络,此时Docker Compose会创建一个默认的网络,如图所示

-
在Docker Compose基本语法中的两个示例属于定义并指定网络
-
-
expose:在同一网络下暴露该服务对应的容器端口- 此时如果我在外部利用
docker run -id -p 9000:8080 dockerfiledemcon命令创建了一个app服务所使用的镜像的容器,并将宿主机的9000端口映射到容器的8000端口上,则:docker run -p 9000:8080这条命令是将 宿主机的 9000 端口 映射到 容器的 8080 端口。这意味着外部世界(例如,浏览器或者其他客户端)通过宿主机的 9000 端口可以访问到容器的 8080 端口expose是告诉 Docker 仅在容器网络中暴露端口 ,并不进行宿主机与容器之间的端口映射。expose只是让其他同网络中的容器可以访问到暴露的端口。它并不会将容器的端口映射到宿主机的端口- 所以它们是互不干扰,互不影响的。但是假设产生了影响则在app服务中利用
container_name指明该服务所创建的容器名称即可
- 此时如果我在外部利用
Docker Compose基本语法
-
docker run参数对应的docker compose指令
docker run 参数 docker compose 指令 说明 --namecontainer_name指定容器名称 -pports端口映射 -eenvironment环境变量 -vvolumes数据卷配置 --networknetworks网络 -
其它docker compose指令
docker compose 指令 说明 build指定该服务的镜像是通过 Dockerfile 文件进行构建的 context指定 Dockerfile文件及利用该文件构建镜像所需的其他文件所在的位置 dockerfile指定要构建的镜像所对应的dockerfile文件名称。如果未指定,则会默认查找名为 Dockerfile的文件image指定服务要使用的镜像名称及版本号(版本号可省略) depends_on指定服务之间的启动顺序,指定的服务会在当前服务启动之前启动 expose在同一网络下暴露该服务对应的容器端口 -
build- 若要使用的自定义镜像不存在且无法从官方仓库拉取,则指定该服务的镜像是通过 Dockerfile 文件进行构建的。此时Docker Compose会自动根据Dockerfile文件来创建自定义镜像
示例1
此处以网络中的示例为例,将MySQL镜像容器加入到自定义的网络webb中
-
创建并运行MySQ镜像的容器代码如下:
- 当使用docker run时,容器要加入的网络必须是已存在的;若不存在则需要提前创建好对应的网络。
- 此处假设自定义的webb网络已创建,具体过程可详见网络部分内容
docker run -id \--name mysql \-p 3307:3306 \-v $PWD/conf:/etc/mysql/conf.d \-v $PWD/logs:/logs \-v $PWD/data:/var/lin/mysql \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123456 \--network webbmysql -
如果用
docker-compose.yml文件来定义,就是这样:-
此处假设webb网络在外部不存在,则文件代码如下:
与
docker run命令不同的是:在Docker Compose文件中的网络可以不存在,因为Docker Compose会自动创建对应的网路(前提是该网络并未指定在外部存在)。# 指定dockercompose文件格式的版本 version: "3.8" # 定义服务 services:# 定义服务1:nagix服务---自定义服务名即可mysql:# image: 镜像名:版本号image: mysql# 自定义该服务创建的容器名称container_name: mysql# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- "3306:3306"# 配置容器内的进程运行时的参数(即配置环境变量)environment:# 设置时区TZ: Asia/Shanghai# 设置root用户的登录密码MYSQL_ROOT_PASSWORD: 123# 将本地目录或文件挂载到容器内的目录或文件volumes:- "./mysql/conf:/etc/mysql/conf.d"- "./mysql/data:/var/lib/mysql"# 该服务创建的容器加入到指定的网络中networks:# 要加入的网络的别名- newwebb # 定义网络 networks:# 定义网络别名newwebb:# 定义网络名称name: webb -
此处假设webb网络在外部存在,则文件代码如下:
注意:若假设在外部存在的webb网络其实在外部是不存在的,此时Docker Compose就不会自动创建对应网络,需手动创建(具体过程可详见网络部分内容)
-
网络别名与外部网络的实际名称不一致
# 指定dockercompose文件格式的版本 version: "3.8" # 定义服务 services:# 定义服务1:nagix服务---自定义服务名即可mysql:# image: 镜像名:版本号image: mysql# 自定义该服务创建的容器名称container_name: mysql# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- "3306:3306"# 配置容器内的进程运行时的参数(即配置环境变量)environment:# 设置时区TZ: Asia/Shanghai# 设置root用户的登录密码MYSQL_ROOT_PASSWORD: 123# 将本地目录或文件挂载到容器内的目录或文件volumes:- "./mysql/conf:/etc/mysql/conf.d"- "./mysql/data:/var/lib/mysql"# 该服务创建的容器加入到指定的网络中networks:# 要加入的网络的别名- newwebb # 定义网络 networks:# 定义网络别名newwebb:# 指定外部已存在的网络external:# 已存在的网络名称name: webb -
网络别名与外部网络的实际名称一致
# 指定dockercompose文件格式的版本 version: "3.8" # 定义服务 services:# 定义服务1:nagix服务---自定义服务名即可mysql:# image: 镜像名:版本号image: mysql# 自定义该服务创建的容器名称container_name: mysql# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- "3306:3306"# 配置容器内的进程运行时的参数(即配置环境变量)environment:# 设置时区TZ: Asia/Shanghai# 设置root用户的登录密码MYSQL_ROOT_PASSWORD: 123# 将本地目录或文件挂载到容器内的目录或文件volumes:- "./mysql/conf:/etc/mysql/conf.d"- "./mysql/data:/var/lib/mysql"# 该服务创建的容器加入到指定的网络中networks:# 要加入的网络的别名- newwebb # 定义网络 networks:# 定义网络别名webb:# 指定该网络在外部已存在external: true
-
-
示例2
黑马商城部署文件
# 指定dockercompose文件格式的版本
version: "3.8"
# 定义服务
services:# 定义服务1:mysql服务---自定义服务名即可mysql:# image: 镜像名:版本号image: mysql# 自定义该服务创建的容器名称container_name: mysql# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- "3306:3306"# 配置容器内的进程运行时的参数(即配置环境变量)environment:# 设置时区TZ: Asia/Shanghai# 设置root用户的登录密码MYSQL_ROOT_PASSWORD: 123# 将本地目录或文件挂载到容器内的目录或文件volumes:- "./mysql/conf:/etc/mysql/conf.d"- "./mysql/data:/var/lib/mysql"- "./mysql/init:/docker-entrypoint-initdb.d"# 该服务创建的容器加入到指定的网络中networks:# 要加入的网络的别名- hm-net# 定义服务2:hmall服务---自定义服务名即可hmall:# 指定该服务的镜像是通过 Dockerfile 文件进行构建的build: # 指定构建镜像所需的所有文件所在位置context: .# 指定Dockerfile文件名称,若未指定则默认为Dockerfiledockerfile: Dockerfile# 自定义该服务创建的容器名称container_name: hmall# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- "8080:8080"# 该服务创建的容器加入到指定的网络中networks:- hm-net# 指定服务之间的启动顺序,指定的mysql服务会在当前hmall服务启动之前启动depends_on:- mysql# 定义服务3:nginx服务---自定义服务名即可nginx:# image: 镜像名:版本号image: nginx# 自定义该服务创建的容器名称container_name: nginx# 主机端口:容器端口 将主机端口映射到容器对应端口ports:- "18080:18080"- "18081:18081"# 将本地目录或文件挂载到容器内的目录或文件volumes:- "./nginx/nginx.conf:/etc/nginx/nginx.conf"- "./nginx/html:/usr/share/nginx/html"# 指定服务之间的启动顺序,指定的mysql服务会在当前hmall服务启动之前启动depends_on:- hmall# 该服务创建的容器加入到指定的网络中networks:- hm-net# 定义网络
networks:# 定义网络别名hm-net:# 定义网络名称name: hmall
Docker Compose基本命令
-
docker compose [OPTIONS] [COMMAND]类型 参数或指令 说明 Options -f指定compose文件的路径和名称 Options -p指定project名称。project就是当前compose文件中设置的多个service的集合,是逻辑概念 Commands up创建并启动所有service容器 Commands down停止并移除所有容器、网络 Commands ps列出所有启动的容器 Commands logs查看指定容器的日志 Commands stop停止容器 Commands start启动容器 Commands restart重启容器 Commands top查看运行的进程 Commands exec在指定的运行中容器中执行命令
Docker私有仓库
Docker官方的Docker hub是一个用于管理公共镜像的仓库,我们可以从上面拉取镜像到本地,也可以把自己的镜像推送上去。但是有时候我们的服务器无法访问互联网,或者不希望将自己的镜像放到公网当中,这就需要搭建自己的私有仓库来存储和管理自己的镜像了
搭建私有仓库
-
Step1: 从Docker Hub拉取私有仓库
registry:docker pull registry -
Step2: 创建并启动私有仓库容器:
docker run -id --name=registry -p 5000:5000 registry -
Step3: 浏览器输入
私有仓库的ip地址:映射的端口号/v2/_catalog测试是否成功{"repositories":[]}表示私有仓库,由于现在并未向私有仓库推送镜像,所以为空

-
Step4: 修改/ect/docker目录下的daemon.json文件:
vim /etc/docker/daemon.jsonetc目录与root目录同级,所以直接
/etc即可- 在deamon.json文件中添加私有仓库服务器的ip以及端口号:
{"insecure-registries":["私有仓库服务器ip:端口号"]}—以此来让Docker信任该私有仓库
{"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["https://st5sw75p.mirrorcgrs572.aliyuncs.com","https://docker.registry.cyou","https://docker-cf.registry.cyou","https://dockercf.jsdelivr.fyi","https://docker.jsdelivr.fyi","https://dockertest.jsdelivr.fyi","https://mirror.aliyuncs.com","https://dockerproxy.com","https://mirror.baidubce.com","https://docker.m.daocloud.io","https://docker.nju.edu.cn","https://docker.mirrors.sjtug.sjtu.edu.cn","https://docker.mirrors.ustc.edu.cn","https://mirror.iscas.ac.cn","https://docker.rainbond.cc"],"insecure-registries": ["192.168.10.131:5000"] } - 在deamon.json文件中添加私有仓库服务器的ip以及端口号:
-
Step5: 重启Docker服务:
systemctl restart docker -
Step6: 启动私有仓库容器:
docker start registry
上传镜像到私有仓库
以CentOS7镜像为例
-
Step1: 将镜像标记为私有仓库的镜像:
docker tag 镜像名:镜像版本号 私有仓库服务器ip:5000/镜像名:镜像版本号 -
Step2: 上传标记的镜像到私有仓库:
docker push 私有仓库服务器ip:5000/镜像名:镜像版本号 -
Step3: 浏览器输入
私有仓库的ip地址:映射的端口号/v2/_catalog测试是否成功
-
注意:
-
为方便后续私有仓库拉取镜像,所以此处会将本地centos7私有镜像删除
- 此时centos7私有镜像的id与centos7镜像的id一样,所以要想删除centos7私有镜像则必须为:
docker rmi 私有镜像名:版本号—版本号不可省略,如下所示
docker rmi 192.168.10.131:5000/centos:7 - 此时centos7私有镜像的id与centos7镜像的id一样,所以要想删除centos7私有镜像则必须为:
-
私有仓库拉取镜像
-
直接使用
docker pull 私有仓库服务器ip:5000/镜像名:镜像版本号
相关文章:
Docker完整技术汇总
Docker 背景引入 在实际开发过程中有三个环境,分别是:开发环境、测试环境以及生产环境,假设开发环境中开发人员用的是jdk8,而在测试环境中测试人员用的时jdk7,这就导致程序员开发完系统后将其打成jar包发给测试人员后…...
在JavaScript文件中定义方法和数据(不是在对象里定以数据和方法,不要搞错了)
在对象里定以数据和方法看这一篇 对象字面量内定义属性和方法(什么使用const等关键字,什么时候用键值对)-CSDN博客https://blog.csdn.net/m0_62961212/article/details/144788665 下是在JavaScript文件中定义方法和数据的基本方式ÿ…...
python爬虫爬抖音小店商品数据+数据可视化
爬虫代码 爬虫代码是我调用的数据接口,可能会过一段时间用不了,欢迎大家留言评论,我会不定时更新 import requests import time cookies {token: 5549EB98B15E411DA0BD05935C0F225F,tfstk: g1vopsc0sQ5SwD8TyEWSTmONZ3cA2u6CReedJ9QEgZ7byz…...
关于 覆铜与导线之间间距较小需要增加间距 的解决方法
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/144776995 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
uniapp中Nvue白屏问题 ReferenceError: require is not defined
uniapp控制台输出如下 exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught ReferenceError: require is not defined 或者 exception function:createInstanceContext, exception:white s…...
在 Windows 上,如果忘记了 MySQL 密码 重置密码
在 Windows 上,如果忘记了 MySQL 密码,可以通过以下方法重置密码: 方法 1:以跳过权限验证模式启动 MySQL 并重置密码 停止 MySQL 服务: 打开 命令提示符 或 PowerShell,输入以下命令停止 MySQL 服务&#…...
《PyTorch:从基础概念到实战应用》
《PyTorch:从基础概念到实战应用》 一、PyTorch 初印象二、PyTorch 之历史溯源三、PyTorch 核心优势尽显(一)简洁高效,契合思维(二)易于上手,调试便捷(三)社区繁荣&#…...
前端:改变鼠标点击物体的颜色
需求: 需要改变图片中某一物体的颜色,该物体是纯色; 鼠标点击哪个物体,哪个物体的颜色变为指定的颜色,利用canvas实现。 演示案例 代码Demo <!DOCTYPE html> <html lang"en"><head>&l…...
Java-33 深入浅出 Spring - FactoryBean 和 BeanFactory BeanPostProcessor
点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatisÿ…...
HTML4笔记
尚硅谷 一、前序知识 1.认识两位先驱 2.计算机基础知识 3.C/S架构与B/S架构 4.浏览器相关知识 5.网页相关概念 二、HTML简介 1.什么是HTML? 2.相关国际组织(了解) 3.HTML发展历史(了解)** 三、准备工作 1.常用电脑设置 2.安装Chrome浏览器 四、HTML入门 1.HTML初体验 2.H…...
python报错ModuleNotFoundError: No module named ‘visdom‘
在用虚拟环境跑深度学习代码时,新建的环境一般会缺少一些库,而一般解决的方法就是直接conda install,但是我在conda install visdom之后,安装是没有任何报错的,conda list里面也有visdom的信息,但是再运行代…...
linux-21 目录管理(一)mkdir命令,创建空目录
对linux而言,对一个系统管理来讲,最关键的还是文件管理。那所以我们接下来就来看看如何实现文件管理。当然,在文件管理之前,我们说过,文件通常都放在目录下,对吧?所以先了解目录,可能…...
总结-常见缓存替换算法
缓存替换算法 1. 总结 1. 总结 常见的缓存替换算法除了FIFO、LRU和LFU还有下面几种: 算法优点缺点适用场景FIFO简单实现可能移除重要数据嵌入式系统,简单场景LRU局部性原理良好维护成本高,占用更多存储空间内存管理,浏览器缓存L…...
【Vue】如何在 Vue 3 中使用组合式 API 与 Vuex 进行状态管理的详细教程
如何在 Vue 3 中使用组合式 API 与 Vuex 进行状态管理的详细教程。 安装 Vuex 首先,在你的 Vue 3 项目中安装 Vuex。可以使用 npm 或 yarn: npm install vuexnext --save # or yarn add vuexnext创建 Store 在 Vue 3 中,你可以使用 creat…...
VSCode 插件开发实战(十五):如何支持多语言
前言 在软件开发中,多语言支持(i18n)是一个非常重要的功能。无论是桌面应用、移动应用,还是浏览器插件,都需要考虑如何支持不同国家和地区的用户,软件应用的多语言支持(i18n)已经成…...
面试241228
面试可参考 1、cas的概念 2、AQS的概念 3、redis的数据结构 使用场景 不熟 4、redis list 扩容流程 5、dubbo 怎么进行服务注册和调用,6、dubbo 预热 7如何解决cos上传的安全问题kafka的高并发高吞吐的原因ES倒排索引的原理 spring的 bean的 二级缓存和三级缓存 spr…...
Python数据序列化模块pickle使用
pickle 是 Python 的一个标准库模块,它实现了基本的对象序列化和反序列化。序列化是指将对象转换为字节流的过程,这样对象就可以被保存到文件中或通过网络传输。反序列化是指从字节流中恢复对象的过程。 以下是 pickle 模块的基本使用方法: …...
Spring Boot对访问密钥加解密——HMAC-SHA256
HMAC-SHA256 简介 HMAC-SHA256 是一种基于 哈希函数 的消息认证码(Message Authentication Code, MAC),它结合了哈希算法(如 SHA-256)和一个密钥,用于验证消息的完整性和真实性。 HMAC 是 “Hash-based M…...
HTML 元素:网页构建的基础
HTML 元素:网页构建的基础 HTML(HyperText Markup Language,超文本标记语言)是构建网页的基石。它定义了网页的结构和内容,而HTML元素则是构成HTML文档的基石。在本篇文章中,我们将深入探讨HTML元素的概念、类型、用法,以及如何在网页设计中有效地使用它们。 什么是HT…...
HEIC 是什么图片格式?如何把 iPhone 中的 HEIC 转为 JPG?
在 iPhone 拍摄照片时,默认的图片格式为 HEIC。虽然 HEIC 格式具有高压缩比、高画质等优点,但在某些设备或软件上可能存在兼容性问题。因此,将 HEIC 格式转换为更为通用的 JPG 格式就显得很有必要。本教程将介绍如何使用简鹿格式工厂…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
