Docker的安装网上已经有不少资源了,在这里就不在赘述,直接进入项目java
1、建立Spring Boot项目,并编写简单的计数器功能,数据记录在mysql中mysql
项目pom.xml文件web
<?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
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文件sql
@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}能够看到计数器增长docker
2、编写Dockerfile将服务的镜像和mysql的镜像生成出来数据库
src文件夹下面新建文件夹src/main/docker/mysqlapache
建立文件my.cnfubuntu
[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上