乐趣区

关于docker:如何用Docker-Compose部署项目

[TOC]

前言

之前咱们用 docker 部署了 springboot,redis,mysql 的我的项目,然而是部署在三个不同的容器里,还须要先晓得 redismysqlip 地址,手动配置到 springboot 利用容器里,我只是想疾速在本地进行测试啊,这样老本太高了,有没有什么方法,把他们集中管理呢?比方把它构建成为一个镜像。

方法总是有的,那就是Docker Compose

之前的我的项目地址:https://github.com/Damaer/Dem…

Docker Compose

1. Docker Compose 是什么?

Docker Compose其实就是用来定义和运行简单利用的 Docker 工具,什么叫简单利用,比方后面写的springboot+redis+mysql,外面就有三个容器,这种多个容器的,用一个工具来治理,它不香么?

docker compose 通过配置文件来治理多个 Docker 容器,在配置文件中,所有的容器通过 service 来进行定义, 而后应用 docker-compose 脚本来启动、进行、重启利用以及利用中的服务和所依赖的容器等。

2. Docker Compose 的具体步骤

个别是三个步骤:

  • 应用Dockerfile 来定义应用程序的环境
  • docker-compose.yml 定义形成应用程序的服务,这样它们能够在隔离环境中一起运行。
  • 执行 docker-compose up 命令来启动并运行整个应用程序。

我应用的是 Mac OS,装Docker 的时候曾经把 Docker Compose 也装置好了,不须要独自装置。

3. 如何在 IDEA 我的项目外面应用 Docker Compose

首先 pom.xml 文件中须要留神配置小写的artifactId:

    <groupId>com.aphysia</groupId>
    <artifactId>dockerdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dockerdemo</name>
    <packaging>jar</packaging>

除此之外还须要配置插件:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!-- 将插件绑定在某个 phase 执行 -->
                <executions>
                    <execution>
                        <id>build-image</id>
                        <!-- 用户只需执行 mvn package,就会主动执行 mvn docker:build -->
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <dockerDirectory>src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>

除此之外,Dockerfile是必要的,下面的插件中曾经配置了咱们 dockerFile 须要放在 <dockerDirectory>src/main/docker</dockerDirectory> 这个地位,DockerFile外面配置如下:

FROM openjdk:8-jdk-alpine
EXPOSE 8081
VOLUME /tmp
# 重写命名为 app.jar
ADD dockerdemo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

实践上到这个时候,咱们应用 mvn clean package 就会生成对应的 jar 包:

docker compose最重要的是配置 docker-compose.yml, 这个文件咱们放在我的项目的根目录就能够,和pom.xml 平级:

version: "3"

services:
  redis:
    image: redis:latest
    restart: always
    ports:
      - "6389:6379"
    volumes:
      - /tmp/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf

  mysql:
    image: mysql:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      MYSQL_USER: 'root'
      MYSQL_PASS: '123456'
    ports:
      - "3306:3306"
    volumes:
      - "./db:/var/lib/mysql"
      - "./conf/my.cnf:/etc/my.cnf"
      - "./init:/docker-entrypoint-initdb.d/"
  # 指定服务名称
  webapp:
    # 指定服务应用的镜像
    image: aphysia/dockerdemo
    # 指定容器名称
    container_name: dockerdemo
    # 指定服务运行的端口
    ports:
      - 8081:8081
    # 指定容器中须要挂载的文件
    volumes:
      - /etc/localtime:/etc/localtime
      - /tmp/dockerdemo/logs:/var/logs

值得注意的点:

  1. service 外面就是咱们配置的镜像,蕴含了 redis,mysql,webappwebapp 其实就是咱们的利用。
  2. "6389:6379"6389 其实是咱们主机的端口,也就是我的 Mac 连贯 redis 容器须要应用6389,而容器之间连贯须要应用6379,这是容器的端口。
  3. /tmp/redis.conf:/etc/redis/redis.conf/tmp/redis.conf 是主机的目录,而这个目录须要在 docker 外面配置才能够,要不就会报错(执行记得加管理员权限):

    docker ERROR: * start service *: Mounts denied

  4. mysql 8.0 可能会报错 java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed,这个是因为url 链接少了一个参数:allowPublicKeyRetrieval=true

