前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分发JavaWeb项目之docker方案

分发JavaWeb项目之docker方案

作者头像
jeremyxu
发布2018-05-10 17:42:49
1.1K0
发布2018-05-10 17:42:49
举报

最近做了个小的Java Web脚手架工程。工程项目虽小,但算是一个很典型的Java Web项目,依赖于数据库,Java写的后端代码,JavaScript写的前端代码。本来写了一个说明,告诉用户如何将这个工程跑起来,很自然想到有好几步:

  • 安装前后端编译工具
  • 安装数据库,并初始化数据库结构
  • 根据数据库的具体信息,修改项目中的配置文件
  • 编译前端代码
  • 编译后端代码,最终形成war包
  • 将war包部署至应用服务器

想了下,真的好麻烦。突然想到可以使用docker简化应用的分发,于是有了以下尝试,这里记录一下。

改造工程

原来加载mysql连接信息配置文件的方式改造了一下,以适应在docker引擎中引用mysql。

db.xml

代码语言:javascript
复制
...
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:jdbc.properties</value>
            <value>classpath:env.properties</value>
            <value>file:///external/env_overwrite.properties</value>
        </list>
    </property>
    <property name="ignoreResourceNotFound" value="true" />
    <property name="searchSystemEnvironment" value="true" />
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
...

jdbc.properties

代码语言:javascript
复制
jdbc_url=jdbc:mysql://${MYSQL_PORT_3306_TCP_ADDR}:${MYSQL_PORT_3306_TCP_PORT}/${MYSQL_ENV_MYSQL_DATABASE}?useUnicode=true
jdbc_user=root
jdbc_password=${MYSQL_ENV_MYSQL_ROOT_PASSWORD}
jdbc_driverClass=com.mysql.jdbc.Driver

env.properties

代码语言:javascript
复制
MYSQL_PORT_3306_TCP_ADDR=127.0.0.1
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_ENV_MYSQL_DATABASE=ssm-db
MYSQL_ENV_MYSQL_ROOT_PASSWORD=123456

这里设置systemPropertiesModeName属性为SYSTEM_PROPERTIES_MODE_OVERRIDE,这样在解析一个占位符的时候,会先用系统属性来尝试,如果系统属性里没有才会用env.properties文件里定义的。

docker相关配置

项目下新建了dockerfiles目录,该目录下有一个docker-compose.yml文件,另外一个initdb目录下放数据库初始化脚本, 一个wars目录下放项目最后打的war包。

代码语言:javascript
复制
proj
  - dockerfiles
    - initdb
      - initdb.sql
    - wars
      - proj.war
    - docker-compose.yml
  - src
    - main
      - frontend
      - java
      - resources
      - webapp
  - pom.xml

docker-compose.yml

version: '2'

services:

ssm-mysql:

image: 'mysql'

volumes:

- ./initdb:/docker-entrypoint-initdb.d

environment:

- MYSQL_DATABASE=ssm-db

- MYSQL_ROOT_PASSWORD=123456

ssm-web:

image: 'jetty:9-alpine'

depends_on:

- ssm-mysql

links:

- ssm-mysql

volumes:

- ./wars:/var/lib/jetty/webapps

ports:

- "8080:8080"

environment:

- MYSQL_PORT_3306_TCP_ADDR=ssm-mysql

- MYSQL_PORT_3306_TCP_PORT=3306

- MYSQL_ENV_MYSQL_DATABASE=ssm-db

- MYSQL_ENV_MYSQL_ROOT_PASSWORD=123456

docker-compose.yml文件里定义了两个docker service, ssm-mysql是数据库服务,ssm-web是Web容器服务。

这里遇到了一坑,本来一个容器link另一个容器时,会从另一个容器得到一些环境变量,所以ssm-web服务的环境变量声明原本是不需要的,但去掉之后发现ssm-web服务跑不起来,好像是根本没有读到原本应该得到的环境变量。查了下原因,最后原因如下:

links with environment variables: As documented in the environment variables reference, environment variables created by links have been deprecated for some time. In the new Docker network system, they have been removed. You should either connect directly to the appropriate hostname or set the relevant environment variable yourself, using the link hostname:

代码语言:javascript
复制
web:
  links:
    - db
  environment:
    - DB_PORT=tcp://db:5432

看来以后还是不能依赖于links带来的变量。

改造pom.xml文件

最后稍微改造了下pom.xml文件

pom.xml

代码语言:javascript
复制
...
<!-- 打war包前安装npm依赖及编译前端代码 -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.3.2</version>
    <executions>
        <execution>
            <id>install_npm_dependences</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>yarn</executable>
                <workingDirectory>src/main/frontend</workingDirectory>
            </configuration>
        </execution>
        <execution>
            <id>build_frontend</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>npm</executable>
                <workingDirectory>src/main/frontend</workingDirectory>
                <arguments>
                    <argument>run</argument>
                    <argument>build</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

<!-- 将编译后的前端代码也打入war包 -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <webResources>
            <resource>
                <!-- this is relative to the pom.xml directory -->
                <directory>src/main/frontend_react/build</directory>
                <!-- the default value is ** -->
                <includes>
                    <include>**/*</include>
                </includes>
                <!-- there's no default value for this -->
                <excludes>
                    <exclude>asset-manifest.json</exclude>
                    <exclude>**/*.css.map</exclude>
                    <exclude>**/*.js.map</exclude>
                </excludes>
            </resource>
        </webResources>
    </configuration>
</plugin>

<!-- 将最后打出的war包拷贝至dockerfiles/wars目录 -->
<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
            <phase>package</phase>
            <configuration>
                <target>
                    <copy file="${basedir}/target/${project.artifactId}.war" tofile="${basedir}/dockerfiles/wars/${project.artifactId}.war" />
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>
...

总结

像上述这样改造后,分发项目就变得很简单了。

  • 在工程根目录下执行mvn package完成war的构建
  • dockerfiles目录下执行docker-compose up
  • 使用浏览器访问http://${docker_host_ip}:8080

进一步想,其实很多依赖组件较多的项目都可以考虑这样分发。记得以前做的一个项目依赖了mysql, mongodb, redis, mq, zookeeper,当时每个新加入团队的成员至少要花大半天来搭建开发环境,如果工程这样组织的话,一个新人就能很快将项目运行起来。

本工程源码地址:http://git.oschina.net/jeremy-xu/ssm-scaffold

参考

http://javablog.blog.163.com/blog/static/20971116420127109200710/ https://docs.docker.com/compose/compose-file/ https://yeasy.gitbooks.io/docker_practice/content/compose/install.html https://hub.docker.com/_/mysql/ https://hub.docker.com/_/jetty/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 改造工程
  • docker相关配置
  • 改造pom.xml文件
  • 总结
  • 参考
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档