Browse Source

Merge pull request #4 from StephenPCG/dockerize

加入Dockerize支持
Ke Yuan 8 years ago
parent
commit
dbc0a98903
5 changed files with 230 additions and 1 deletions
  1. 16 0
      .dockerignore
  2. 68 0
      Dockerfile
  3. 37 0
      docker-compose.yml
  4. 108 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/

+ 68 - 0
Dockerfile

@@ -0,0 +1,68 @@
+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 \
+	&& find /DWSurvey/src -type f -exec chmod 640 {} \; \
+	&& 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-alpine
+FROM davidcaste/alpine-tomcat:jre8tomcat8
+
+ENV MYSQL_HOST= MYSQL_PORT=3306 MYSQL_DATABASE= MYSQL_USER= MYSQL_PASSWORD=
+ENV ADMIN_EMAIL= ADMIN_PASSWORD=
+ENV CONTEXT_ROOT=/
+
+RUN apk add --no-cache mysql-client
+
+COPY --from=builder /DWSurvey/target/diaowen.war /diaowen.war
+COPY docker-entry.sh /docker-entry.sh
+
+# TODO this is a dirty hack
+VOLUME ["/dwsurvey/WEB-INF/wjHtml", "/dwsurvey/WEB-INF/classes/conf/site"]
+
+EXPOSE 8080
+
+ENTRYPOINT [ "/docker-entry.sh" ]

+ 37 - 0
docker-compose.yml

@@ -0,0 +1,37 @@
+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
+    volumes:
+      - "dwsurvey-wjHtml:/dwsurvey/WEB-INF/wjHtml"
+      - "dwsurvey-site:/dwsurvey/WEB-INF/classes/conf/site"
+    links:
+      - db
+    environment:
+      - MYSQL_HOST=db
+      - MYSQL_DATABASE=dwsurvey
+      - MYSQL_USER=dwsurvey
+      - MYSQL_PASSWORD=dwsurvey
+      - ADMIN_EMAIL=admin@example.com
+      - ADMIN_PASSWORD=123456
+      - CONTEXT_ROOT=/
+    ports:
+      - "8080:8080"
+
+volumes:
+  mysql-data: {}
+  dwsurvey-wjHtml: {}
+  dwsurvey-site: {}

+ 108 - 0
docker-entry.sh

@@ -0,0 +1,108 @@
+#!/bin/bash
+set -e
+
+WAR_FILE=/diaowen.war
+UNPACK_DIR=/dwsurvey
+WEBAPP_BASE=$CATALINA_HOME/webapps
+
+# determine context root path
+if [[ "x${CONTEXT_ROOT}x" == "xx" || "$CONTEXT_ROOT" == "/" ]]; then
+    CONTEXT_PATH=ROOT
+else
+    CONTEXT_PATH=${CONTEXT_ROOT}
+fi
+WEBAPP_DIR=${WEBAPP_BASE}/${CONTEXT_PATH}
+CONF_DIR=${WEBAPP_DIR}/WEB-INF/classes/conf
+
+require_env() {
+    local ENV_NAME="$1"
+    # if docker provides secret, secret wins env
+    if [[ -r "/run/secrets/$ENV_NAME" ]]; then
+        eval $ENV_NAME=$(cat /run/secrets/$ENV_NAME)
+    fi
+
+    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 ..."
+    mkdir -p "$UNPACK_DIR"
+    unzip -q -x "$WAR_FILE" -d "$UNPACK_DIR" \
+             -x "WEB-INF/wjHtml/*" \
+             -x "WEB-INF/classes/conf/site/*"
+    ln -snf "$UNPACK_DIR" "$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
+    # remove example survey (just don't INSERT anything), meaningless for production usage
+    sed -i '/INSERT INTO/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
+    exec $CATALINA_HOME/bin/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>