diff --git a/containers/zammad-postgresql/backup.sh b/containers/zammad-postgresql/backup.sh index 3db010e..02cf4b4 100644 --- a/containers/zammad-postgresql/backup.sh +++ b/containers/zammad-postgresql/backup.sh @@ -2,8 +2,10 @@ set -e +: "${ZAMMAD_RAILSSERVER_HOST:=zammad-railsserver}" + function check_railsserver_available { - until (echo > /dev/tcp/zammad-railsserver/3000) &> /dev/null; do + until (echo > /dev/tcp/${ZAMMAD_RAILSSERVER_HOST}/3000) &> /dev/null; do echo "waiting for railsserver to be ready..." sleep 60 done @@ -19,8 +21,10 @@ function zammad_backup { find ${BACKUP_DIR}/*_zammad_*.gz -type f -mtime +${HOLD_DAYS} -exec rm {} \; fi - # tar files - tar -czf ${BACKUP_DIR}/${TIMESTAMP}_zammad_files.tar.gz ${ZAMMAD_DIR} + if [ "${NO_FILE_BACKUP}" != "yes" ]; then + # tar files + tar -czf ${BACKUP_DIR}/${TIMESTAMP}_zammad_files.tar.gz ${ZAMMAD_DIR} + fi #db backup pg_dump --dbname=postgresql://postgres@zammad-postgresql:5432/zammad_production | gzip > ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.psql.gz @@ -43,3 +47,9 @@ if [ "$1" = 'zammad-backup-once' ]; then zammad_backup fi + +if [ "$1" = 'zammad-backup-db' ]; then + NO_FILE_BACKUP="yes" + + zammad_backup +fi diff --git a/containers/zammad/Dockerfile b/containers/zammad/Dockerfile index 3ab2e76..455ea40 100644 --- a/containers/zammad/Dockerfile +++ b/containers/zammad/Dockerfile @@ -3,12 +3,14 @@ MAINTAINER Zammad ARG BUILD_DATE ENV ZAMMAD_DIR /opt/zammad -ENV ZAMMAD_TMP_DIR /tmp/zammad ENV ZAMMAD_USER zammad ENV RAILS_ENV production ENV RAILS_SERVER puma -ENV GIT_URL https://github.com/zammad/zammad.git +ENV PROJECT_URL https://github.com/zammad/zammad +ENV GIT_URL ${PROJECT_URL}.git ENV GIT_BRANCH develop +ENV ZAMMAD_TMP_DIR /tmp/zammad-${GIT_BRANCH} +ENV TAR_GZ_URL ${PROJECT_URL}/archive/${GIT_BRANCH}.tar.gz ENV GOSU_VERSION 1.10 ENV ZAMMAD_READY_FILE tmp/zammad.ready @@ -23,31 +25,32 @@ LABEL org.label-schema.build-date="$BUILD_DATE" \ org.label-schema.schema-version="1.2" \ org.label-schema.docker.cmd="sysctl -w vm.max_map_count=262144;docker-compose up" -# install dependencies, GOSU & zammad -RUN BUILD_DEPENDENCIES="git build-essential libffi-dev libpq5 libpq-dev nginx rsync" \ - GOSU_DEPENDENCIES="ca-certificates wget" \ +# install dependencies & gosu +RUN BUILD_DEPENDENCIES="build-essential ca-certificates curl git libffi-dev libpq5 libpq-dev nginx rsync" \ set -ex \ - && apt-get update && apt-get install -y --force-yes --no-install-recommends ${BUILD_DEPENDENCIES} ${GOSU_DEPENDENCIES} && rm -rf /var/lib/apt/lists/* \ - && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \ - && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \ + && apt-get update && apt-get install -y --force-yes --no-install-recommends ${BUILD_DEPENDENCIES} && rm -rf /var/lib/apt/lists/* \ + && curl -s -J -L -o /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-$(dpkg --print-architecture)" \ + && curl -s -J -L -o /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-$(dpkg --print-architecture).asc" \ && export GNUPGHOME="$(mktemp -d)" \ && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \ && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \ && rm -rf "${GNUPGHOME}" /usr/local/bin/gosu.asc \ && chmod +x /usr/local/bin/gosu \ - && gosu nobody true \ - && useradd -M -d ${ZAMMAD_DIR} -s /bin/bash ${ZAMMAD_USER} \ + && gosu nobody true + +# install zammad +RUN groupadd -g 1000 ${ZAMMAD_USER} \ + && useradd -M -d ${ZAMMAD_DIR} -s /bin/bash -u 1000 -g 1000 ${ZAMMAD_USER} \ && cd $(dirname ${ZAMMAD_TMP_DIR}) \ - && git clone --depth 1 -b "${GIT_BRANCH}" "${GIT_URL}" \ + && curl -s -J -L -O "${TAR_GZ_URL}" \ + && tar -xzf zammad-${GIT_BRANCH}.tar.gz \ + && rm zammad-${GIT_BRANCH}.tar.gz \ && cd ${ZAMMAD_TMP_DIR} \ && bundle install --without test development mysql \ && contrib/packager.io/fetch_locales.rb \ && sed -e 's#.*adapter: postgresql# adapter: nulldb#g' -e 's#.*username:.*# username: postgres#g' -e 's#.*password:.*# password: \n host: zammad-postgresql\n#g' < config/database.yml.pkgr > config/database.yml \ && bundle exec rake assets:precompile \ - && sed -e 's#.*adapter: postgresql# adapter: postgresql#g' -e 's#.*username:.*# username: postgres#g' -e 's#.*password:.*# password: \n host: zammad-postgresql\n#g' < config/database.yml.pkgr > config/database.yml \ && rm -r tmp/cache \ - && sed -i -e "s/.*config.cache_store.*file_store.*cache_file_store.*/ config.cache_store = :dalli_store, 'zammad-memcached:11211'\n config.session_store = :dalli_store, 'zammad-memcached:11211'/" config/application.rb \ - && sed -e 's#server localhost:3000#server zammad-railsserver:3000#g' -e 's#localhost:6042#zammad-websocket:6042#g' -e 's#server_name localhost#server_name _#g' -e 's#.*\(access\|error\)_log.*log;##g' < contrib/nginx/zammad.conf > /etc/nginx/sites-enabled/default \ && chown -R ${ZAMMAD_USER}:${ZAMMAD_USER} ${ZAMMAD_TMP_DIR} # docker init diff --git a/containers/zammad/docker-entrypoint.sh b/containers/zammad/docker-entrypoint.sh index e5e31d7..94553f6 100644 --- a/containers/zammad/docker-entrypoint.sh +++ b/containers/zammad/docker-entrypoint.sh @@ -2,6 +2,15 @@ set -e +: "${ELASTICSEARCH_HOST:=zammad-elasticsearch}" +: "${MEMCACHED_HOST:=zammad-memcached}" +: "${POSTGRESQL_HOST:=zammad-postgresql}" +: "${POSTGRESQL_USER:=postgres}" +: "${POSTGRESQL_PASS:=}" +: "${ZAMMAD_RAILSSERVER_HOST:=zammad-railsserver}" +: "${ZAMMAD_WEBSOCKET_HOST:=zammad-websocket}" +: "${NGINX_SERVER_NAME:=_}" + function check_zammad_ready { until [ -f "${ZAMMAD_DIR}/${ZAMMAD_READY_FILE}" ]; do echo "waiting for install or update to be ready..." @@ -11,7 +20,7 @@ function check_zammad_ready { # zammad init if [ "$1" = 'zammad-init' ]; then - until (echo > /dev/tcp/zammad-postgresql/5432) &> /dev/null; do + until (echo > /dev/tcp/${POSTGRESQL_HOST}/5432) &> /dev/null; do echo "zammad railsserver waiting for postgresql server to be ready..." sleep 5 done @@ -22,6 +31,10 @@ if [ "$1" = 'zammad-init' ]; then cd ${ZAMMAD_DIR} + # configure database & cache + sed -e "s#.*adapter:.*# adapter: postgresql#g" -e "s#.*username:.*# username: ${POSTGRESQL_USER}#g" -e "s#.*password:.*# password: ${POSTGRESQL_PASS}\n host: ${POSTGRESQL_HOST}\n#g" < config/database.yml.pkgr > config/database.yml + sed -i -e "s/.*config.cache_store.*file_store.*cache_file_store.*/ config.cache_store = :dalli_store, '${MEMCACHED_HOST}:11211'\n config.session_store = :dalli_store, '${MEMCACHED_HOST}:11211'/" config/application.rb + echo "initialising / updating database..." # db mirgrate set +e @@ -37,9 +50,14 @@ if [ "$1" = 'zammad-init' ]; then echo "changing settings..." # es config - bundle exec rails r "Setting.set('es_url', 'http://zammad-elasticsearch:9200')" + bundle exec rails r "Setting.set('es_url', 'http://${ELASTICSEARCH_HOST}:9200')" - until (echo > /dev/tcp/zammad-elasticsearch/9200) &> /dev/null; do + if [ -n "${ELASTICSEARCH_USER}" ] && [ -n "${ELASTICSEARCH_PASS}" ]; then + bundle exec rails r "Setting.set('es_user', \"${ELASTICSEARCH_USER}\")" + bundle exec rails r "Setting.set('es_password', \"${ELASTICSEARCH_PASS}\")" + fi + + until (echo > /dev/tcp/${ELASTICSEARCH_HOST}/9200) &> /dev/null; do echo "zammad railsserver waiting for elasticsearch server to be ready..." sleep 5 done @@ -57,6 +75,11 @@ fi # zammad nginx if [ "$1" = 'zammad-nginx' ]; then + # configure nginx + if [ -z "$(env|grep KUBERNETES)" ]; then + sed -e "s#server .*:3000#server ${ZAMMAD_RAILSSERVER_HOST}:3000#g" -e "s#server .*:6042#server ${ZAMMAD_WEBSOCKET_HOST}:6042#g" -e "s#server_name .*#server_name ${NGINX_SERVER_NAME};#g" -e 's#/var/log/nginx/zammad.\(access\|error\).log#/dev/stdout#g' < contrib/nginx/zammad.conf > /etc/nginx/sites-enabled/default + fi + until [ -f "${ZAMMAD_DIR}/${ZAMMAD_READY_FILE}" ] && [ -n "$(grep zammad-railsserver < ${ZAMMAD_DIR}/${ZAMMAD_READY_FILE})" ] && [ -n "$(grep zammad-scheduler < ${ZAMMAD_DIR}/${ZAMMAD_READY_FILE})" ] && [ -n "$(grep zammad-websocket < ${ZAMMAD_DIR}/${ZAMMAD_READY_FILE})" ] ; do echo "waiting for all zammad services to start..." sleep 5 @@ -80,7 +103,7 @@ if [ "$1" = 'zammad-railsserver' ]; then echo "zammad-railsserver" >> ${ZAMMAD_DIR}/${ZAMMAD_READY_FILE} - exec gosu ${ZAMMAD_USER}:${ZAMMAD_USER} bundle exec puma -b tcp://0.0.0.0:3000 -e ${RAILS_ENV} + exec gosu ${ZAMMAD_USER}:${ZAMMAD_USER} bundle exec rails server puma -b [::] -p 3000 -e ${RAILS_ENV} fi @@ -108,5 +131,5 @@ if [ "$1" = 'zammad-websocket' ]; then echo "zammad-websocket" >> ${ZAMMAD_DIR}/${ZAMMAD_READY_FILE} - exec gosu ${ZAMMAD_USER}:${ZAMMAD_USER} bundle exec script/websocket-server.rb -b 0.0.0.0 start + exec gosu ${ZAMMAD_USER}:${ZAMMAD_USER} bundle exec script/websocket-server.rb -b 0.0.0.0 -p 6042 start fi diff --git a/docker-compose.yml b/docker-compose.yml index 9dccbfb..158eadb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,6 +65,8 @@ services: labels: io.rancher.container.pull_image: always restart: always + volumes: + - postgresql-data:/var/lib/postgresql/data zammad-railsserver: command: ["zammad-railsserver"] @@ -116,6 +118,8 @@ services: volumes: elasticsearch-data: driver: local + postgresql-data: + driver: local zammad-backup: driver: local zammad-data: diff --git a/kubernetes/10_pvc.yaml b/kubernetes/10_pvc.yaml index 9f849f1..6f28253 100644 --- a/kubernetes/10_pvc.yaml +++ b/kubernetes/10_pvc.yaml @@ -12,6 +12,20 @@ spec: requests: storage: 10G +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: zammad-backup + namespace: zammad +spec: + storageClassName: standard + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10G + --- kind: PersistentVolumeClaim apiVersion: v1 @@ -25,7 +39,7 @@ spec: resources: requests: storage: 10G - + --- kind: PersistentVolumeClaim apiVersion: v1 diff --git a/kubernetes/30_configmap_nginx.yaml b/kubernetes/30_configmap_nginx.yaml index 8e50fd4..0712910 100644 --- a/kubernetes/30_configmap_nginx.yaml +++ b/kubernetes/30_configmap_nginx.yaml @@ -26,6 +26,9 @@ data: root /opt/zammad/public; + access_log /dev/stdout; + error_log /dev/stderr; + client_max_body_size 50M; location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico) { diff --git a/kubernetes/60_cronjob_backup.yaml b/kubernetes/60_cronjob_backup.yaml new file mode 100644 index 0000000..6bbbf09 --- /dev/null +++ b/kubernetes/60_cronjob_backup.yaml @@ -0,0 +1,23 @@ +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: backup + namespace: zammad +spec: + schedule: "0 0 * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + volumes: + - name: zammad-backup + persistentVolumeClaim: + claimName: zammad-backup + containers: + - name: zammad-backup + image: zammad/zammad-docker-compose:zammad-postgresql + args: [ "zammad-backup-db" ] + volumeMounts: + - name: zammad-backup + mountPath: /var/tmp/zammad diff --git a/kubernetes/Readme.md b/kubernetes/Readme.md index bf2d561..58431db 100644 --- a/kubernetes/Readme.md +++ b/kubernetes/Readme.md @@ -37,8 +37,6 @@ beta and not ready for production. ## If you want to help to improve the Kuberntes deployments here are some todos: -* create a zammad helm chart -* document steps to use existing helm charts for elasticsearch, postgresql and so on * add cpu & mem limits * add rolling upgrade strategy to deployments * add RBAC