Skip to content

Commit

Permalink
refactor docker build
Browse files Browse the repository at this point in the history
Signed-off-by: André Bauer <[email protected]>
  • Loading branch information
monotek authored and mgruner committed Nov 7, 2022
1 parent 0ee93e9 commit d879c67
Show file tree
Hide file tree
Showing 7 changed files with 368 additions and 24 deletions.
24 changes: 0 additions & 24 deletions .github/workflows/build-docker-compose-images.yaml

This file was deleted.

50 changes: 50 additions & 0 deletions .github/workflows/docker-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: docker-ci

on:
pull_request:

jobs:
docker-ci:
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Get version tag in the old way
run: echo ZAMMAD_VERSION="$(git describe --tags | sed -e 's/-[a-z0-9]\{8,\}.*//g')" >> $GITHUB_ENV

- name: Docker metadata action
id: meta
uses: docker/metadata-action@v4
with:
images: |
index.docker.io/zammad/zammad-docker-compose
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'stable') }}
type=raw,value=${{ env.ZAMMAD_VERSION }},enable=${{ github.ref == format('refs/heads/{0}', 'stable') }}
type=raw,value=zammad-${{ env.ZAMMAD_VERSION }},enable=${{ github.ref == format('refs/heads/{0}', 'stable') }}
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
type=sha
- name: Build
id: docker_build
uses: docker/build-push-action@v3
with:
context: .
labels: ${{ steps.meta.outputs.labels }}
# arm64 build takes up to 4 hours
platforms: linux/amd64 #,linux/arm64
push: false
tags: ${{ steps.meta.outputs.tags }}
65 changes: 65 additions & 0 deletions .github/workflows/docker-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: docker-release

on:
push:
branches:
- stable
- develop
tags:
- '*'

jobs:
docker-build-push:
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to docker.io container registry
uses: docker/login-action@v2
with:
registry: index.docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Get version tag in the old way
run: echo ZAMMAD_VERSION="$(git describe --tags | sed -e 's/-[a-z0-9]\{8,\}.*//g')" >> $GITHUB_ENV

- name: Docker metadata action
id: meta
uses: docker/metadata-action@v4
with:
images: |
index.docker.io/zammad/zammad-docker-compose
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'stable') }}
type=raw,value=${{ env.ZAMMAD_VERSION }},enable=${{ github.ref == format('refs/heads/{0}', 'stable') }}
type=raw,value=zammad-${{ env.ZAMMAD_VERSION }},enable=${{ github.ref == format('refs/heads/{0}', 'stable') }}
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{major}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{version}}
type=sha
- name: Build and push
id: docker_build
uses: docker/build-push-action@v3
with:
context: .
labels: ${{ steps.meta.outputs.labels }}
# arm64 build takes up to 4 hours
platforms: linux/amd64 #,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}

- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM node:16.18.0-slim as node


FROM ruby:3.0.4-slim AS builder
ARG DEBIAN_FRONTEND=noninteractive
ARG RAILS_ENV=production
ARG ZAMMAD_TMP_DIR=/tmp/zammad
COPY --from=node /opt /opt
COPY --from=node /usr/local/bin /usr/local/bin
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
WORKDIR ${ZAMMAD_TMP_DIR}
COPY . .
RUN contrib/docker/setup.sh builder


# note: zammad is currently incompatible to alpine because of:
# https://github.com/docker-library/ruby/issues/113
FROM ruby:3.0.4-slim
ARG DEBIAN_FRONTEND=noninteractive
ARG ZAMMAD_DIR=/opt/zammad
ARG ZAMMAD_TMP_DIR=/tmp/zammad
ARG ZAMMAD_USER=zammad
COPY --from=builder ${ZAMMAD_TMP_DIR} ${ZAMMAD_TMP_DIR}
COPY --from=builder /usr/local/bundle /usr/local/bundle
COPY --from=builder ${ZAMMAD_TMP_DIR}/contrib/docker/docker-entrypoint.sh /
WORKDIR ${ZAMMAD_TMP_DIR}
RUN contrib/docker/setup.sh runner
ENTRYPOINT ["/docker-entrypoint.sh"]
USER zammad
WORKDIR ${ZAMMAD_DIR}
11 changes: 11 additions & 0 deletions contrib/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# docker stable image

