Docker入门
Docker
1.基本操作
登录docker hub
1 | docker login |
使用 docker tag
命令给本地镜像打标签
1 | docker tag demo-docker:1.0 lypsdocker/teacherspringboot1:1.0 |
这里,demo-docker:1.0
是你本地镜像的名字和标签,lypsdocker/teacherspringboot1:1.0
是你想要推送到 Docker Hub 的用户名、仓库名和标签。
使用 docker push
命令推送镜像到 Docker Hub
1 | docker push lypsdocker/teacherspringboot1:1.0 |
查看正在运行的容器
1 | docker ps |
查看所有容器(包括已停止的)
1 | docker ps -a |
停止容器
1 | docker stop demo-docker |
这将停止名为demo-docker
的容器.
启动容器(如果之前已经停止)
1 | docker start demo-docker |
删除容器
1 | docker rm demo-docker |
进入容器内部
1 | docker exec -it demo-docker /bin/bash |
2.创建镜像和容器并上传到Docker hub
3.从Docker bub 上拉取镜像并创建容器并运行
拉取镜像
1 | docker pull lypsdocker/teacherspringboot1:1.0 |
你的Docker Hub用户名是lypsdocker
,并且你要拉取的镜像名称是demo-docker
,标签是1.0
运行docker容器
1 | docker run -d --name my-springboot-app -p 9090:9090 lypsdocker/teacherspringboot1:1.0 |
1 | docker run -d --name my-container-name my-app |
-d
:在“分离”模式下运行容器,这意味着容器将在后台运行,并返回容器ID。--name my-container-name
:给容器指定一个名称,这样你可以更容易地引用它。-p
或--publish
:将容器的端口映射到宿主机的端口。例如,-p 8080:80
会将容器内的80端口映射到宿主机的8080端口。-v
或--volume
:挂载宿主机的目录或文件到容器内。例如,-v /host/path:/container/path
会将宿主机的/host/path
目录挂载到容器的/container/path
目录。--env
或-e
:设置环境变量。例如,-e "VAR_NAME=value"
会在容器内设置一个名为VAR_NAME
的环境变量,其值为value
。--network
:指定容器使用的网络。--restart
:设置容器的重启策略。例如,--restart=always
会使容器在退出时总是重新启动。
数据卷
是一个虚拟目录,是容器内目录和宿主机目录之间双向映射的桥梁
数据卷操作命令
本地目录挂载
在执行docvker run命令时,使用 -v 本地目录:容器内目录 可以完成本地目录挂载
本地目录必须以“/” 或”./“开头,如果直接以名称开头,会被识别为数据卷而非本地目录
Dockerfile语法
一个文本文件,其中包含一个个指令,用指令来执行上面操作来构建镜像。
构建镜像
1 | # 进入镜像目录 |
docker build
: 就是构建一个docker镜像-t docker-demo:1.0
:-t
参数是指定镜像的名称(repository
和tag
).
: 最后的点是指构建时Dockerfile所在路径,由于我们进入了demo目录,所以指定的是.
代表当前目录,也可以直接指定Dockerfile目录:# 直接指定Dockerfile目录 docker build -t docker-demo:1.0 /root/demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
我们的容器之间能否互相访问呢?测试一下
首先,我们查看下MySQL容器的详细信息,重点关注其中的网络IP地址:
```Bash
# 1.用基本命令,寻找Networks.bridge.IPAddress属性
docker inspect mysql
# 也可以使用format过滤结果
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql
# 得到IP地址如下:
172.17.0.2
# 2.然后通过命令进入dd容器
docker exec -it dd bash
# 3.在容器内,通过ping命令测试网络
ping 172.17.0.2
# 结果
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.058 ms
发现可以互联,没有问题。
但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。
所以,我们必须借助于docker的网络功能来解决这个问题,官方文档:
https://docs.docker.com/engine/reference/commandline/network/
常见命令有:
命令 | 说明 | 文档地址 |
---|---|---|
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 |
演示:
1 | # 1.首先通过命令创建一个网络 |
现在无需记住IP地址也可以实现容器互联了。
总结:
- 在自定义网络中,可以给容器起多个别名,默认的别名是容器名本身
- 在同一个自定义网络中的容器,可以通过别名互相访问
部署java项目
部署后端
现在我们以部署黑马的hmall项目为例
我们要部署的就是其中的hm-service
,其中的配置文件采用了多环境的方式:
其中的application-dev.yaml
是部署到开发环境的配置,application-local.yaml
是本地运行时的配置。
在dev开发环境(也就是Docker部署时)采用了mysql作为地址,刚好是我们的mysql容器名,只要两者在一个网络,就一定能互相访问。
将项目打为jar包
将
hm-service
目录下的Dockerfile
和hm-service/target
目录下的hm-service.jar
一起上传到虚拟机的root
目录:部署项目
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 1.构建项目镜像,不指定tag,则默认为latest
docker build -t hmall .
# 2.查看镜像
docker images
# 结果
REPOSITORY TAG IMAGE ID CREATED SIZE
hmall latest 0bb07b2c34b9 43 seconds ago 362MB
docker-demo 1.0 49743484da68 24 hours ago 327MB
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB
# 3.创建并运行容器,并通过--network将其加入hmall网络,这样才能通过容器名访问mysql
docker run -d --name hmall --network hmall -p 8080:8080 hmall测试,通过浏览器访问:http://你的虚拟机地址:8080/search/list
部署前端
hmall-portal
和hmall-admin
是前端代码,需要基于nginx部署。在课前资料中已经给大家提供了nginx的部署目录
其中:
html
是静态资源目录,我们需要把hmall-portal
以及hmall-admin
都复制进去nginx.conf
是nginx的配置文件,主要是完成对html
下的两个静态资源目录做代理
我们现在要做的就是把整个nginx目录上传到虚拟机的/root
目录下:
然后创建nginx容器并完成两个挂载:
- 把
/root/nginx/nginx.conf
挂载到/etc/nginx/ng``inx.conf
- 把
/root/nginx/html
挂载到/usr/share/nginx/html
由于需要让nginx同时代理hmall-portal和hmall-admin两套前端资源,因此我们需要暴露两个端口:
- 18080:对应hmall-portal
- 18081:对应hmall-admin
命令如下:
1 | docker run -d \ |
测试,通过浏览器访问:http://你的虚拟机ip:18080
DockerCompose
Docker Compose就可以帮助我们实现多个相互关联的Docker容器的快速部署。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器。
基本语法
docker-compose.yml文件的基本语法可以参考官方文档
docker-compose文件中可以定义多个相互关联的应用容器,每一个应用容器被称为一个服务(service)。由于service就是在定义某个应用的运行时参数,因此与docker run
参数非常相似。
举例来说,用docker run部署MySQL的命令如下:
1 | docker run -d \ |
如果用docker-compose.yml
文件来定义,就是这样:
1 | version: "3.8" |
那么黑马商城部署文件:
1 | version: "3.8" |
基础命令
编写好docker-compose.yml文件,就可以部署项目了
1 | docker compose [OPTIONS] [COMMAND] |
其中,OPTIONS和COMMAND都是可选参数,比较常见的有:
类型 | 参数或指令 | 说明 |
---|---|---|
Options | -f | 指定compose文件的路径和名称 |
-p | 指定project名称。project就是当前compose文件中设置的多个service的集合,是逻辑概念 | 指定project名称。project就是当前compose文件中设置的多个service的集合,是逻辑概念 |
Commands | up | 创建并启动所有service容器创建并启动所有service容器 |
down | 停止并移除所有容器、网络 | 停止并移除所有容器、网络 |
ps | 列出所有启动的容器 | 列出所有启动的容器 |
logs | 查看指定容器的日志 | 查看指定容器的日志 |
stop | 停止容器 | 停止容器 |
start | 启动容器 | 启动容器 |
restart | 重启容器 | 重启容器 |
top | 查看运行的进程 | 查看运行的进程 |
exec | 在指定的运行中容器中执行命令 | 在指定的运行中容器中执行命令 |