Docker的安装网上已经有很多资源了,在这里就不在赘述,直接进入项目
一、创建Spring Boot项目,并编写简单的计数器功能,数据记录在mysql中
项目pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<docker.image.prefix>leo</docker.image.prefix>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin> --Docker插件
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.11</version>
<executions>
<execution>
-- 当执行package命令的时候进行Docker镜像的build
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
-- 镜像名称
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
-- Dockerfile所在的路径
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>generator.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
application.yml文件
spring:
datasource:
url: jdbc:mysql://mysql1:3306/lhz?useSSL=false -- 此处由于要链接到mysql容器中去,所以这里写的是容器的名称
username: docker
password: 123456
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath*:/mapper/*/*Mapper.xml
HelloController文件
@RestController
public class HelloController {
@Autowired
private UserService userService;
@ResponseBody
@RequestMapping(value="hello",method=RequestMethod.GET)
public String hello() {
return "hello";
}
@ResponseBody
@RequestMapping(value="hello/{userId}",method=RequestMethod.GET)
public Integer hello(@PathVariable(value = "userId") String userId) {
return userService.plus(userId);
}
}
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public Integer plus(String userId) {
User user = userMapper.selectById(userId);
if(user == null) {
user = new User();
user.setId(1);
user.setCount(0);
userMapper.insert(user);
return 0;
}
Integer count = user.getCount();
user.setCount(++count);
userMapper.update(user);
return count;
}
}
@Mapper
public interface UserMapper {
int insert(User record);
List<User> selectAll();
User selectById(String userId);
void update(User user);
}
public class User {
private Integer id;
private Integer count;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.mapper.UserMapper" >
<resultMap id="BaseResultMap" type="com.example.demo.domain.User" >
<result column="id" property="id" jdbcType="INTEGER" />
<result column="count" property="count" jdbcType="INTEGER" />
</resultMap>
<insert id="insert" parameterType="com.example.demo.domain.User" >
insert into user (id, count)
values (#{id,jdbcType=INTEGER}, #{count,jdbcType=INTEGER})
</insert>
<select id="selectAll" resultMap="BaseResultMap" >
select id, count
from user
</select>
<update id="update" parameterType="com.example.demo.domain.User">
update user set count = #{count,jdbcType=INTEGER} where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectById" resultMap="BaseResultMap" >
select id, count
from user where id = #{id,jdbcType=INTEGER}
</select>
</mapper>
到这里项目都已经创建完成,启动后访问hello/{userId}可以看到计数器增加
二、编写Dockerfile将服务的镜像和mysql的镜像生成出来
src文件夹下面新建文件夹src/main/docker/mysql
创建文件my.cnf
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
schema.sql
CREATE DATABASE IF NOT EXISTS `lhz` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `lhz`;
-- MySQL dump 10.13 Distrib 5.7.22, for Linux (x86_64)
--
-- Host: localhost Database: lhz
-- ------------------------------------------------------
-- Server version 5.7.22-0ubuntu0.17.10.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`count` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2018-05-01 22:23:08
privileges.sql
use mysql;
select host, user from user;
-- 因为mysql版本是5.7,因此新建用户为如下命令:
create user docker identified by '123456';
-- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456:
grant all on lhz.* to docker@'%' identified by '123456' with grant option;
-- 这一条命令一定要有:
flush privileges;
setup.sh
#!/bin/bash
set -e
#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`
echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`
echo '2.开始导入数据....'
#导入数据
mysql < /etc/mysql/schema.sql
echo '3.导入数据完毕....'
sleep 3
echo `service mysql status`
#重新设置mysql密码
echo '4.开始修改密码....'
mysql < /etc/mysql/privileges.sql
echo '5.修改密码完毕....'
#sleep 3
echo `service mysql status`
echo 'mysql容器启动完毕,且数据导入成功'
tail -f /dev/null
Dockerfile文件
FROM mysql:5.7
VOLUME my.cnf:/etc/mysql/my.cnf mysql
#将所需文件放到容器中
ADD setup.sh /etc/mysql/setup.sh
ADD schema.sql /etc/mysql/schema.sql
ADD privileges.sql /etc/mysql/privileges.sql
EXPOSE 3306
ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
#设置容器启动时执行的命令
CMD ["sh", "/etc/mysql/setup.sh"]
至此mysql镜像所需文件完成,进入docker/mysql文件夹下执行命令
docker build -t leo/mysql .
输出如下
Sending build context to Docker daemon 8.192kB
Step 1/8 : FROM mysql:5.7
---> db763dfc448b
Step 2/8 : VOLUME my.cnf:/etc/mysql/my.cnf mysql
---> Running in c7983fbbc27e
Removing intermediate container c7983fbbc27e
---> 6713fe9fbd20
Step 3/8 : ADD setup.sh /etc/mysql/setup.sh
---> 250290ecac96
Step 4/8 : ADD schema.sql /etc/mysql/schema.sql
---> 0bff6bb6ccbc
Step 5/8 : ADD privileges.sql /etc/mysql/privileges.sql
---> 41909954766f
Step 6/8 : EXPOSE 3306
---> Running in c34065f6f503
Removing intermediate container c34065f6f503
---> a40db40e4fc6
Step 7/8 : ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
---> Running in d7dc727ade54
Removing intermediate container d7dc727ade54
---> 4ce1e5739a43
Step 8/8 : CMD ["sh", "/etc/mysql/setup.sh"]
---> Running in 2d24626e4b53
Removing intermediate container 2d24626e4b53
---> edbaec51aa90
Successfully built edbaec51aa90
Successfully tagged leo/mysql:latest
镜像创建成功
执行docker images命令可以看到我们刚才创建的镜像
下面我们来创建服务镜像,这里我们使用maven的docker插件,在上面我们都有注释。
然后我们在docker文件夹下面创建Dockerfile文件
FROM java:8
VOLUME /tmp
ADD demo-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
EXPOSE 8080
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
然后在项目路径执行mvn clean package命令,可以看到最后面生成了我么服务的镜像
[INFO] Building image leo/demo
Step 1/7 : FROM java:8
---> d23bdf5b1b1b
Step 2/7 : VOLUME /tmp
---> Using cache
---> f3b25192acf9
Step 3/7 : ADD demo-0.0.1-SNAPSHOT.jar app.jar
---> 74b032aca919
Step 4/7 : RUN sh -c 'touch /app.jar'
---> Running in 4910f0d0bc10
Removing intermediate container 4910f0d0bc10
---> 1c3adcdb997e
Step 5/7 : EXPOSE 8080
---> Running in 608eca7f3c3f
Removing intermediate container 608eca7f3c3f
---> 75894ae6a8a4
Step 6/7 : ENV JAVA_OPTS=""
---> Running in 3b64b4567ac4
Removing intermediate container 3b64b4567ac4
---> 327ee6e1d18e
Step 7/7 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
---> Running in 057a92e82ce7
Removing intermediate container 057a92e82ce7
---> 15289a9089fe
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 15289a9089fe
Successfully tagged leo/demo:latest
现在两个镜像都有了,我们进行服务的编排。在项目目录下创建docker-compose.yml文件
version : '2'
services:
-- 服务名称,其他服务调用的时候就用这个名称
mysql1:
image: leo/mysql:latest
volumes:
- ./src/main/docker/mysql/my.cnf:/etc/mysql/my.cnf mysql
environment:
- MYSQL_ROOT_PASSWORD=123456
ports:
- "3307:3306"
expose:
- "3307"
demo:
image: leo/demo:latest
ports:
- "8080:8080"
links:
-- 连接的服务,这里连接到了mysql1
- mysql1
编写完之后,在同目录下执行命令
docker-compose up
会自动开始创建容器,启动服务
demo_1 | 2018-05-02 14:35:23.603 INFO 6 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
demo_1 | 2018-05-02 14:35:23.604 INFO 6 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
demo_1 | 2018-05-02 14:35:24.048 INFO 6 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
demo_1 | 2018-05-02 14:35:24.051 INFO 6 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'dataSource' has been autodetected for JMX exposure
demo_1 | 2018-05-02 14:35:24.064 INFO 6 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
demo_1 | 2018-05-02 14:35:24.352 INFO 6 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
demo_1 | 2018-05-02 14:35:24.357 INFO 6 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 8.268 seconds (JVM running for 11.648)
mysql1_1 | 2018-05-02T14:35:28.633990Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634029Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634038Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634055Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634060Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634070Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634095Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | 2018-05-02T14:35:28.634102Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
mysql1_1 | ..
mysql1_1 | MySQL Community Server 5.7.22 is started.
mysql1_1 | MySQL Community Server 5.7.22 is running.
mysql1_1 | 2.开始导入数据....
mysql1_1 | 3.导入数据完毕....
mysql1_1 | MySQL Community Server 5.7.22 is running.
mysql1_1 | 4.开始修改密码....
mysql1_1 | host user
mysql1_1 | localhost mysql.session
mysql1_1 | localhost mysql.sys
mysql1_1 | localhost root
mysql1_1 | 5.修改密码完毕....
mysql1_1 | MySQL Community Server 5.7.22 is running.
mysql1_1 | mysql容器启动完毕,且数据导入成功
启动完成,这时候我们从浏览器中访问刚才的服务地址/hello/1
可以看到计数器依旧生效,至此我们完成了一个简单的将服务运行在docker上