启动可能呈现的坑点

启动后可能链接不上 mysql 或者redis,然而看容器运行状况又是失常的:

DockerCompose % docker container ps
CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS         PORTS                                                  NAMES
32fd6ce598ba   aphysia/dockerdemo   "java -jar /app.jar"     7 minutes ago    Up 7 minutes   0.0.0.0:8081->8081/tcp, :::8081->8081/tcp              dockerdemo
585b9b6bd71d   redis:latest         "docker-entrypoint.s…"   10 minutes ago   Up 7 minutes   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              dockercompose_redis_1
d96ba57941d9   mysql:latest         "docker-entrypoint.s…"   16 minutes ago   Up 7 minutes   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   dockercompose_mysql_1

执行docker-compose up 没有报错,申请的时候报错:

 io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: /127.0.0.1:6379

这是因为容器之间的申请不能用 127.0.0.1,必须用mysql,redis 代表容器的网络, 比方:jdbc:mysql://mysql:3306/test?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true

残缺的application.yml:

server:
  port: 8081
spring:
  #数据库连贯配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://mysql:3306/test?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
  redis:
    host: redis     ## redis 所在的服务器 IP
    port: 6379
    ## 明码,我这里没有设置,所以不填
    password:
    ## 设置最大连接数,0 为有限
    pool:
      max-active: 8
      min-idle: 0
      max-idle: 8
      max-wait: -1
#mybatis 的相干配置
mybatis:
  #mapper 配置文件
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.aphysia.springdocker.model
  #开启驼峰命名
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    root: debug

还有一个问题,就是 docker-compose.yml 外面配置的镜像名字肯定要对,要不 docker-compose up 执行的时候,就会呈现:

Pulling xxxx...
ERROR: The image for the service you're trying to recreate has been removed. If you continue, volume data could be lost. Consider backing up your data before continuing.

Continue with the new image? [yN]y
Pulling xxxx...
ERROR: pull access denied for postgresql, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

我还认为是登录的起因,原本是本地镜像,应该间接 create 而不是 pull,如果不晓得名字,能够通过以下命令查看,REPOSITORY 就是名字:

DockerCompose % docker images
REPOSITORY           TAG            IMAGE ID       CREATED             SIZE
aphysia/dockerdemo   latest         1429aa26790a   54 minutes ago      137MB
<none>               <none>         ceb493583d7c   57 minutes ago      137MB
<none>               <none>         dffcc47602a2   About an hour ago   137MB
<none>               <none>         a695cf2cd2df   About an hour ago   137MB
<none>               <none>         209ce4f96d34   2 hours ago         137MB
redis                latest         40c68ed3a4d2   10 days ago         113MB
mysql                latest         e1d7dc9731da   14 months ago       544MB
openjdk              8-jdk-alpine   a3562aa0b991   2 years ago         105MB

最初启动命令:

sudo docker-compose up

胜利启动:

启动之后记得初始化一下数据库数据表!!!

drop database IF EXISTS test;
CREATE DATABASE test;
use test;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT "",
  `age` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES (1, '李四', 11);
INSERT INTO `user` VALUES (2, '王五', 11);

至此,功败垂成,看似简略的命令,其实还是有不少坑点。

【作者简介】
秦怀,公众号【秦怀杂货店 】作者,技术之路不在一时,山高水长,纵使迟缓,驰而不息。集体写作方向:Java 源码解析JDBCMybatisSpringredis 分布式 剑指 OfferLeetCode等,认真写好每一篇文章,不喜爱题目党,不喜爱花里胡哨,大多写系列文章,不能保障我写的都完全正确,然而我保障所写的均通过实际或者查找材料。脱漏或者谬误之处,还望斧正。

剑指 Offer 全副题解 PDF

2020 年我写了什么?

开源编程笔记

退出移动版