Skip to content

Commit

Permalink
[Feature] Combined Docker image (#150)
Browse files Browse the repository at this point in the history
  • Loading branch information
tchapi authored May 31, 2024
1 parent 0f958e8 commit c385629
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 15 deletions.
38 changes: 26 additions & 12 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
ACCOUNT: tchapi

jobs:
build:
Expand All @@ -18,9 +18,17 @@ jobs:
strategy:
fail-fast: false
matrix:
image:
- davis
- davis-standalone
platform:
- linux/amd64
- linux/arm64
include:
- image: davis
dockerfile: docker/Dockerfile
- image: davis-standalone
dockerfile: docker/Dockerfile-standalone
steps:
-
name: Prepare
Expand All @@ -36,7 +44,7 @@ jobs:
uses: docker/metadata-action@v5
with:
context: git
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
images: ${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ matrix.image }}
# "Push by digest" needs an untagged ref
tags: |
type=raw,value=
Expand All @@ -63,30 +71,36 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: docker/Dockerfile
file: ${{ matrix.dockerfile }}
platforms: ${{ matrix.platform }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ matrix.image }},push-by-digest=true,name-canonical=true,push=true
-
name: Export digest
run: |
mkdir -p /tmp/digests
mkdir -p /tmp/digests/
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
-
name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
name: digests-${{ matrix.image }}_${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
name: Create merged manifest and push to Github Packages
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image:
- davis
- davis-standalone
needs:
- build
steps:
Expand All @@ -98,8 +112,8 @@ jobs:
name: Download digests
uses: actions/download-artifact@v4
with:
path: /tmp/digests
pattern: digests-*
path: /tmp/digests/${{ matrix.image }}/
pattern: digests-${{ matrix.image }}_*
merge-multiple: true
-
name: Set up Docker Buildx
Expand All @@ -115,7 +129,7 @@ jobs:
uses: docker/metadata-action@v5
with:
context: git
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
images: ${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ matrix.image }}
tags: |
type=semver,pattern={{version}}
type=edge,branch=${{ github.ref_name }}
Expand All @@ -128,7 +142,7 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Create manifest list and push
working-directory: /tmp/digests
working-directory: /tmp/digests/${{ matrix.image }}/
run: |
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
Expand All @@ -140,8 +154,8 @@ jobs:
--annotation index:org.opencontainers.image.source="${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.source'] }}" \
--annotation index:org.opencontainers.image.url="${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.url'] }}" \
--annotation index:org.opencontainers.image.revision="${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}" \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
$(printf '${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ matrix.image }}@sha256:%s ' *)
-
name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.ACCOUNT }}/${{ matrix.image }}:${{ steps.meta.outputs.version }}
105 changes: 105 additions & 0 deletions docker/Dockerfile-standalone
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
FROM php:8.2-fpm-alpine

ENV PHP_OPCACHE_MEMORY_CONSUMPTION="256" \
PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10"

LABEL org.opencontainers.image.authors="tchap@tchap.me"
LABEL org.opencontainers.image.url="https://github.com/tchapi/davis/pkgs/container/davis-standalone"
LABEL org.opencontainers.image.description="A simple, fully translatable admin interface for sabre/dav based on Symfony 5 and Bootstrap 4 (Standalone version with reverse-proxy)"

# Run update, and gets basic packages and packages for runtime
RUN apk --no-progress --update add --no-cache \
curl unzip \
# These are for php-intl
icu-libs \
# This one is for IMAP (to provide libc-client.so)
c-client \
# This one for LDAP
libldap \
# These are for GD (map image in mail)
freetype \
libjpeg-turbo \
libpng \
# This is for PostgreSQL
libpq \
# For the webserver and process manager
caddy supervisor

