Przeglądaj źródła

Dockerize

* 为了减小生成的docker镜像的体积,使用了docker multiple-stage build,
  编译docker image需要使用17.05以上的版本(目前在edge频道),运行
  镜像无特殊要求,目前stable频道的docker即可运行。
* 镜像(war包)中删除了一些不使用的js库,详见 .dockerignore 文件
* docker编译镜像时,支持通过 --build-arg LOCAL_MAVEN_MIRROR=xxx 来指定
  使用的maven镜像,加快编译速度。目前默认使用阿里云的镜像。
* docker镜像提供了以下环境变量:
  - MYSQL_HOST, MYSQL_PORT, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD
    第一次启动时,会自动根据这些环境变量修改配置文件
  - ADMIN_EMAIL, ADMIN_PASSWORD
    启动时如果发现数据库没有初始化,则初始化数据库,并依此创建管理员帐号。
* 提供了一个 docker-compose 文件,可以直接 `docker-compose up` 来运行,
  compose中使用了mysql数据库。注意,首次启动时,应该先启动数据库,等
  数据库初始化完成后再启动dwsurvey。
  ```
  docker-compose up -d db
  # 等待一段事件
  docker-compose up -d dwsurvey
  ```
Zhang Cheng 8 lat temu
rodzic
commit
be54986262
5 zmienionych plików z 205 dodań i 1 usunięć
  1. 16 0
      .dockerignore
  2. 69 0
      Dockerfile
  3. 31 0
      docker-compose.yml
  4. 88 0
      docker-entry.sh
  5. 1 1
      pom.xml

+ 16 - 0
.dockerignore

@@ -0,0 +1,16 @@
+.git/
+.m2/
+target/
+
+# ignore unused files, reducing image size
+src/main/webapp/js/plugs/ueditor1_4_3-utf8-jsp/
+src/main/webapp/js/plugs/echarts-2.2.3/
+src/main/webapp/js/plugs/echarts/echarts-master/.github/
+src/main/webapp/js/plugs/echarts/echarts-master/asset/
+src/main/webapp/js/plugs/echarts/echarts-master/build/
+src/main/webapp/js/plugs/echarts/echarts-master/extension/
+src/main/webapp/js/plugs/echarts/echarts-master/map/
+src/main/webapp/js/plugs/echarts/echarts-master/src/
+src/main/webapp/js/plugs/echarts/echarts-master/test/
+src/main/webapp/js/plugs/jquery-ui-1.9.0.custom/
+src/main/webapp/js/plugs/zeroclipboard-master/test/

+ 69 - 0
Dockerfile