This docker image is build from our [stable branch](https://github.com/zammad/zammad/tree/stable).

It's used in:
* https://github.com/zammad/zammad-docker-compose
* https://github.com/zammad/zammad-helm

## Status

[![CI Status](https://github.com/zammad/zammad-docker-compose/workflows/ci/badge.svg)](https://github.com/zammad/zammad-docker-compose/actions) [![Docker Pulls](https://badgen.net/docker/pulls/zammad/zammad-docker-compose?icon=docker&label=pulls)](https://hub.docker.com/r/zammad/zammad-docker-compose/)
178 changes: 178 additions & 0 deletions contrib/docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#!/usr/bin/env bash

set -e

: "${AUTOWIZARD_JSON:=''}"
: "${ELASTICSEARCH_ENABLED:=true}"
: "${ELASTICSEARCH_HOST:=zammad-elasticsearch}"
: "${ELASTICSEARCH_PORT:=9200}"
: "${ELASTICSEARCH_SCHEMA:=http}"
: "${ELASTICSEARCH_NAMESPACE:=zammad}"
: "${ELASTICSEARCH_REINDEX:=true}"
: "${ELASTICSEARCH_SSL_VERIFY:=true}"
: "${NGINX_PORT:=8080}"
: "${NGINX_SERVER_NAME:=_}"
: "${NGINX_SERVER_SCHEME:=\$scheme}"
: "${POSTGRESQL_HOST:=zammad-postgresql}"
: "${POSTGRESQL_PORT:=5432}"
: "${POSTGRESQL_USER:=zammad}"
: "${POSTGRESQL_PASS:=zammad}"
: "${POSTGRESQL_DB:=zammad_production}"
: "${POSTGRESQL_DB_CREATE:=true}"
: "${RAILS_ENV:=production}"
: "${RAILS_LOG_TO_STDOUT:=true}"
: "${RAILS_TRUSTED_PROXIES:=['127.0.0.1', '::1']}"
: "${RSYNC_ADDITIONAL_PARAMS:=--no-perms --no-owner}"
: "${ZAMMAD_DIR:=/opt/zammad}"
: "${ZAMMAD_RAILSSERVER_HOST:=zammad-railsserver}"
: "${ZAMMAD_RAILSSERVER_PORT:=3000}"
: "${ZAMMAD_READY_FILE:=${ZAMMAD_DIR}/tmp/zammad.ready}"
: "${ZAMMAD_TMP_DIR:=/tmp/zammad}"
: "${ZAMMAD_WEBSOCKET_HOST:=zammad-websocket}"
: "${ZAMMAD_WEBSOCKET_PORT:=6042}"
: "${ZAMMAD_WEB_CONCURRENCY:=0}"

function check_zammad_ready {
sleep 15
until [ -f "${ZAMMAD_READY_FILE}" ]; do
echo "waiting for init container to finish install or update..."
sleep 10
done
}

# zammad init
if [ "$1" = 'zammad-init' ]; then
# install / update zammad
test -f "${ZAMMAD_READY_FILE}" && rm "${ZAMMAD_READY_FILE}"
# shellcheck disable=SC2086
rsync -a ${RSYNC_ADDITIONAL_PARAMS} --delete --exclude 'public/assets/images/*' --exclude 'storage/fs/*' "${ZAMMAD_TMP_DIR}/" "${ZAMMAD_DIR}"
# shellcheck disable=SC2086
rsync -a ${RSYNC_ADDITIONAL_PARAMS} "${ZAMMAD_TMP_DIR}"/public/assets/images/ "${ZAMMAD_DIR}"/public/assets/images

until (echo > /dev/tcp/"${POSTGRESQL_HOST}"/"${POSTGRESQL_PORT}") &> /dev/null; do
echo "zammad railsserver waiting for postgresql server to be ready..."
sleep 5
done

cd "${ZAMMAD_DIR}"

# configure database
# https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
ESCAPED_POSTGRESQL_PASS=$(echo "$POSTGRESQL_PASS" | sed -e 's/[\/&]/\\&/g')
sed -e "s#.*adapter:.*# adapter: postgresql#g" -e "s#.*database:.*# database: ${POSTGRESQL_DB}#g" -e "s#.*username:.*# username: ${POSTGRESQL_USER}#g" -e "s#.*password:.*# password: ${ESCAPED_POSTGRESQL_PASS}\\n host: ${POSTGRESQL_HOST}\\n port: ${POSTGRESQL_PORT}#g" < contrib/packager.io/database.yml.pkgr > config/database.yml

# configure trusted proxies
sed -i -e "s#config.action_dispatch.trusted_proxies =.*#config.action_dispatch.trusted_proxies = ${RAILS_TRUSTED_PROXIES}#" config/environments/production.rb

# check if database exists / update to new version
echo "initialising / updating database..."
if ! (bundle exec rails r 'puts User.any?' 2> /dev/null | grep -q true); then
if [ "${POSTGRESQL_DB_CREATE}" == "true" ]; then
bundle exec rake db:create
fi
bundle exec rake db:migrate
bundle exec rake db:seed

# create autowizard.json on first install
if base64 -d <<< ${AUTOWIZARD_JSON} &>> /dev/null; then
echo "Saving autowizard json payload..."
base64 -d <<< "${AUTOWIZARD_JSON}" > auto_wizard.json
fi
else
bundle exec rails r "Cache.clear"
bundle exec rake db:migrate
fi

# es config
echo "changing settings..."
if [ "${ELASTICSEARCH_ENABLED}" == "false" ]; then
bundle exec rails r "Setting.set('es_url', '')"
else
bundle exec rails r "Setting.set('es_url', '${ELASTICSEARCH_SCHEMA}://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}')"

bundle exec rails r "Setting.set('es_index', '${ELASTICSEARCH_NAMESPACE}')"

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}/${ELASTICSEARCH_PORT}) &> /dev/null; do
echo "zammad railsserver waiting for elasticsearch server to be ready..."
sleep 5
done

if [ "${ELASTICSEARCH_SSL_VERIFY}" == "false" ]; then
SSL_SKIP_VERIFY="-k"
else
SSL_SKIP_VERIFY=""
fi

if [ "${ELASTICSEARCH_REINDEX}" == "true" ]; then
if ! curl -s "${SSL_SKIP_VERIFY}" "${ELASTICSEARCH_SCHEMA}://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_cat/indices" | grep -q zammad; then
echo "rebuilding es searchindex..."
bundle exec rake zammad:searchindex:rebuild
fi
fi
fi

# create install ready file
echo 'zammad-init' > "${ZAMMAD_READY_FILE}"
fi


# zammad nginx
if [ "$1" = 'zammad-nginx' ]; then
check_zammad_ready

# configure nginx
sed -e "s#\(listen\)\(.*\)80#\1\2${NGINX_PORT}#g" \
-e "s#proxy_set_header X-Forwarded-Proto .*;#proxy_set_header X-Forwarded-Proto ${NGINX_SERVER_SCHEME};#g" \
-e "s#server .*:3000#server ${ZAMMAD_RAILSSERVER_HOST}:${ZAMMAD_RAILSSERVER_PORT}#g" \
-e "s#server .*:6042#server ${ZAMMAD_WEBSOCKET_HOST}:${ZAMMAD_WEBSOCKET_PORT}#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

echo "starting nginx..."

exec /usr/sbin/nginx -g 'daemon off;'
fi


# zammad-railsserver
if [ "$1" = 'zammad-railsserver' ]; then
test -f /opt/zammad/tmp/pids/server.pid && rm /opt/zammad/tmp/pids/server.pid

check_zammad_ready

cd "${ZAMMAD_DIR}"

echo "starting railsserver... with WEB_CONCURRENCY=${ZAMMAD_WEB_CONCURRENCY}"

#shellcheck disable=SC2101
exec bundle exec puma -b tcp://[::]:"${ZAMMAD_RAILSSERVER_PORT}" -w "${ZAMMAD_WEB_CONCURRENCY}" -e "${RAILS_ENV}"
fi


# zammad-scheduler
if [ "$1" = 'zammad-scheduler' ]; then
check_zammad_ready

cd "${ZAMMAD_DIR}"

echo "starting background services..."

exec bundle exec script/background-worker.rb start
fi


# zammad-websocket
if [ "$1" = 'zammad-websocket' ]; then
check_zammad_ready

cd "${ZAMMAD_DIR}"

echo "starting websocket server..."

exec bundle exec script/websocket-server.rb -b 0.0.0.0 -p "${ZAMMAD_WEBSOCKET_PORT}" start
fi
34 changes: 34 additions & 0 deletions contrib/docker/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -e

if [ "$1" = 'builder' ]; then
PACKAGES="build-essential curl git libimlib2-dev libpq-dev shared-mime-info"
elif [ "$1" = 'runner' ]; then
PACKAGES="curl libimlib2 libpq5 nginx rsync"
fi

apt-get update
apt-get upgrade -y
# shellcheck disable=SC2086
apt-get install -y --no-install-recommends ${PACKAGES}
rm -rf /var/lib/apt/lists/*

if [ "$1" = 'builder' ]; then
cd "${ZAMMAD_TMP_DIR}"
bundle config set without 'test development mysql'
bundle install
sed -e 's#.*adapter: postgresql# adapter: nulldb#g' -e 's#.*username:.*# username: postgres#g' -e 's#.*password:.*# password: \n host: zammad-postgresql\n#g' < contrib/packager.io/database.yml.pkgr > config/database.yml
sed -i "/require 'rails\/all'/a require\ 'nulldb'" config/application.rb
touch db/schema.rb
bundle exec rake assets:precompile
rm -r tmp/cache
script/build/cleanup.sh
fi

if [ "$1" = 'runner' ]; then
groupadd -g 1000 "${ZAMMAD_USER}"
useradd -M -d "${ZAMMAD_DIR}" -s /bin/bash -u 1000 -g 1000 "${ZAMMAD_USER}"
sed -i -e "s#user www-data;##g" -e 's#/var/log/nginx/\(access\|error\).log#/dev/stdout#g' -e 's#pid /run/nginx.pid;#pid /tmp/nginx.pid;#g' /etc/nginx/nginx.conf
mkdir -p "${ZAMMAD_DIR}" /var/log/nginx
chown -R "${ZAMMAD_USER}":"${ZAMMAD_USER}" /etc/nginx /var/lib/nginx /var/log/nginx "${ZAMMAD_DIR}" "${ZAMMAD_TMP_DIR}"
fi

0 comments on commit d879c67

Please sign in to comment.