# Intl support
RUN apk --update --virtual build-deps-intl add --no-cache icu-dev \
&& docker-php-ext-install intl \
&& apk del build-deps-intl \
&& rm -rf /tmp/*

# PDO: MySQL
RUN docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install pdo_mysql

# PDO: PostgreSQL
RUN apk --update --virtual build-deps-pg add --no-cache libpq-dev \
&& docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install pgsql pdo_pgsql \
&& apk del build-deps-pg \
&& rm -rf /tmp/*

# GD (map image in mail)
RUN apk --update --virtual build-deps-gd add --no-cache freetype-dev libjpeg-turbo-dev libpng-dev \
&& docker-php-ext-configure gd --with-freetype \
&& docker-php-ext-install gd \
&& docker-php-ext-enable gd \
&& apk del build-deps-gd \
&& rm -rf /tmp/*

# LDAP auth support
RUN apk --update --virtual build-deps-ldap add --no-cache openldap-dev \
&& docker-php-ext-configure ldap \
&& docker-php-ext-install ldap \
&& apk del build-deps-ldap \
&& rm -rf /tmp/*

# IMAP auth support
RUN apk --update --virtual build-deps-imap add --no-cache imap-dev openssl-dev krb5-dev \
&& docker-php-ext-configure imap --with-kerberos --with-imap-ssl \
&& docker-php-ext-install imap \
&& apk del build-deps-imap \
&& rm -rf /tmp/*

# OPCache
RUN docker-php-ext-install opcache
COPY ./docker/configurations/opcache.ini /usr/local/etc/php/conf.d/opcache.ini

# Davis source
# The app folder needs to be owned by www-data so PHP-fpm can execute files
ADD --chown=www-data:www-data . /var/www/davis
WORKDIR /var/www/davis

# Install Composer 2, then dependencies
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN APP_ENV=prod COMPOSER_ALLOW_SUPERUSER=1 composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader

# Caddy: web server
RUN mkdir -p /var/log/caddy
ADD ./docker/configurations/Caddyfile /etc/caddy/Caddyfile

# Supervisor: Process manager
RUN mkdir -p /var/log/supervisor && mkdir -p /var/log/php-fpm
ADD ./docker/configurations/supervisord.conf /etc/supervisord.conf

# We want to use sockets inside the container between Caddy and PHP-fpm
RUN mkdir /var/run/php-fpm && chown -R www-data:www-data /var/run/php-fpm
RUN sed -i 's/listen = /;listen = /' /usr/local/etc/php-fpm.d/www.conf
RUN sed -i 's/listen = 9000/listen = \/var\/run\/php-fpm\/php-fpm.sock/' /usr/local/etc/php-fpm.d/zz-docker.conf

RUN mkdir -p ./var/log ./var/cache && chown -R www-data:www-data ./var

# Cleanup (only useful when using --squash)
RUN docker-php-source delete && \
rm -rf /var/www/davis/docker

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]

HEALTHCHECK --interval=120s --timeout=10s --start-period=30s --retries=3 \
CMD curl --fail http://localhost:9000 || exit 1

# It's the Caddy port, not the PHP-fpm one (as we use sockets)
EXPOSE 9000
28 changes: 28 additions & 0 deletions docker/configurations/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
auto_https off
}

:9000 {
root * /var/www/davis/public
php_fastcgi unix//var/run/php-fpm/php-fpm.sock
file_server {
# Safety net, just in case
hide .git .gitignore
}

# enable compression
encode zstd gzip

# Remove leaky headers
header {
-Server
-X-Powered-By

# keep referrer data off of HTTP connections
Referrer-Policy no-referrer-when-downgrade

# disable clients from sniffing the media type
X-Content-Type-Options nosniff
}

}
File renamed without changes.
31 changes: 31 additions & 0 deletions docker/configurations/supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[supervisord]
nodaemon=true
user=root
pidfile=/run/supervisord.pid
logfile=/dev/null
logfile_maxbytes=0

[unix_http_server]
file=/run/supervisord.sock ; the path to the socket file

[supervisorctl]
serverurl=unix:///run/supervisord.sock ; use a unix:// URL for a unix socket

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[program:caddy]
command=/usr/sbin/caddy run -c /etc/caddy/Caddyfile
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/caddy/access.log
stdout_logfile_maxbytes = 0

[program:php-fpm]
command=/usr/local/sbin/php-fpm --nodaemonize
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/php-fpm/access.log
stdout_logfile_maxbytes = 0
2 changes: 1 addition & 1 deletion docker/docker-compose-postgresql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ services:
volumes:
- davis_www:/var/www/davis
- type: bind
source: ./configurations/davis.conf
source: ./configurations/nginx.conf
target: /etc/nginx/conf.d/default.conf
ports:
- 9000:80
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-compose-sqlite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ services:
volumes:
- davis_www:/var/www/davis
- type: bind
source: ./configurations/davis.conf
source: ./configurations/nginx.conf
target: /etc/nginx/conf.d/default.conf
ports:
- 9000:80
Expand Down
48 changes: 48 additions & 0 deletions docker/docker-compose-standalone.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
version: "3.7"
name: "davis-docker"

services:

mysql:
image: mariadb:10.6.10
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=${DB_DATABASE}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- database:/var/lib/mysql

davis:
build:
context: ../
dockerfile: ./docker/Dockerfile-standalone
image: davis:latest
# If you want to use a prebuilt image from Github
# image: ghcr.io/tchapi/davis-standalone:edge
container_name: davis-standalone
environment:
- APP_ENV=prod
- DATABASE_DRIVER=mysql
- DATABASE_URL=mysql://${DB_USER}:${DB_PASSWORD}@mysql:3306/${DB_DATABASE}?serverVersion=mariadb-10.6.10&charset=utf8mb4
- MAILER_DSN=smtp://${MAIL_USERNAME}:${MAIL_PASSWORD}@${MAIL_HOST}:${MAIL_PORT}
- ADMIN_LOGIN=${ADMIN_LOGIN}
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- AUTH_REALM=${AUTH_REALM}
- AUTH_METHOD=${AUTH_METHOD}
- CALDAV_ENABLED=${CALDAV_ENABLED}
- CARDDAV_ENABLED=${CARDDAV_ENABLED}
- WEBDAV_ENABLED=${WEBDAV_ENABLED}
- WEBDAV_TMP_DIR=${WEBDAV_TMP_DIR}
- WEBDAV_PUBLIC_DIR=${WEBDAV_PUBLIC_DIR}
- INVITE_FROM_ADDRESS=${INVITE_FROM_ADDRESS}
- APP_TIMEZONE=${TIMEZONE}
depends_on:
- mysql
ports:
- 9000:9000

volumes:
database:
name: database
2 changes: 1 addition & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ services:
volumes:
- davis_www:/var/www/davis
- type: bind
source: ./configurations/davis.conf
source: ./configurations/nginx.conf
target: /etc/nginx/conf.d/default.conf
ports:
- 9000:80
Expand Down

0 comments on commit c385629

Please sign in to comment.