├── .dockerignore ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yaml ├── docker-entrypoint ├── pro ├── Dockerfile ├── docker-compose.yaml └── docker-entrypoint └── upgrade.php /.dockerignore: -------------------------------------------------------------------------------- 1 | # comment 2 | *.md 3 | data*/ 4 | pro/ 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | data*/ 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM buildpack-deps:20.04-curl 2 | LABEL maintainer="Swire Chen " 3 | 4 | ENV ZENTAO_VER=18.9 5 | ARG ZENTAO_URL=https://www.zentao.net/dl/zentao/${ZENTAO_VER}/ZenTaoPMS-${ZENTAO_VER}-zbox_amd64.tar.gz 6 | 7 | #ADD https://raw.githubusercontent.com/easysoft/zentaopms/master/www/upgrade.php.tmp /tmp/upgrade.php 8 | COPY upgrade.php /tmp/upgrade.php 9 | 10 | COPY docker-entrypoint /usr/local/bin/docker-entrypoint 11 | 12 | RUN curl --dns-servers 1.2.4.8 -sSL ${ZENTAO_URL} -o /tmp/zbox.tar.gz \ 13 | && chmod +x /usr/local/bin/docker-entrypoint 14 | 15 | HEALTHCHECK --start-period=20s --interval=45s --timeout=3s CMD wget http://localhost/ -O /dev/null || exit 1 16 | 17 | EXPOSE 80 3306 18 | 19 | ENTRYPOINT ["docker-entrypoint"] 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Image for Zentao 2 | [![Docker Build Status](https://img.shields.io/docker/cloud/build/idoop/zentao)](https://hub.docker.com/r/idoop/zentao/) 3 | [![Docker Automated build](https://img.shields.io/docker/automated/idoop/zentao)](https://hub.docker.com/r/idoop/zentao/) 4 | [![Docker Pulls](https://img.shields.io/docker/pulls/idoop/zentao.svg)](https://hub.docker.com/r/idoop/zentao/) 5 | [![Docker Stars](https://img.shields.io/docker/stars/idoop/zentao)](https://hub.docker.com/r/idoop/zentao/) 6 | [![ImageLayers Size](https://img.shields.io/docker/image-size/idoop/zentao/latest)](https://hub.docker.com/r/idoop/zentao/) 7 | [![GitHub stars](https://img.shields.io/github/stars/idoop/zentao)](https://github.com/idoop/zentao) 8 | 9 | Auto build docker image for zentao(禅道),include open source edition and pro edition. 10 | 11 | DockerHub:[https://hub.docker.com/r/idoop/zentao/](https://hub.docker.com/r/idoop/zentao/) 12 | 13 | Office Support:[http://www.zentao.net/](http://www.zentao.net/) 14 | ### Tags 15 | 16 | **Open soure edition** 17 | 18 | - `18.1`,`18.2`,`18.3`,`18.4`,`18.5`,`18.6`,`18.7`,`18.8`,`18.9`,`latest` 19 | - `17.0`,`17.1`,`17.2`,`17.3`,`17.4`,`17.5`,`17.6`,`17.6.1` 20 | - `16.0`,`16.1`,`16.2`,`16.3`,`16.4`,`16.5` 21 | - `15.2`,`15.3`,`15.4`,`15.5`,`15.6`,`15.7`,`15.7.1` 22 | - `15.0.1`, `15.0.2`,`15.0.3`,`15.2` 23 | - `12.0`, `12.0.1`, `12.3`, `12.3.2`, `12.4.4`, `12.5.3` 24 | - `11.3`, `11.4.1`, `11.5.1`, `11.6`, `11.6.1`, `11.6.5`, `11.7` 25 | - `10.0`,`10.1`,`10.3`,`10.4`,`10.5`,`10.6` 26 | - `9.6.3`,`9.7`,`9.8`,`9.8.3` 27 | 28 | **Pro edition** 29 | 30 | - `pro-8.7.1`,`pro` 31 | - `pro-8.2`,`pro-8.3`,`pro-8.4`,`pro-8.5.1`,`pro-8.5.3` 32 | - `pro-7.1`,`pro-7.3`,`pro-7.5.1` 33 | - `pro-6.7.3` 34 | 35 | ### QuickStart 36 | 37 | open soure edition: 38 | ``` bash 39 | mkdir -p /data/zbox && \ 40 | docker run -d -p 80:80 -p 3306:3306 \ 41 | -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ 42 | -e BIND_ADDRESS="false" \ 43 | -v /data/zbox/:/opt/zbox/ \ 44 | --add-host smtp.exmail.qq.com:163.177.90.125 \ 45 | --name zentao-server \ 46 | idoop/zentao:latest 47 | ``` 48 | 49 | pro edition: 50 | ``` bash 51 | mkdir -p /data/zbox && \ 52 | docker run -d -p 80:80 -p 3306:3306 \ 53 | -e USER="root" -e PASSWD="password" \ 54 | -e BIND_ADDRESS="false" \ 55 | -v /data/zbox/:/opt/zbox/ \ 56 | --add-host smtp.exmail.qq.com:163.177.90.125 \ 57 | --name zentao-server-pro \ 58 | idoop/zentao:pro 59 | ``` 60 | 61 | Note: Make sure your Host feed available on either port `80` or `3306`. 62 | 63 | ### Environment configuration 64 | 65 | * `ADMINER_USER` : set the database Adminer account. 66 | * `ADMINER_PASSWD` : set the database Adminer password. 67 | * `BIND_ADDRESS` : if set value with `false`,the MySQL server will not bind address. 68 | * `SMTP_HOST` : set the smtp server IP and host.(If can't send mail,it will be helpful.) Can also use `extra_host` in docker-compose.yaml,or use param `--add-host` when use `dokcer run` command. 69 | 70 | Note: The Zentao web login administrator account is **admin**,and default initialization password is **123456**. 71 | And MySQL root account password is **123456**,please change password when you first login. 72 | 73 | ### Upgrade Version 74 | 75 | > If you want upgrade the zentao version, just run a container with the latest docker image and mount the same zbox path `$volume/zbox/`. 76 | 77 | ``` bash 78 | # stop and backup old container 79 | docker stop zentao-server 80 | docker rename zentao-server zentao-server-bak 81 | # backup zbox 82 | cp -r /data/zbox /data/zbox-bak 83 | # pull the latest image 84 | docker pull idoop/zentao:latest 85 | # run new container with the latest image and mount the same path 86 | docker run -d -p 80:80 -p 3306:3306 \ 87 | -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ 88 | -e BIND_ADDRESS="false" \ 89 | -v /data/zbox/:/opt/zbox/ \ 90 | --add-host smtp.exmail.qq.com:163.177.90.125 \ 91 | --name zentao-server \ 92 | idoop/zentao:latest 93 | docker logs -f zentao-server 94 | ``` 95 | You will see the upgrading process logs like following. 96 | ``` 97 | Installed Zentao version: 11.0 98 | New Zentao version: 11.4 99 | Backuping config/my.php and upload ... 100 | Upgrading Zentao ... 101 | Restoring config/my.php and upload ... 102 | Upgraded Zentao version to: 11.4 103 | Please visit your Zentao website to complete the upgrade task. 104 | ZBOX是Apache、Mysql、PHP的精简的集成环境。使用时,需要将其解压到/opt目录。 105 | 106 | /opt/zbox/zbox -h 可以获取帮助 107 | /opt/zbox/zbox start 启动脚本 108 | 109 | Mysql 用户名root,密码为123456。 110 | 111 | 更多可以访问http://www.zentao.net/goto.php?item=zbox. 112 | Start Apache success 113 | Start Mysql success 114 | Start xxd success 115 | ``` 116 | 117 | Wait until `Start xxd success`, visit your zentao website to complete the upgrade task step by step. 118 | After you complete the upgrade task in your zentao website and confirm everything looks good, delete the backups to save your disk space.`docker rm -f zentao-server-bak && rm -rf /data/zbox-bak` 119 | > [See Detail](https://www.zentao.net/book/zentaopmshelp/67.html) 120 | 121 | ### Building the image 122 | 123 | Clone this repo, modify `Dockerfile` or `docker-entrypoint` if you want. 124 | Then execute the following command: 125 | 126 | ``` bash 127 | docker build -t zentao . 128 | ``` 129 | 130 | ### FAQ 131 | upgrade or auto remove plugins when restart? 132 | 133 | added `ZENTAO_VER` env when u startup (e.g. `-e ZENTAO_VER="12.3.stable"`, because Dockerfile's `ZENTAO_VER` (that is `12.3.2`) not eq `cat /opt/zbox/app/zentao/VERSION` (that is `12.3.stable` )) 134 | 135 | ```bash 136 | docker run -d -p 80:80 -p 3306:3306 \ 137 | -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ 138 | -e BIND_ADDRESS="false" \ 139 | -e ZENTAO_VER="12.3.stable" \ 140 | -v /data/zbox/:/opt/zbox/ \ 141 | --add-host smtp.exmail.qq.com:163.177.90.125 \ 142 | --name zentao-server \ 143 | idoop/zentao:latest 144 | ``` 145 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "2.2" 2 | services: 3 | zentao: 4 | image: idoop/zentao:latest 5 | container_name: zentao 6 | # if web response code: 310 ERR_TOO_MANY_REDIRECTS, please use host mode. 7 | # network_mode: "host" 8 | ports: 9 | - "80:80" 10 | - "3306:3306" 11 | # mysql root account default password is '123456'. 12 | # the zentao adminstrator account is 'admin',and init password is '123456'. 13 | environment: 14 | # specifies Adminer account and password for web login database. 15 | USER: "root" 16 | PASSWD: "123456" 17 | BIND_ADDRESS: "false" 18 | extra_hosts: 19 | - "smtp.exmail.qq.com:163.177.90.125" 20 | volumes: 21 | - ./data:/opt/zbox/ 22 | restart: always 23 | -------------------------------------------------------------------------------- /docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | MYSQL_CONFIG="/opt/zbox/etc/mysql/my.cnf" 5 | VERSION_FILE="/opt/zbox/app/zentao/VERSION" 6 | 7 | export PATH=/opt/zbox/:$PATH 8 | if [ "${1:0:1}" == "-" ]; then 9 | zbox --help 10 | elif [ "$#" == "0" ]; then 11 | # if the container run firstly 12 | if [ ! -d "/opt/zbox" -o ! -d "/opt/zbox/app" ]; then 13 | echo "Installing Zentao version: ${ZENTAO_VER} ..." 14 | tar -zxf /tmp/zbox.tar.gz -C /opt/ 15 | rm -rf /opt/zbox/app/zentao[ep]* 16 | 17 | if [[ "${BIND_ADDRESS}" == [fF][aA][lL][sS][eE] ]] && [ -f "${MYSQL_CONFIG}" ]; then 18 | sed -e 's/^bind-address.*$/bind-address = 0.0.0.0/' -i ${MYSQL_CONFIG} 19 | fi 20 | 21 | elif [ -f "${VERSION_FILE}" -a `cat ${VERSION_FILE}` != ${ZENTAO_VER} ]; then 22 | CURRENT_VER=`cat ${VERSION_FILE}` 23 | echo -e "The Zentao need update.\n Old version: $CURRENT_VER \n New version: $ZENTAO_VER" 24 | # upgrade zentao version 25 | echo "Backuping config / my.php / upload ..." 26 | cp /opt/zbox/app/zentao/config/my.php /opt/zbox/app/ 27 | mv /opt/zbox/app/zentao/www/data/upload /opt/zbox/app/ 28 | rm -rf /opt/zbox/app/zentao 29 | 30 | echo "Upgrading..." 31 | tar -zxf /tmp/zbox.tar.gz -C /tmp/ 32 | mv /tmp/zbox/app/zentao /opt/zbox/app/ 33 | mv /tmp/upgrade.php /opt/zbox/app/zentao/www/ 34 | chmod 664 /opt/zbox/app/zentao/www/upgrade.php 35 | rm -rf /opt/zbox/tmp/apache/httpd.pid /tmp/* 36 | 37 | echo "Restoring config / my.php / upload ..." 38 | mv /opt/zbox/app/my.php /opt/zbox/app/zentao/config/my.php 39 | rm -rf /opt/zbox/app/zentao/www/data/upload 40 | mv /opt/zbox/app/upload /opt/zbox/app/zentao/www/data/ 41 | touch /opt/zbox/app/zentao/www/ok.txt 42 | echo "Upgraded Zentao version to: ${ZENTAO_VER}\nPlease visit your Zentao website to complete the upgrade task." 43 | fi 44 | 45 | # add apache http password for adminer 46 | if [ -n "${ADMINER_USER}" -a -n "${ADMINER_PASSWD}" ]; then 47 | /opt/zbox/bin/htpasswd -b /opt/zbox/auth/users ${ADMINER_USER} ${ADMINER_PASSWD} 48 | chmod 0644 /opt/zbox/auth/users 49 | fi 50 | # compatible old version 51 | if [ -n "${USER}" -a -n "${PASSWD}" ]; then 52 | /opt/zbox/bin/htpasswd -b /opt/zbox/auth/users ${USER} ${PASSWD} 53 | chmod 0644 /opt/zbox/auth/users 54 | fi 55 | 56 | # add smtp server ip to hosts 57 | if [ -n "${SMTP_HOST}" ];then 58 | #IS_EXIST_SMTP_HOST=`grep "${SMTP_HOST}" /etc/hosts` 59 | #if [ -z "${IS_EXIST_SMTP_HOST}"];then 60 | echo "${SMTP_HOST}" >> /etc/hosts 61 | #fi 62 | fi 63 | 64 | # auto location / to /zentao/ 65 | echo "" > /opt/zbox/app/htdocs/index.html 66 | 67 | # start service and health check 68 | cat /opt/zbox/README 69 | zbox start 70 | tail -f /dev/null 71 | else 72 | exec "$@" 73 | fi 74 | -------------------------------------------------------------------------------- /pro/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM buildpack-deps:18.04-curl 2 | MAINTAINER Swire Chen 3 | 4 | ENV ZENTAO_VER=8.7.1 5 | 6 | ARG ZENTAO_URL=http://dl.cnezsoft.com/zentao/pro${ZENTAO_VER}/ZenTaoPMS.pro${ZENTAO_VER}.zbox_64.tar.gz 7 | 8 | COPY docker-entrypoint /usr/local/bin/docker-entrypoint 9 | 10 | RUN curl -s ${ZENTAO_URL} -o zbox.tar.gz && mv zbox.tar.gz /tmp \ 11 | && chmod +x /usr/local/bin/docker-entrypoint 12 | 13 | HEALTHCHECK --start-period=20s --interval=45s --timeout=3s CMD wget http://localhost/ -O /dev/null || exit 1 14 | 15 | EXPOSE 80 3306 16 | 17 | ENTRYPOINT ["docker-entrypoint"] 18 | -------------------------------------------------------------------------------- /pro/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "2.2" 2 | services: 3 | zentao: 4 | image: idoop/zentao:pro 5 | container_name: zentaopro 6 | ports: 7 | - "80:80" 8 | - "3306:3306" 9 | # if web response code: 310 ERR_TOO_MANY_REDIRECTS, please use host mode. 10 | # network_mode: "host" 11 | environment: 12 | # specifies you own account and password. 13 | USER: "root" 14 | PASSWD: "123456" 15 | BIND_ADDRESS: "false" 16 | extra_hosts: 17 | - "smtp.exmail.qq.com:163.177.90.125" 18 | volumes: 19 | # specifies the path replace "./data". 20 | - ./data:/opt/zbox/ 21 | restart: always 22 | -------------------------------------------------------------------------------- /pro/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | MYSQL_CONFIG="/opt/zbox/etc/mysql/my.cnf" 5 | APACHE_CONFIG="/opt/zbox/etc/apache/httpd.conf" 6 | 7 | if [ "${1:0:1}" == "-" ]; then 8 | zbox --help 9 | elif [ "$#" == "0" ]; then 10 | if [ ! -d "/opt/zbox" ]; then 11 | tar -zxf /tmp/zbox.tar.gz -C /opt/ 12 | if [[ "${BIND_ADDRESS}" == [fF][aA][lL][sS][eE] ]] && [ -f "${MYSQL_CONFIG}" ]; then 13 | #sed -Ei 's/^bind-address/#&/' ${MYSQL_CONFIG} 14 | sed -e 's/^bind-address.*$/bind-address = 0.0.0.0/' -i ${MYSQL_CONFIG} 15 | fi 16 | else 17 | WORK_DIR=`ls /opt/zbox` 18 | if [ -z "${WORK_DIR}" ];then 19 | tar -zxf /tmp/zbox.tar.gz -C /opt/ 20 | if [[ "${BIND_ADDRESS}" == [fF][aA][lL][sS][eE] ]] && [ -f "${MYSQL_CONFIG}" ]; then 21 | #sed -Ei 's/^bind-address/#&/' ${MYSQL_CONFIG} 22 | sed -e 's/^bind-address.*$/bind-address = 0.0.0.0/' -i ${MYSQL_CONFIG} 23 | fi 24 | fi 25 | fi 26 | export PATH=/opt/zbox/:$PATH 27 | cat /opt/zbox/README && zbox start 28 | if [ -n "${USER}" -a -n "${PASSWD}" ]; then 29 | /opt/zbox/bin/htpasswd -b /opt/zbox/auth/users ${USER} ${PASSWD} 30 | chmod 0644 /opt/zbox/auth/users 31 | fi 32 | 33 | if [ -n "${SMTP_HOST}" ];then 34 | echo "${SMTP_HOST}" >> /etc/hosts 35 | fi 36 | sleep 120 37 | loop=1 38 | while [ ${loop} -eq 1 ] 39 | do 40 | wget http://localhost/ -O /dev/null || exit 1 41 | sleep 30 42 | done 43 | else 44 | exec "$@" 45 | fi 46 | -------------------------------------------------------------------------------- /upgrade.php: -------------------------------------------------------------------------------- 1 | 8 | * @package ZenTaoPMS 9 | * @version $Id: upgrade.php 4677 2013-04-26 06:23:58Z chencongzhi520@gmail.com $ 10 | * @link http://www.zentao.net 11 | */ 12 | /* Judge my.php exists or not. */ 13 | define('IN_UPGRADE', true); 14 | $dbConfig = dirname(dirname(__FILE__)) . '/config/db.php'; 15 | $myConfig = dirname(dirname(__FILE__)) . '/config/my.php'; 16 | if(file_exists($dbConfig)) 17 | { 18 | if(file_exists($myConfig)) 19 | { 20 | $myContent = trim(file_get_contents($myConfig)); 21 | $myContent = str_replace('"; 28 | echo "Please execute the command 'chmod 777 $configDir' to modify the permissions to ensure that the ZenTao has operating file permissions in this directory"; 29 | exit; 30 | } 31 | 32 | if(!empty($myContent)) 33 | { 34 | $myContent = file_get_contents($myConfig) . "\n" . $myContent; 35 | file_put_contents($myConfig, $myContent); 36 | } 37 | } 38 | if(!file_exists($myConfig)) die(header('location: install.php')); 39 | 40 | error_reporting(0); 41 | 42 | /* Load the framework. */ 43 | include '../framework/router.class.php'; 44 | include '../framework/control.class.php'; 45 | include '../framework/model.class.php'; 46 | include '../framework/helper.class.php'; 47 | 48 | /* Instance the app. */ 49 | $app = router::createApp('pms', dirname(dirname(__FILE__)), 'router'); 50 | $common = $app->loadCommon(); 51 | 52 | /* Reset the config params to make sure the install program will be lauched. */ 53 | $config->set('requestType', 'GET'); 54 | $config->set('default.module', 'upgrade'); 55 | $app->setDebug(); 56 | 57 | /* Check the installed version is the latest or not. */ 58 | $config->installedVersion = $common->loadModel('setting')->getVersion(); 59 | if(($config->version[0] == $config->installedVersion[0] or (is_numeric($config->version[0]) and is_numeric($config->installedVersion[0]))) and version_compare($config->version, $config->installedVersion) <= 0) die(header('location: index.php')); 60 | 61 | /* Run it. */ 62 | $app->parseRequest(); 63 | $common->checkUpgradeStatus(); 64 | $app->loadModule(); 65 | --------------------------------------------------------------------------------