Docker的安装 Mac brew installl docker安装Docker Desktop
打开docker图形界面->settings->Docker Engine->添加阿里云镜像
示例:部署MySQL 1 2 3 4 5 6 docker run -d \ --name mysql \ -p 3307 :3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=123 \ mysql
-d
:让容器在后台运行
--name
:给容器起个名字
-p 3306:3306
:端口映射 宿主机端口:容器端口【连接要连接宿主机端口】
-e
:环境变量:KEY=VALUEE 来设置环境变量
mysql:5.7
:指定运行的镜像的名字:版本
docker run是一条龙服务,会先检查本地镜像是否存在,然后拉取,然后创建容器
常见命令
docker pull
:从镜像仓库拉取镜像到本地
docker build
:创建自定义镜像
docker push
:把镜像推到镜像仓库
docker images
:查看本地镜像
docker rmi
:删除本地镜像
docker run
:创建并运行容器
docker stop
:停止容器(并不会删除容器,只是停止镜像线程)
docker start
:启动容器
docker ps
:查看当前容器的运行状态
1 2 3 4 5 docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}" dps
docker ps -a
:查看当前所有所有容器,包括stop的容器
docker rm
:删除容器
docker logs
:查看容器运行的日志
docker exec
进入容器内部
1 2 docker exec -t mysql bash
挂载 数据卷挂载 数据卷(volume) 是一个虚拟目录,是容器内目录 与宿主机 目录之间映射的桥梁
以Nginx为例,我们知道Nginx中有两个关键的目录:
html
:放置一些静态资源
conf
:放置配置文件
注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建 。
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 26 27 28 29 30 31 32 33 34 35 36 docker run -d --name nginx -p 80 :80 -v html:/usr/share/nginx/html nginx docker volume ls DRIVER VOLUME NAME local 29524 ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f local html docker volume inspect html [ { "CreatedAt" : "2024-05-17T19:57:08+08:00" , "Driver" : "local" , "Labels" : null , "Mountpoint" : "/var/lib/docker/volumes/html/_data" , "Name" : "html" , "Options" : null , "Scope" : "local" } ] ll /var/lib/docker/volumes/html/_data 总用量 8 -rw-r--r-- . 1 root root 497 12 月 28 2021 50 x.html-rw-r--r-- . 1 root root 615 12 月 28 2021 index.htmlcd /var/lib/docker/volumes/html/_datavi index.html
本地目录挂载 可以发现,数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
1 2 3 4 -v 本地目录:容器内目录 -v 本地文件:容器内文件
注意 :本地目录或文件必须以 /
或 ./
开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。
1 2 -v mysql:/var/lib/mysql -v ./mysql:/var/lib/mysql
以初始化挂载MySQl为例:
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 docker rm -f mysql docker run -d \ --name mysql \ -p 3307:3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=zrh015658 \ -v /Users/zrh/DockerFile/mysql/data:/var/lib/mysql \ -v /Users/zrh/DockerFile/mysql/conf:/etc/mysql/conf.d \ -v /Users/zrh/DockerFile/mysql/init:/docker-entrypoint-initdb.d \ mysql ls -l mysql总用量 4 drwxr-xr-x. 2 root root 20 5月 19 15:11 conf drwxr-xr-x. 7 polkitd root 4096 5月 19 15:11 data drwxr-xr-x. 2 root root 23 5月 19 15:11 init ls -l data
自定义镜像 镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一id,称为Layer (层 )。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。
Dockerfile
镜像打包
由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。
而这种记录镜像结构的文件就称为Dockerfile ,其对应的语法可以参考官方文档:
例如,要基于Ubuntu镜像来构建一个Java应用,其Dockerfile内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 FROM ubuntu:16.04 ENV JAVA_DIR=/usr/localENV TZ=Asia/ShanghaiCOPY ./jdk8.tar.gz $JAVA_DIR / COPY ./docker-demo.jar /tmp/app.jar RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 ENV JAVA_HOME=$JAVA_DIR/java8ENV PATH=$PATH:$JAVA_HOME/binEXPOSE 8080 ENTRYPOINT ["java" , "-jar" , "/app.jar" ]
我们会有很多很多java项目需要打包为镜像,他们都需要Linux系统环境、JDK环境这两层,只有上面的3层不同(因为jar包不同)。如果每次制作java镜像都重复制作前两层镜像,是不是很麻烦。所以,就有人提供了基础的系统加JDK环境,我们在此基础上制作java镜像,就可以省去JDK的配置了:
1 2 3 4 5 6 7 8 9 FROM openjdk:11.0 -jre-busterENV TZ=Asia/ShanghaiRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY docker-demo.jar /app.jar ENTRYPOINT ["java" , "-jar" , "/app.jar" ]
构建镜像
在/root/demo里准备个jar包及对应的Dockerfile
1 2 3 4 docker build -t docker-demo:1.0 /root/demo docker build -t docker-demo:1.0 .
创建容器运行镜像
1 2 docker run -d --name dd -p 8080:8080 docker-demo:1.0
网络互联 而Java项目往往需要访问其它各种中间件,例如MySQL、Redis等。现在,我们的容器之间能否互相访问呢
可以互联,但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。所以,我们必须借助于docker的网络功能来解决这个问题:
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 26 27 28 29 30 31 32 33 34 35 docker network create hmall docker network ls NETWORK ID NAME DRIVER SCOPE 639bc44d0a87 bridge bridge local 403f16ec62a2 hmall bridge local 0dc0f72a0fbb host host local cd8d3e8df47b none null local docker network connect hmall mysql --alias db docker network connect hmall dd docker exec -it dd bash ping db PING db (172.18.0.2) 56(84) bytes of data. 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms ping mysql PING mysql (172.18.0.2) 56(84) bytes of data. 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms 64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms
项目部署 分别部署 一般来说,项目会多环境开发:
其中的application-dev.yaml
是部署到开发环境的配置,application-local.yaml
是本地运行时的配置
查看application.yaml,你会发现其中的JDBC地址并未写死,而是读取变量
在dev开发环境(也就是Docker部署时)采用了mysql作为地址,刚好是我们的mysql容器名,只要两者在一个网络,就一定能互相访问
部署完后端,部署前端,Nginx,MySQL等….
关联部署 DockerCompose
示例:
docker-compose.yml
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 version: "3.8" services: mysql: image: mysql container_name: mysql ports: - "3306:3306" environment: TZ: Asia/Shanghai 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 hmall: build: context: . dockerfile: Dockerfile container_name: hmall ports: - "8080:8080" networks: - hm-net depends_on: - mysql nginx: image: nginx container_name: nginx ports: - "18080:18080" - "18081:18081" volumes: - "./nginx/nginx.conf:/etc/nginx/nginx.conf" - "./nginx/html:/usr/share/nginx/html" depends_on: - hmall networks: - hm-net networks: hm-net: name: hmall