[TOC]
preface
Previously, we deployed springboot, redis and mysql projects with docker, but they are deployed in three different containers. We also need to know the ip addresses of redis and mysql and manually configure them into the springboot application container. I just want to test them locally quickly. This cost is too high. Is there any way to centrally manage them? For example, build it into a mirror.
There is always a way, that is, Docker Compose.
Previous project address: https://github.com/Damaer/Dem...
Docker Compose
1. What is docker compose?
Docker Compose is actually a docker tool used to define and run complex applications. What is a complex application? For example, the previously written springboot+redis+mysql has three containers. This kind of multiple containers is managed by one tool. Isn't it fragrant?
Docker compose manages multiple docker containers through a configuration file. In the configuration file, all containers are defined through services, and then docker compose scripts are used to start, stop and restart applications, as well as services and dependent containers in applications.
2. Specific steps of docker compose
There are generally three steps:
- Use Dockerfile to define the environment of the application
- At docker compose YML defines the services that make up the application so that they can run together in an isolated environment.
- Execute the docker compose up command to start and run the entire application.
I use Mac OS. Docker Compose has been installed when docker is installed. There is no need to install it separately.
3. How to use Docker Compose in an IDEA project
First, POM In the XML file, you should pay attention to configuring the lowercase artifactId:
<groupId>com.aphysia</groupId> <artifactId>dockerdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dockerdemo</name> <packaging>jar</packaging>
In addition, you need to configure plug-ins:
<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> <!-- Bind a plug-in to a phase implement --> <executions> <execution> <id>build-image</id> <!-- Users only need to execute mvn package ,It will be executed automatically 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>
In addition, dockerfile is necessary. It has been configured in the plug-in above. We need to place dockerfile in < dockerdirectory > Src / main / docker < / dockerdirectory >. The configuration in dockerfile is as follows:
FROM openjdk:8-jdk-alpine EXPOSE 8081 VOLUME /tmp # Rewrite and name it app jar ADD dockerdemo-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"]
Theoretically, by this time, we will generate the corresponding jar package by using mvn clean package:
The most important thing for docker compose is to configure docker compose YML, we can put this file in the root directory of the project, and POM XML level:
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/" # Specify the service name webapp: # Specifies the image used by the service image: aphysia/dockerdemo # Specify container name container_name: dockerdemo # Specifies the port on which the service runs ports: - 8081:8081 # Specify the files to mount in the container volumes: - /etc/localtime:/etc/localtime - /tmp/dockerdemo/logs:/var/logs
Notable points:
- service is the image we configured, including redis, MySQL and webapp. Webapp is actually our application.
- In "6389:6379", 6389 is actually the port of our host, that is, my Mac needs to use 6389 to connect to the redis container, and the connection between containers needs to use 6379, which is the port of the container.
/tmp/redis.conf:/etc/redis/redis.conf / TMP / redis Conf is the directory of the host, and this directory needs to be configured in docker, or an error will be reported (remember to add administrator permission when executing):
docker ERROR: * start service *: Mounts denied
- mysql 8.0 may report an error Java sql. Sqlnontransientconnectionexception: public key retrieval is not allowed because the url link is missing a parameter: allowPublicKeyRetrieval=true
Start possible pit points
mysql or redis may not be linked after startup, but it is normal to see the operation of the container:
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
No error is reported when docker compose up is executed. An error is reported when requesting:
io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: /127.0.0.1: 6379
This is because requests between containers cannot use 127.0 0.1. MySQL and redis must be used to represent the container network, such as JDBC: mysql://mysql:3306/test?characterEncoding=utf -8&useSSL=false&allowPublicKeyRetrieval=true
Complete application yml:
server: port: 8081 spring: #Database connection configuration 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 ## Server IP of redis port: 6379 ##I don't have a password here, so I don't fill it in password: ## Set the maximum number of connections. 0 is infinite pool: max-active: 8 min-idle: 0 max-idle: 8 max-wait: -1 #Configuration of mybatis mybatis: #mapper profile mapper-locations: classpath:mapper/*.xml type-aliases-package: com.aphysia.springdocker.model #Open hump naming configuration: map-underscore-to-camel-case: true logging: level: root: debug
Another problem is docker compose The image name configured in YML must be correct, otherwise it will appear when docker compose up is executed:
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
I thought it was because of login. It was originally a local image. You should directly create instead of pull. If you don't know the name, you can view it through the following command. REPOSITORY is the name:
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
Last start command:
sudo docker-compose up
Successfully started:
Remember to initialize the database data table after startup!!!
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, 'Li Si', 11); INSERT INTO `user` VALUES (2, 'Wang Wu', 11);
So far, it has been completed. There are still many pits in the seemingly simple command.
[about the author]:
Qin Huai, official account [Qinhuai grocery store] the author, the road of technology is not at the moment. The mountain is high and the river is long. Even if it is slow, it will not stop. His personal writing direction: Java source code analysis, JDBC, Mybatis, Spring, redis, distributed, sword finger Offer, LeetCode, etc. He carefully writes every article. He doesn't like the title party and fancy. He mostly writes a series of articles, which can't guarantee that I write completely correctly Yes, but I guarantee that what I write has been practiced or searched for information. Please correct any omissions or mistakes.