@@ -0,0 +1,69 @@
+FROM maven:3.5-jdk-8-alpine as builder
+
+ARG LOCAL_MAVEN_MIRROR=http://maven.aliyun.com/nexus/content/groups/public/
+
+# used to edit maven settings.xml
+RUN apk add --no-cache xmlstarlet
+# change default local repository location. parent image set ~/.m2 as volume, so data won't be persisted for following build cmds
+RUN xmlstarlet ed --inplace -N 's=http://maven.apache.org/SETTINGS/1.0.0' \
+	--subnode '/s:settings' --type elem -n localRepository -v '${user.home}/m2/repository' \
+	/usr/share/maven/conf/settings.xml
+RUN if test -n "$LOCAL_MAVEN_MIRROR"; then \
+	xmlstarlet ed --inplace -N 's=http://maven.apache.org/SETTINGS/1.0.0' \
+		--subnode '/s:settings/s:mirrors' --type elem -n mirror -v '' \
+		/usr/share/maven/conf/settings.xml \
+	&& xmlstarlet ed --inplace -N 's=http://maven.apache.org/SETTINGS/1.0.0' \
+		--subnode '/s:settings/s:mirrors/s:mirror' --type elem -n id -v 'custom-mirror' \
+		/usr/share/maven/conf/settings.xml \
+	&& xmlstarlet ed --inplace -N 's=http://maven.apache.org/SETTINGS/1.0.0' \
+		--subnode '/s:settings/s:mirrors/s:mirror' --type elem -n name -v 'custom-mirror' \
+		/usr/share/maven/conf/settings.xml \
+	&& xmlstarlet ed --inplace -N 's=http://maven.apache.org/SETTINGS/1.0.0' \
+		--subnode '/s:settings/s:mirrors/s:mirror' --type elem -n url -v "$LOCAL_MAVEN_MIRROR" \
+		/usr/share/maven/conf/settings.xml \
+	&& xmlstarlet ed --inplace -N 's=http://maven.apache.org/SETTINGS/1.0.0' \
+		--subnode '/s:settings/s:mirrors/s:mirror' --type elem -n mirrorOf -v 'central' \
+		/usr/share/maven/conf/settings.xml \
+	;fi
+
+# copy lib/ and src/ seperately to leverage cache (lib/ rarely changes)
+COPY ./lib /DWSurvey/lib
+RUN mvn install:install-file -Dfile=/DWSurvey/lib/QRCode.jar -DgroupId=net.qrcode -DartifactId=qrcode -Dversion=1.0 -Dpackaging=jar
+RUN mvn install:install-file -Dfile=/DWSurvey/lib/spssw-1.66.jar -DgroupId=net.spssw -DartifactId=spssw -Dversion=1.66 -Dpackaging=jar
+RUN mvn install:install-file -Dfile=/DWSurvey/lib/xssProtect-0.1.jar -DgroupId=net.xssprotect -DartifactId=xssprotest -Dversion=1.0 -Dpackaging=jar
+
+# if pom.xml is not updates, m2/ may be cached as well
+COPY pom.xml /DWSurvey/pom.xml
+RUN cd /DWSurvey && mvn dependency:resolve
+
+# copy src/ and build, src changes constantly
+COPY ./src /DWSurvey/src
+RUN cd /DWSurvey && mvn install
+
+# ------------------------- 8< -------------------------
+
+# there is a bug with 8.0-jre8-alpine, which was introduced in alpine3.6
+# see: https://bugs.alpinelinux.org/issues/7372
+# image layers: tomcat:8.0-jre8 -> openjdk:8-jre-alpine -> alpine:3.6
+# let's switch to 8.0-jre8-alpine after alpine has fixed the bug (alpine 3.6.3 release)
+FROM tomcat:8.0-jre8
+
+ENV MYSQL_HOST= MYSQL_PORT=3306 MYSQL_DATABASE= MYSQL_USER= MYSQL_PASSWORD=
+ENV ADMIN_EMAIL= ADMIN_PASSWORD=
+
+# install xmlstarlet to edit configurations
+#RUN apk add --no-cache xmlstarlet mysql-client bash
+RUN apt-get update \
+	&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
+		xmlstarlet \
+		mysql-client \
+	&& rm -rf /var/lib/apt/lists/*
+
+COPY --from=builder /DWSurvey/target/diaowen.war /target/diaowen.war
+COPY docker-entry.sh /docker-entry.sh
+
+# TODO , specify volumes
+
+EXPOSE 8080
+
+ENTRYPOINT [ "/docker-entry.sh" ]

+ 31 - 0
docker-compose.yml

@@ -0,0 +1,31 @@
+version: "3"
+
+services:
+  db:
+    image: mariadb:10.3
+    restart: always
+    volumes:
+      - "mysql-data:/var/lib/mysql"
+    environment:
+      - MYSQL_RANDOM_ROOT_PASSWORD=yes
+      - MYSQL_DATABASE=dwsurvey
+      - MYSQL_USER=dwsurvey
+      - MYSQL_PASSWORD=dwsurvey
+
+  dwsurvey:
+    image: dwsurvey
+    restart: always
+    links:
+      - db
+    environment:
+      - MYSQL_HOST=db
+      - MYSQL_DATABASE=dwsurvey
+      - MYSQL_USER=dwsurvey
+      - MYSQL_PASSWORD=dwsurvey
+      - ADMIN_EMAIL=admin@example.com
+      - ADMIN_PASSWORD=123456
+    ports:
+      - "8080:8080"
+
+volumes:
+  mysql-data: {}

+ 88 - 0
docker-entry.sh

@@ -0,0 +1,88 @@
+#!/bin/bash
+set -e
+
+WAR_FILE=/target/diaowen.war
+WEBAPP_DIR=/usr/local/tomcat/webapps/diaowen
+CONF_DIR=${WEBAPP_DIR}/WEB-INF/classes/conf
+
+require_env() {
+    ENV_NAME="$1"
+    eval ENV_VALUE=\$$ENV_NAME
+
+    if [ -z "$ENV_VALUE" ]; then
+        echo "Missing required environment variable: $ENV_NAME"
+        exit 1
+    fi
+}
+
+init_run() {
+    # check variables required for initialization
+    require_env MYSQL_HOST
+    require_env MYSQL_PORT
+    require_env MYSQL_DATABASE
+    require_env MYSQL_USER
+    require_env MYSQL_PASSWORD
+
+    echo "Unpacking war ..."
+    unzip -x "$WAR_FILE" -d "$WEBAPP_DIR"
+
+    echo "Configuring dwsurvey ..."
+    sed -i "s^jdbc.url=.*\$jdbc.url=jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}?useUnicode=true\&characterEncoding=utf8g;
+            s^jdbc.username=.*\$jdbc.username=${MYSQL_USER}g;
+            s^jdbc.password=.*\$jdbc.password=${MYSQL_PASSWORD}g" \
+                ${CONF_DIR}/application.properties
+    migrate
+}
+
+migrate() {
+    # TODO We should use some migration mechanism.
+    # For now, let's do it in a dirty hacky way.
+    require_env ADMIN_EMAIL
+    require_env ADMIN_PASSWORD
+
+    # DIRTY hack, check if table t_user exist, if exist, skip migration
+    echo "Checking if table t_user exist ..."
+    if [[ $(mysql -N -s -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" --password="$MYSQL_PASSWORD" -e \
+             "SELECT count(*) FROM information_schema.TABLES
+                WHERE (TABLE_SCHEMA='${MYSQL_DATABASE}') AND (TABLE_NAME='t_user')") \
+            -eq 1 ]]; then
+        echo "table t_user exists, skipping migration."
+        return
+    fi
+
+    local MIGRATION_FILE=/tmp/migrate.sql
+    cp ${WEBAPP_DIR}/WEB-INF/classes/conf/sql/dwsurvey.sql $MIGRATION_FILE
+
+    # remove "CREATE DATABASE" clouse, db should be created outside, so no root db account required
+    sed -i '/CREATE DATABASE/d' $MIGRATION_FILE
+    # use the specified database name
+    sed -i "s/USE \`dwsurvey\`;/USE \`${MYSQL_DATABASE}\`;/g" $MIGRATION_FILE
+    # remove default user
+    sed -i '/INSERT INTO `t_user`/d' $MIGRATION_FILE
+    # apply migration file
+    echo "Applying migration ..."
+    mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" --password="$MYSQL_PASSWORD" < $MIGRATION_FILE
+
+    rm -f "$MIGRATION_FILE"
+
+    # create admin user
+    local ADMIN_LOGIN=${ADMIN_EMAIL%%@*} # use email prefix for login
+    local ADMIN_SHA_PASSWORD=$(echo -n "$ADMIN_PASSWORD" | sha1sum | cut -d' ' -f 1)
+    echo "Creating admin user ..."
+    mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" --password="$MYSQL_PASSWORD" "$MYSQL_DATABASE" -e \
+        "INSERT INTO \`t_user\`
+                       (id, email,         login_name,     name,            sha_password,         status, version)
+                VALUES (1, '$ADMIN_EMAIL', '$ADMIN_LOGIN', '$ADMIN_LOGIN', '$ADMIN_SHA_PASSWORD', 1, 1);"
+}
+
+# if webapp directory does not exist, it's first run
+if [ ! -d "$WEBAPP_DIR" ]; then
+    init_run
+fi
+
+# start tomcat
+if [ -z "$@" ]; then
+    catalina.sh run
+else
+    exec "$@"
+fi

+ 1 - 1
pom.xml

@@ -474,7 +474,7 @@
 		<dependency>
 		    <groupId>org.slf4j</groupId>
 		    <artifactId>slf4j-log4j12</artifactId>
-		    <version>1.5.0</version>
+		    <version>1.6.0</version>
 		</dependency>
 		
 		<dependency>