业务背景
代码仓库
项目写好了,其中必要使用到一些中间件,考虑使用Docker来进行部署,但一个个初始化容器太慢了,以是考虑使用DockerCompose来指定镜像一键进行部署。
当然小编使用的是mac,但手上并没有服务器,当然愿意折腾的可以使用virtualBox安装Linux镜像,在当地搭建一个虚拟机来运行。
这篇文章重要来讲讲在mac情况下,使用 Docker DeskTop 来一键部署必要的情况
标准流程:
- idea配置ssh直接利用长途服务器,而且在服务器上安装并开发docker
- 可以看这篇文章:IDEA+Docker一键部署项目_intellij idea docker开发java项目-CSDN博客
- 在项目Pom文件中集成Docker插件,一键将项目镜像打包并部署到长途服务器上。
- 可以看这篇文章:Maven一键部署Springboot到Docker仓库
- docker拉取所需镜像,编写dockercompose
- dockercompose中涉及到的配置文件必要自界说(nginx)并上传到服务器上,使用dockerfile编写脚本进行上传
- 留意dockercompose中也要写挂载的配置文件地点
留意服务器必要包含底子镜像,dockercompose指定镜像才能生效,同理配置文件地点也是要有效的
DockerDeskTop
起首由于Mac的虚拟机情况太折磨人,尤其是M系列芯片之后,建议直接使用DockerDeskTop避免内耗。
起首docker desktop它其本质也是一个虚拟机,只不过它是透明的,我们在mac当地不能直接去访问或修改其下的文件,自由性就没有Linux那么高,但通常来说也不容易玩坏。
可以通过这个地点可以看到docker desktop的一些东西,它重要是用来存放镜像和容器的底层存储路径 :
- ~/Library/Containers/com.docker.docker/Data/vms/0/
DockerDeskTop挂载宿主主机配置文件
在docker中有时间是必要挂载我们编写的配置文件,在虚拟机中只必要将配置文件找到,写在指令中即可,例如:
- docker run -d --name redis -p 6379:6379
- -v /etc/redis/data:/data
- -v /etc/redis/conf/redis.conf:/etc/redis/redis.conf
复制代码 但这里DockerDeskTop显然是无法这样做的,这里就是必要将mac当地(宿主主机)的配置文件地点来进行利用,其实利用也较为简单,必要在设置中将配置文件的地点设置为共享即可,之后就可以正常的在dockercompose中写入了,这里是参考代码:
- version: '3'
- services:
- redis:
- image: redis:7
- container_name: redis
- command: redis-server --appendonly yes
- volumes:
- - /mydata/redis/data:/data #数据文件挂载
- ports:
- - 6379:6379
- nginx:
- image: nginx:1.22
- container_name: nginx
- volumes:
- - /Users/tomsmile/Desktop/mydata/nginx/conf/nginx.conf:/etc/nginx/nginx.conf # 修改为宿主机的文件路径
- - /Users/tomsmile/Desktop/mydata/nginx/html:/usr/share/nginx/html #静态资源根目录挂载
- - /Users/tomsmile/Desktop/mydata/nginx/logs:/var/log/nginx #日志文件挂载
- ports:
- - 80:80
- rabbitmq:
- image: rabbitmq:3.9.11-management
- container_name: rabbitmq
- volumes:
- - /mydata/rabbitmq/data:/var/lib/rabbitmq #数据文件挂载
- ports:
- - 5672:5672
- - 15672:15672
- elasticsearch:
- image: elasticsearch:7.17.3
- container_name: elasticsearch
- environment:
- - "cluster.name=elasticsearch" #设置集群名称为elasticsearch
- - "discovery.type=single-node" #以单一节点模式启动
- - "ES_JAVA_OPTS=-Xms2g -Xmx2g" #设置使用jvm内存大小
- volumes:
- - /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins #插件文件挂载
- - /mydata/elasticsearch/data:/usr/share/elasticsearch/data #数据文件挂载
- ports:
- - 9200:9200
- - 9300:9300
- mem_limit: 4g # 设置内存限制
- cpu_shares: 512 # 设置 CPU 权重
- logstash:
- image: logstash:7.17.3
- container_name: logstash
- environment:
- - TZ=Asia/Shanghai
- volumes:
- - /Users/tomsmile/Desktop/mydata/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf # 修改为宿主机的文件路径
- depends_on:
- - elasticsearch #kibana在elasticsearch启动之后再启动
- links:
- - elasticsearch:es #可以用es这个域名访问elasticsearch服务
- ports:
- - 4560:4560
- - 4561:4561
- - 4562:4562
- - 4563:4563
- kibana:
- image: kibana:7.17.3
- container_name: kibana
- links:
- - elasticsearch:es #可以用es这个域名访问elasticsearch服务
- depends_on:
- - elasticsearch #kibana在elasticsearch启动之后再启动
- environment:
- - "elasticsearch.hosts=http://es:9200" #设置访问elasticsearch的地址
- ports:
- - 5601:5601
复制代码 留意在部署es的时间,最好是能在compose文件中指明其内存,否则可能启动失败,当然也可能必要在docker-desktop中为资源添加更多空间
额外阐明,假如要在docker中部署mysql5.7,可能出现镜像拉取失败的题目:
mac m2 arm64 docker安装mysql 5.7_macbook m2安装mysql5.7-CSDN博客
-
- docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7 --lower_case_table_names=1
复制代码 参数顺序一定要对,–lower_case_table_names=1要加在镜像名背面,镜像名前面是参数,背面是mysql配置,否则会报错
dockercompose写法:
- version: '3'
- services:
- mysql:
- image: mysql:5.7
- container_name: mysql
- command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
- restart: always
- environment:
- MYSQL_ROOT_PASSWORD: root #设置root帐号密码
- ports:
- - 3306:3306
- volumes:
- - /mydata/mysql/data:/var/lib/mysql #数据文件挂载
- - /mydata/mysql/conf:/etc/mysql #配置文件挂载
- - /mydata/mysql/log:/var/log/mysql #日志文件挂载
复制代码 宿主主机路径 /mydata/mysql/data 被映射到 容器内部路径 /var/lib/mysql。
容器内的数据将会存储在宿主主机上对应的路径上。
假如有的配置文件并不必要挂载自界说编写的配置文件,可以使用 /mydata/mysql/data 这个地点,留意 /mydata必要在DockerDeskTop 中的共享文件中进行额外添加
/mydata:实际上并不是直接对应宿主主机的物理地点,这里是DockerDeskTop自身映射的地点,必要也必要我们额外进行添加
Docker文件存放地点:
- 在Docker中,当地的镜像文件都存放在哪里? - 黄嘉波 - 博客园
- Docker学习笔记之在 Windows 和 Mac 中使用 Docker - 时光飞逝,逝者如斯 - 博客园
测试宿主文件挂载到docker中:Docker Desktop中安装Redis并挂载配置文件_docker desktop 挂载当地文件夹-CSDN博客
- Error response from daemon: Mounts denied:
- The path /mydata/rabbitmq/data is not shared from the host and is not known to Docker.
- You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.
复制代码 题目形貌:在Mac系统下,实验让系统根目录下的文件与容器内文件进行映射时报错。
办理方案:在设置中,将路径设置为共享即可
继docker-maven-plugin插件的使用,下面简单讲讲在Mac上踩的坑
小编使用的是dockerdesktop来使用docker,以是一切配置都是在dockerdesktop中进行。
docker配置
在mac的idea中配备docker,并不必要额外配置什么,只必要勾选 docker for mac 即可使用
开启长途API
Windows、Mac、Linux中Docker开启长途访问API(2375端口)以及各种坑 - (App Store/公众号/小程序:分享录)
试了下在mac的dockerdesktop中直接修改deamon.json并不能开启,还会导致报错:
后续实验将其设置修改为User,也不行,而且这种情势还必要重新指定docker的情况变量位置
后续通过下载镜像socat,并开启容器来实现开启长途API
- docker run -d --name=socat --restart=always \
- -p 2375:2375 \
- -v /var/run/docker.sock:/var/run/docker.sock \
- alpine/socat \
- tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock
复制代码 测试(输入本机ip地点):
- curl http://192.168.8.86:2375/version
复制代码
至此docker的配置完成,接下来是代码插件配置
docker-maven-plugin
重要就是修改地点为指定服务器的地点,下面是一个示例文件:
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>io.fabric8</groupId>
- <artifactId>docker-maven-plugin</artifactId>
- <version>${docker.maven.plugin.version}</version>
- <executions>
- <!--如果想在项目打包时构建镜像添加-->
- <execution>
- <id>build-image</id>
- <phase>package</phase>
- <goals>
- <goal>build</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <!-- Docker 远程管理地址-->
- <dockerHost>${docker.host}</dockerHost>
- <images>
- <image>
- <!--定义镜像名称-->
- <name>mall-tiny/${project.name}:${project.version}</name>
- <!--定义镜像构建行为-->
- <build>
- <!--定义基础镜像-->
- <from>openjdk:8</from>
- <args>
- <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
- </args>
- <!--定义哪些文件拷贝到容器中-->
- <assembly>
- <!--定义拷贝到容器的目录-->
- <targetDir>/</targetDir>
- <!--只拷贝生成的jar包-->
- <descriptorRef>artifact</descriptorRef>
- </assembly>
- <!--定义容器启动命令-->
- <entryPoint>["java", "-jar","-Dspring.profiles.active=prod","/${project.build.finalName}.jar"]</entryPoint>
- <!--定义维护者-->
- <maintainer>macrozheng</maintainer>
- </build>
- </image>
- </images>
- </configuration>
- </plugin>
- </plugins>
- </build>
复制代码
- 相关配置阐明:
- executions.execution:此处配置了在maven打包应用时构建docker镜像;
- image.name:用于指定镜像名称,mall-tiny是仓库名称, p r o j e c t . n a m e 为镜像名称, {project.name}为镜像名称, project.name为镜像名称,{project.version}为镜像标署名称;
- dockerHost:打包后上传到的docker服务器地点;
- build.from:该应用所依赖的底子镜像,此处为openjdk;
- entryPoint:docker容器启动时执行的下令,可以使用-Dspring.profiles.active=prod指定应用配置文件;
- assembly:界说哪些文件拷贝到容器中;
- assembly.targetDir:界说拷贝到容器的目录;
- assembly.descriptorRef:只拷贝生成的jar包;
- maintainer:界说项目的维护者。
- 添加application-prod.yml配置文件,只是将之前的数据库地点的localhost改为了db;
可以把docker中的容器看作独立的虚拟机,mall-tiny-docker访问localhost自然会访问不到mysql,docker容器之间可以通过指定好的服务名称db进行访问,至于db这个名称可以在运行mall-tiny-docker容器的时间指定。
- server:
- port: 8080
- spring:
- datasource:
- url: jdbc:mysql://db:3306/mall_tiny?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
- username: root
- password: root
复制代码 其中在pom文件中配置的和dockerFile实际上是差不多的,两种方式都可以用来实现打包项目的镜像jar包,dockerFile是最为传统的方式,它是由用户起首使用maven对项目进行打包(留意使用此方式必要将pom文件关于docker-maven-plugin的代码进行注释),之后将打好的jar包放置在dockerFile的同级目录下,点击运行即可推至长途服务器上的docker。
更多介绍–docker-maven-plugin
代码仓库:GitHub - macrozheng/mall-learning at dev-v2
还在手动部署SpringBoot应用?试试这个自动化插件! | mall学习教程
docker-maven-plugin不仅可以利用镜像,还可以利用容器,乃至可以直接在pom文件中指明挂载的位置,例如下面指令:
- docker run -p 8080:8080 --name mall-tiny-fabric \
- --link mysql:db \
- -v /etc/localtime:/etc/localtime \
- -v /mydata/app/mall-tiny-fabric/logs:/var/logs \
- -d 192.168.3.101:5000/mall-tiny/mall-tiny-fabric:0.0.1-SNAPSHOT
复制代码 在pom文件中可以这样写:
- <!--定义容器启动行为-->
- <run>
- <!--设置容器名,可采用通配符-->
- <containerNamePattern>${project.artifactId}</containerNamePattern>
- <!--设置端口映射-->
- <ports>
- <port>8080:8080</port>
- </ports>
- <!--设置容器间连接-->
- <links>
- <link>mysql:db</link>
- </links>
- <!--设置容器和宿主机目录挂载-->
- <volumes>
- <bind>
- <volume>/etc/localtime:/etc/localtime</volume>
- <volume>/mydata/app/${project.artifactId}/logs:/var/logs</volume>
- </bind>
- </volumes>
- </run>
复制代码 当然照旧建议使用dockerCompose来同一订定,可读性也比较高
docker启动容器
在docker中启动打包的项目镜像,留意要指定mysql的服务要和配置文件中也要保持同等,这里是用服务名称来进行启动,db是启动的mysql容器。
- docker run -p 3307:3306 --name mysql \
- -v /mydata/mysql/log:/var/log/mysql \
- -v /mydata/mysql/data:/var/lib/mysql \
- -v /mydata/mysql/conf:/etc/mysql \
- -e MYSQL_ROOT_PASSWORD=root \
- -d mysql:5.7
复制代码
- 假如遇到mysql容器无法启动的情况,可以先删除容器,再使用如下下令启动(该下令只是删除了mysql配置文件挂载的那行下令);
- docker run -p 3306:3306 --name mysql \
- -v /mydata/mysql/log:/var/log/mysql \
- -v /mydata/mysql/data:/var/lib/mysql \
- -e MYSQL_ROOT_PASSWORD=root \
- -d mysql:5.7
复制代码
- docker exec -it mysql /bin/bash
复制代码
- mysql -uroot -proot --default-character-set=utf8
复制代码
- grant all privileges on *.* to 'root'@'%';
复制代码
- create database mall_tiny character set utf8;
复制代码
- 将mall_tiny.sql文件拷贝到mysql容器的/目录下:
- docker cp /mydata/mall_tiny.sql mysql:/
复制代码
- use mall_tiny;
- source /mall_tiny.sql;
复制代码
启动项目
项目推至本机的docker下之后,可以通过长途服务器的ip进行测试访问(留意必要打开80端口),这里小编使用本机测试,在同一个局域网内是能够访问的,但超出这个范围的就不能访问成功。
思考下为什么长途服务器部署好项目,就可以在任何地方进行访问,而这里我通过本机部署的项目为什么不能做到任何地方都访问呢?
其实重要涉及到 网络访问控制 和 防火墙设置 这两块
Docker 的默认网络模式–bridge,容器会毗连到一个虚拟的桥接网络,容器之间可以通过虚拟网桥通信,但容器外的呆板(包括同一局域网内的其他呆板)默认是无法直接访问容器的端口的。
dockerFile常用语法:
- FROM # 基础镜像,当前新镜像是基于哪个镜像的
- MAINTAINER # 镜像维护者的姓名混合邮箱地址
- RUN # 容器构建时需要运行的命令
- EXPOSE # 当前容器对外保留出的端口
- WORKDIR # 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点
- ENV # 用来在构建镜像过程中设置环境变量
- ADD # 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
- COPY # 类似ADD,拷贝文件和目录到镜像中!
- VOLUME # 容器数据卷,用于数据保存和持久化工作
- CMD # 指定一个容器启动时要运行的命令,dockerFile中可以有多个CMD指令,但只有最后一个生效!
- ENTRYPOINT # 指定一个容器启动时要运行的命令!和CMD一样
- ONBUILD # 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的ONBUILD被触发
复制代码- # 该镜像需要依赖的基础镜像
- FROM openjdk:8
- # 将当前目录下的jar包复制到docker容器的/目录下
- ADD mall-tiny-docker-1.0-SNAPSHOT.jar /mall-tiny-docker-1.0-SNAPSHOT.jar
- # 声明服务运行在8080端口
- EXPOSE 8080
- # 指定docker容器启动时运行jar包
- ENTRYPOINT ["java", "-jar","-Dspring.profiles.active=prod","/mall-tiny-docker-1.0-SNAPSHOT.jar"]
- # 指定维护者的名字
- MAINTAINER macrozheng
复制代码 ADD
用于复制文件,格式:
示例:
- # 将当前目录下的mall-tiny-docker.jar包复制到docker容器的/目录下
- ADD mall-tiny-docker.jar /mall-tiny-docker.jar
复制代码 ENTRYPOINT
指定docker容器启动时执行的下令,格式:
- ENTRYPOINT ["executable", "param1","param2"...]
复制代码 示例:
- # 指定docker容器启动时运行jar包
- ENTRYPOINT ["java", "-jar","/mall-tiny-docker.jar"]
复制代码 ENV
用于设置情况变量,格式:
示例:
- # mysql运行时设置root密码
- ENV MYSQL_ROOT_PASSWORD root
复制代码 EXPOSE
声明必要袒露的端口(只声明不会打开端口),格式:
- EXPOSE <port1> <port2> ...
复制代码 示例:
- # 声明服务运行在8080端口
- EXPOSE 8080
复制代码 FROM
指定所需依赖的底子镜像,格式:
示例:
- # 该镜像需要依赖的openjdk的镜像
- FROM openjdk:8
复制代码 MAINTAINER
指定维护者的名字,格式:
示例:
RUN
在容器构建过程中执行的下令,我们可以用该下令自界说容器的行为,好比安装一些软件,创建一些文件等,格式:
- RUN <command>
- RUN ["executable", "param1","param2"...]
复制代码 示例:
- # 在容器构建过程中需要在/目录下创建一个mall-tiny-docker.jar文件
- RUN bash -c 'touch /mall-tiny-docker.jar'
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |