I know that people have read this time I write about Docker related articles, no pain does not itch, still do not feel the convenience of Docker, yes, I also think so, I know your felling.
Early to understand the concept of what is really boring, please do not worry about the wonderful start immediately, when we have a knowledge of Docker related concepts, I will combine Spring Boot to you a series of small examples, will let everyone feel that using Docker is so cool!
Today to show you the director is the Docker family Docker-compare, starring is Spring Boot, Nginx, Mysql three red and purple Bowl, the name of the name in the time is often ready to do things, and then a classic blockbuster is worth everyone's expectation.
Spring boot + Nginx + MySQL is the most commonly used combination in the actual work, the most front-end use of Nginx proxy request forwarding to the back-end Spring boot embedded Tomcat service, Mysql responsible for the business of data-related interactions, then there is no Docker How did we manage these environments before?
- 1, install Nginx, configure Nginx related information, restart.
- 2, install Mysql, configure the character set time zone and other information, restart, and finally initialize the script.
- 3, start the Spring boot project, the overall test of the joint adjustment.
You see I only wrote three lines, but actually build these environments when it is very troublesome, but this is not the end, in the use of a period of time need to migrate to another environment, how to do again need to do again? Under normal circumstances, test environment, SIT Environment, UAT environment, production environment! We need to build it four times over again. Some people say that is not build four times? It's no big deal, then I want to tell you, Too Yong, Too simple.
Let's take a look at the following factors:
First, this is just one of the simplest cases if the project involves MongoDB, Redis, ES ... What about the environment of some columns?
Second, if you often build the environment or debug the program, you will know what is the environmental problem? Sometimes it is exactly the same configuration, but to another environment is not run up. So you spend a lot of time looking for it, and finally find out that there is a problem with a parameter or a comma, or the system kernel version is inconsistent, or you don't understand why! You can only switch to another server, so using Docker is a perfect escape from these pits.
All right, no more nonsense, let's get started!
Spring Boot Case
First we prepare a spring boot using MySQL small scene, we do such an example, using Spring boot to do a WEB application, provide a method according to the number of IP address statistics access, each request to the statistics in MySQL and presented to the page.
Configuration information
Dependency Packages
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies>
The main additions are Spring Boot Web support, using JPA to manipulate databases, add MYQL driver packages, and more.
Configuration file
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.jpa.properties.hibernate.hbm2ddl.auto=updatespring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialectspring.jpa.show-sql=true
Configure link information for the database, as well as JPA Update table patterns, dialects, and whether to display SQL
Core code
The core code is very simple, each come up with a request to determine whether it has been counted, if there is no statistics added data, if there is statistical data update data.
@RestControllerpublic class VisitorController { @Autowired private VisitorRepository repository; @RequestMapping("/") public String index(HttpServletRequest request) { String ip=request.getRemoteAddr(); Visitor visitor=repository.findByIp(ip); if(visitor==null){ visitor=new Visitor(); visitor.setIp(ip); visitor.setTimes(1); }else { visitor.setTimes(visitor.getTimes()+1); } repository.save(visitor); return "I have been seen ip "+visitor.getIp()+" "+visitor.getTimes()+" times."; }}
Entity class and Repository layer code is relatively simple, here is not posted out, we are interested can download source view.
After the above content is complete, start the project, visit: http://localhost:8080/
We can see the result of this:
I have been seen ip 0:0:0:0:0:0:0:1 1 times.
Another visit will become
I have been seen ip 0:0:0:0:0:0:0:1 2 times.
Multiple visits have been superimposed, demonstrating the completion of the project development.
Docker Retrofit
First we transform the catalogue into such a structure
Let's start with the outermost layer:
docker-compose.yaml
: Docker-compose's core file that describes how to build the entire service
nginx
: About Nginx Configuration
app
: Spring Boot Project Address
If we need to have special customization for MySQL, we can also create a MySQL folder in the outermost layer and configure it in this directory.
docker-compose.yaml
Detailed documentation
version: ' 3 ' Services:nginx:container_name:v-nginx image:nginx:1.13 RESTART:ALW Ays Ports:-80:80-443:443 volumes:-./NGINX/CONF.D:/ETC/NGINX/CONF.D mysql:container_name:v-mysql IMA ge:mysql/mysql-server:5.7 environment:MYSQL_DATABASE:test mysql_root_password:root mysql_root_host: '% ' P Orts:-"3306:3306" Restart:always app:restart:always Build:./app working_dir:/app volumes:-. /app:/app-~/.m2:/root/.m2 Expose:-"8080" depends_on:-nginx-mysql command:mvn clean s Pring-boot:run-dspring-boot.run.profiles=docker
version: ‘3‘
: Represents the use of a third-generation syntax to build a Docker-compose.yaml file.
services
: Used to indicate the service that compose needs to start, we can see that there are three services in this file: Nginx, MySQL, app.
container_name
: Container Name
environment
: The information under this node is passed into the container as an environment variable, and in this example the MySQL service configures the database, password, and permission information.
ports
: port that represents open to the outside
restart: always
Indicates that if the service starts unsuccessfully it will always try.
volumes
: Load the configuration file under the local directory to the container destination address
depends_on
: You can configure dependent services to indicate that you need to start the depends_on
following service before you start the service.
command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker
: Represents the start of the project with this command, which means that the -Dspring-boot.run.profiles=docker
application-docker.properties
file configuration information is used to start.
Analysis of Nginx file
Nginx in the directory has a file app.conf, the main configuration of service forwarding information
server { listen 80; charset utf-8; access_log off; location / { proxy_pass http://app:8080; proxy_set_header Host $host:$server_port; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /static { access_log off; expires 30d; alias /app/static; }}
This piece of content is relatively simple, configure request forwarding, forwarding 80 port requests to the service app 8080 port. The proxy_pass http://app:8080
configuration information for this piece needs to be explained, and the use here is not app
localhost
, because they are not in a container, the service communication in a set of compose needs to be accessed using the name of the services.
Spring Boot Project Retrofit
In the app
directory that is pom.xm
, and file siblings Dockerfile
to add files, the file content is as follows:
FROM maven:3.5-jdk-8
There is only one sentence that relies on the underlying image maven3.5
and jdk 1.8
. Because the docker-compose.yaml
project Start command is set in the file, there is no need to add the start command.
resources
Create application-dev.properties
and application-docker.properties
file in the project directory
application-dev.properties
The configuration information in is consistent with the above
application-docker.properties
The configuration information in the database is modified slightly, and the connection information of the databases is jdbc:mysql://localhost:3306/test
changed jdbc:mysql://mysql:3306/test
.
So all of our configurations have been completed.
Deployment
We copy the project to the server for testing, the server needs to install the Docker and Docker Compos environment first, and if you don't know the friends can see the two previous articles:
- Docker (i): Docker Getting Started tutorial
- Docker (iv): Docker Compose of the Three Musketeers
Copy the project to the server and enter the directorycd dockercompose-springboot-mysql-nginx
Start the service:docker-compose up
[[email protected]_73_217_centos dockercompose-springboot-mysql-nginx]# Docker-compose upcreating Network "Dockercomposespringbootmysqlnginx_default" with the default drivercreating V-nginx ... donecreating v-mysql ... donecreating dockercomposespringbootmysqlnginx_app_1 ... doneattaching to V-nginx, V-mysql, Dockercomposespringbootmysqlnginx_app_1v-mysql | [EntryPoint] MySQL Docker Image 5.7.21-1.1.4v-mysql | [EntryPoint] Initializing Databaseapp_1 | [INFO] Scanning for projects ... app_1 | 2018-03-26 02:54:55.658 INFO 1---[main] o.s.b.w.embedded.tomcat.tomcatwebserver:tomcat started on port (s) : 8080 (HTTP) with context path ' app_1 | 2018-03-26 02:54:55.660 INFO 1---[main] com.neo.ComposeApplication:Started Composeapplicatio N in 14.869 seconds (JVM running for 30.202)
Seeing the message Tomcat started on port(s): 8080
indicates that the service started successfully. You can also use the docker-compose up -d
background to start
Access server address; http://58.87.69.230/
, return: I have been seen ip 172.19.0.2 1 times.
indicates that the overall service started successfully
Use docker-compose ps
to view all current containers in a project
[[email protected]_73_217_centos dockercompose-springboot-mysql-nginx]# docker-compose ps Name Command State Ports ----------------------------------------------------------------------------------------------------------------------------------dockercomposespringbootmysqlnginx_app_1 /usr/local/bin/mvn-entrypo ... Up 8080/tcp v-mysql /entrypoint.sh mysqld Up (healthy) 0.0.0.0:3306->3306/tcp, 33060/tcp v-nginx nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
You can see information about the status, commands, ports, and so on for a service in your project.
Close Servicedocker-compose down
[[email protected]_73_217_centos dockercompose-springboot-mysql-nginx]# docker-compose downStopping dockercomposespringbootmysqlnginx_app_1 ... doneStopping visitor-nginx ... doneStopping visitor-mysql ... doneRemoving dockercomposespringbootmysqlnginx_app_1 ... doneRemoving visitor-nginx ... doneRemoving visitor-mysql ... done
Docker-compose Order
When you start using Docker-compose, the project reports that the Mysql connection is abnormal, tracking the day finally found the problem. Docker-compose Although it is possible to define the order in which services are started, it is not possible to determine whether the service is started or not, depends_on
so there is a situation where the MySQL service starts slowly when the Spring boot project is started, but MySQL is not initialized. , so that when the project connects to the Mysql database, there will be exceptions to the connection database.
There are two solutions to this problem:
1, enough fault tolerance and retry mechanisms, such as connection to the database, when the initial connection is not on, the service consumers can continue to retry until the connection service. That is, defined in the service:restart: always
2, synchronous wait, use wait-for-it.sh
or other shell
scripts to start blocking the current service until the dependent service load is complete. This scenario can be tried later in the use.
Summarize
No comparison, no harm, before using Docker, we need to build such an environment, we need to install Nginx, Mysql, and then a series of configuration debugging, but also to worry about various environmental issues, after using Docker simple two commands to complete the service on-line, offline.
docker-compose updocker-compose down
In fact, container technology on the deployment of operational optimization There are many, this is just the beginning, behind the use of Swarm will really feel its convenience and strong.
Sample Code-github
Sample code-Cloud Code
Reference
Docker Compose with Spring Boot, MySQL and NGINX
Spring Boot 2.0 (Fri): Docker Compose + Spring boot +