DockerDeskTop+DockerCompose一键部署(Mac)

业务背景

代码仓库

项目写好了,其中需要使用到一些中间件,考虑使用Docker来进行部署,但一个个初始化容器太慢了,所以考虑使用DockerCompose来指定镜像一键进行部署。

当然小编使用的是mac,但手上并没有服务器,当然愿意折腾的可以使用virtualBox安装Linux镜像,在本地搭建一个虚拟机来运行。

这篇文章主要来讲讲在mac环境下,使用 Docker DeskTop 来一键部署需要的环境

标准流程:

  1. idea配置ssh直接操作远程服务器,并且在服务器上安装并开发docker
  2. 在项目Pom文件中集成Docker插件,一键将项目镜像打包并部署到远程服务器上。
  3. docker拉取所需镜像,编写dockercompose
  4. 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 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并不能开启,还会导致报错:

image.png

后续尝试将其设置修改为User,也不行,而且这种形式还需要重新指定docker的环境变量位置

image.png
后续通过下载镜像socat,并开启容器来实现开启远程API

docker pull alpine/socat
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

image.png

至此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命令启动:
  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
  • 进入运行mysql的docker容器:
docker exec -it mysql /bin/bash
  • 使用mysql命令打开客户端:
mysql -uroot -proot --default-character-set=utf8

  • 修改root帐号的权限,使得任何ip都能访问:
grant all privileges on *.* to 'root'@'%';

  • 创建mall数据库:
create database mall_tiny character set utf8;
  • mall_tiny.sql文件拷贝到mysql容器的/目录下:
docker cp /mydata/mall_tiny.sql mysql:/
  • 将sql文件导入到数据库:
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

用于复制文件,格式:

ADD <src> <dest>

示例:

# 将当前目录下的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

用于设置环境变量,格式:

ENV <key> <value>

示例:

# mysql运行时设置root密码
ENV MYSQL_ROOT_PASSWORD root

EXPOSE

声明需要暴露的端口(只声明不会打开端口),格式:

EXPOSE <port1> <port2> ...

示例:

# 声明服务运行在8080端口
EXPOSE 8080

FROM

指定所需依赖的基础镜像,格式:

FROM <image>:<tag>

示例:

# 该镜像需要依赖的openjdk的镜像
FROM openjdk:8

MAINTAINER

指定维护者的名字,格式:

MAINTAINER <name>

示例:

MAINTAINER macrozheng

RUN

在容器构建过程中执行的命令,我们可以用该命令自定义容器的行为,比如安装一些软件,创建一些文件等,格式:

RUN <command>
RUN ["executable", "param1","param2"...]

示例:

# 在容器构建过程中需要在/目录下创建一个mall-tiny-docker.jar文件
RUN bash -c 'touch /mall-tiny-docker.jar'
### 如何在 Docker Desktop 上部署 DeesKeep 应用 #### 准备工作 为了成功部署 DeesKeep 应用程序,在本地环境中需先确保已正确安装并配置好 Docker Desktop[^1]。 对于 Windows 用户而言,应遵循官方指南完成 Docker Desktop 的安装过程。而对于 Mac OS 用户,默认情况下 Docker Desktop 安装路径位于 `/Applications/Docker.app` 中;可以从应用程序文件夹中启动它,并按照提示输入必要的登录凭证来授权访问权限[^2]。 #### 部署步骤概述 要使 DeesKeep 运行于容器内,通常涉及以下几个方面的工作: - 获取或构建适合的应用镜像; - 编写 `docker-compose.yml` 或者直接通过命令行参数指定运行选项; - 启动服务并将端口映射到主机以便外部能够访问该应用实例。 #### 获取或创建 DeesKeep 镜像 如果存在现成的公共仓库中的 DeesKeep 镜像,则可以直接拉取: ```bash docker pull deeskeep/image_name:tag_version ``` 假设没有可用的标准镜像版本,那么就需要基于项目源码自行制作自定义镜像。这一步骤可能涉及到编写 Dockerfile 并执行如下指令来进行打包操作: ```bash cd path_to_deeskeep_project_directory docker build -t my-deeskeep-app . ``` #### 使用 docker-compose 管理多容器环境(可选) 当应用程序依赖多个微服务组件时,推荐采用 Compose 工具简化管理流程。编辑一份名为 `docker-compose.yml` 的 YAML 文件描述所需的服务集合及其关联关系: ```yaml version: '3' services: app: image: "my-deeskeep-app" ports: - "8080:80" environment: - ENV_VAR_NAME=value_for_env_var ``` 保存上述配置之后,只需一条简单的命令就能一键启动整个集群: ```bash docker-compose up -d ``` #### 处理常见错误情况 有时会遇到诸如 “WSL distro terminated abruptly” 类似的报错信息,这类问题往往是因为某些后台进程意外终止而导致 WSL 被迫关闭所引起的。针对这种情况可以尝试重启计算机或者重新初始化 WSL 来解决问题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值