From 1192a228efcddc401f7210890323b5a972a38789 Mon Sep 17 00:00:00 2001 From: Romain de Laage Date: Tue, 1 Nov 2022 17:55:39 +0000 Subject: [PATCH] build(docker): add dedicated ffmpeg image to run video clips' scheduled tasks --- docker/production/.gitlab-ci.yml | 3 + docker/production/app/Dockerfile | 10 +-- docker/production/video-clipper/Dockerfile | 32 ++++++++++ docker/production/video-clipper/entrypoint.sh | 62 +++++++++++++++++++ docs/src/getting-started/docker.md | 29 ++++++++- 5 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 docker/production/video-clipper/Dockerfile create mode 100644 docker/production/video-clipper/entrypoint.sh diff --git a/docker/production/.gitlab-ci.yml b/docker/production/.gitlab-ci.yml index 2a8c05e7..d99889d0 100644 --- a/docker/production/.gitlab-ci.yml +++ b/docker/production/.gitlab-ci.yml @@ -12,6 +12,7 @@ docker-build-rolling: - cp ${DOCKER_HUB_CONFIG} /kaniko/.docker/config.json - /kaniko/executor --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${TAG} - /kaniko/executor --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${TAG} + - /kaniko/executor --context . --dockerfile docker/production/video-clipper/Dockerfile --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${TAG} needs: - pipeline: $PARENT_PIPELINE_ID job: bundle @@ -29,6 +30,7 @@ docker-build-main-release: - export CP_VERSION=$(cat CP_VERSION.env) - /kaniko/executor --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${CP_VERSION} --destination ${DOCKER_IMAGE_WEB_SERVER}:latest - /kaniko/executor --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${CP_VERSION} --destination ${DOCKER_IMAGE_APP}:latest + - /kaniko/executor --context . --dockerfile docker/production/video-clipper/Dockerfile --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${CP_VERSION} --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:latest needs: - pipeline: $PARENT_PIPELINE_ID job: release @@ -48,6 +50,7 @@ docker-build-alpha-beta-release: - export CP_VERSION=$(cat CP_VERSION.env) - /kaniko/executor --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${CP_VERSION} --destination ${DOCKER_IMAGE_WEB_SERVER}:${TAG} - /kaniko/executor --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${CP_VERSION} --destination ${DOCKER_IMAGE_APP}:${TAG} + - /kaniko/executor --context . --dockerfile docker/production/video-clipper/Dockerfile --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${CP_VERSION} --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${TAG} needs: - pipeline: $PARENT_PIPELINE_ID job: release diff --git a/docker/production/app/Dockerfile b/docker/production/app/Dockerfile index bf281d05..2fc667d8 100644 --- a/docker/production/app/Dockerfile +++ b/docker/production/app/Dockerfile @@ -1,10 +1,3 @@ -FROM docker.io/alpine:3.16 AS ffmpeg-downloader - -RUN apk add --no-cache curl && \ - curl https://johnvansickle.com/ffmpeg/releases/ffmpeg-5.1.1-amd64-static.tar.xz -o ffmpeg.tar.xz && \ - mkdir ffmpeg && \ - tar -xJf ffmpeg.tar.xz -C ffmpeg --strip-components 1 - FROM docker.io/php:8.1-fpm-alpine3.16 COPY docker/production/app/entrypoint.sh /entrypoint.sh @@ -12,9 +5,9 @@ COPY docker/production/app/entrypoint.sh /entrypoint.sh COPY docker/production/app/uploads.ini /usr/local/etc/php/conf.d/uploads.ini RUN echo "* * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-activities" > /crontab.txt && \ - echo "* * * * 10 /usr/local/bin/php /opt/castopod/public/index.php scheduled-video-clips" >> /crontab.txt && \ echo "* * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-websub-publish" >> /crontab.txt +# TODO: remove freetype (package and gd support) and ffmpeg RUN apk add --no-cache libpng icu-libs freetype libwebp libjpeg-turbo libxpm ffmpeg && \ apk add --no-cache --virtual .php-ext-build-dep freetype-dev libpng-dev libjpeg-turbo-dev libwebp-dev zlib-dev libxpm-dev icu-dev && \ docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-xpm && \ @@ -23,7 +16,6 @@ RUN apk add --no-cache libpng icu-libs freetype libwebp libjpeg-turbo libxpm ffm apk del .php-ext-build-dep COPY castopod /opt/castopod -COPY --from=ffmpeg-downloader /ffmpeg/ffmpeg /ffmpeg/ffprobe /ffmpeg/qt-faststart /usr/local/bin/ RUN chmod 544 /entrypoint.sh && \ chmod 444 /crontab.txt && \ diff --git a/docker/production/video-clipper/Dockerfile b/docker/production/video-clipper/Dockerfile new file mode 100644 index 00000000..d01ee076 --- /dev/null +++ b/docker/production/video-clipper/Dockerfile @@ -0,0 +1,32 @@ +FROM docker.io/php:8.1-bullseye + +ENV SUPERCRONIC_VERSION=v0.2.1 + +COPY docker/production/video-clipper/entrypoint.sh /entrypoint.sh + +RUN echo "*/2 * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-video-clips" >> /crontab.txt + +RUN apt update && \ + apt install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev libwebp-dev libxpm-dev libicu-dev && \ + docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-xpm && \ + docker-php-ext-install mysqli gd intl && \ + docker-php-ext-enable mysqli gd intl + +RUN apt update && \ + apt install -y ffmpeg curl && \ + curl -OL https://github.com/aptible/supercronic/releases/download/$SUPERCRONIC_VERSION/supercronic-linux-amd64 && \ + mv supercronic-linux-amd64 /usr/local/bin/supercronic && \ + chmod +x /usr/local/bin/supercronic + +COPY castopod /opt/castopod + +RUN chmod 544 /entrypoint.sh && \ + chmod 444 /crontab.txt + +WORKDIR /opt/castopod + +VOLUME /opt/castopod/public/media + +ENTRYPOINT [ "sh", "-c" ] + +CMD [ "/entrypoint.sh" ] diff --git a/docker/production/video-clipper/entrypoint.sh b/docker/production/video-clipper/entrypoint.sh new file mode 100644 index 00000000..638e3dfc --- /dev/null +++ b/docker/production/video-clipper/entrypoint.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +if [ -z "${CP_DATABASE_HOSTNAME}" ] +then + echo "CP_DATABASE_HOSTNAME is empty, using default" + CP_DATABASE_HOSTNAME="mariadb" +fi + +if [ -z "${CP_DATABASE_PREFIX}" ] +then + echo "CP_DATABASE_PREFIX is empty, using default" + CP_DATABASE_PREFIX="cp_" +fi + +if [ -z "${CP_DATABASE_NAME}" ] +then + if [ -z "${MYSQL_DATABASE}" ] + then + echo "When CP_DATABASE_NAME is empty, MYSQL_DATABASE must be set" + exit 1 + fi + + echo "CP_DATABASE_NAME is empty, using mysql variable" + CP_DATABASE_NAME="${MYSQL_DATABASE}" +fi + +if [ -z "${CP_DATABASE_USERNAME}" ] +then + if [ -z "${MYSQL_USER}" ] + then + echo "When CP_DATABASE_USERNAME is empty, MYSQL_USER must be set" + exit 1 + fi + + echo "CP_DATABASE_USERNAME is empty, using mysql variable" + CP_DATABASE_USERNAME="${MYSQL_USER}" +fi + +if [ -z "${CP_DATABASE_PASSWORD}" ] +then + if [ -z "${MYSQL_PASSWORD}" ] + then + echo "When CP_DATABASE_PASSWORD is empty, MYSQL_PASSWORD must be set" + exit 1 + fi + + echo "CP_DATABASE_PASSWORD is empty, using mysql variable" + CP_DATABASE_PASSWORD="${MYSQL_PASSWORD}" +fi + +cat << EOF >> /opt/castopod/.env +database.default.hostname="${CP_DATABASE_HOSTNAME}" +database.default.database="${CP_DATABASE_NAME}" +database.default.username="${CP_DATABASE_USERNAME}" +database.default.password="${CP_DATABASE_PASSWORD}" +database.default.DBPrefix="${CP_DATABASE_PREFIX}" +EOF + +echo "Using config:" +cat /opt/castopod/.env + +supercronic /crontab.txt diff --git a/docs/src/getting-started/docker.md b/docs/src/getting-started/docker.md index e75dd1c9..b2ef420f 100644 --- a/docs/src/getting-started/docker.md +++ b/docs/src/getting-started/docker.md @@ -5,13 +5,15 @@ sidebarDepth: 3 # Official Docker images -Castopod pushes 2 Docker images to the Docker Hub during its automated build +Castopod pushes 3 Docker images to the Docker Hub during its automated build process: - [**`castopod/app`**](https://hub.docker.com/r/castopod/app): the app bundle with all of Castopod dependencies - [**`castopod/web-server`**](https://hub.docker.com/r/castopod/web-server): an Nginx configuration for Castopod +- [**`castopod/video-clipper`**](https://hub.docker.com/r/castopod/video-clipper): + an optional image building videoclips thanks to ffmpeg Additionally, Castopod requires a MySQL-compatible database. A Redis database can be added as a cache handler. @@ -85,6 +87,21 @@ can be added as a cache handler. networks: - castopod-app + # this container is optional + # add this if you want to use the videoclips feature + ffmpeg: + image: castopod/video-clipper:latest + container_name: "castopod-video-clipper" + volumes: + - castopod-media:/opt/castopod/public/media + environment: + MYSQL_DATABASE: castopod + MYSQL_USER: castopod + MYSQL_PASSWORD: changeme + networks: + - castopod-db + restart: unless-stopped + volumes: castopod-media: castopod-db: @@ -117,6 +134,16 @@ can be added as a cache handler. ## Environment Variables +- **castopod/video-clipper** + + | Variable name | Type (`default`) | Default | + | -------------------------- | ---------------- | ---------------- | + | **`CP_DATABASE_HOSTNAME`** | ?string | `"mariadb"` | + | **`CP_DATABASE_NAME`** | ?string | `MYSQL_DATABASE` | + | **`CP_DATABASE_USERNAME`** | ?string | `MYSQL_USER` | + | **`CP_DATABASE_PASSWORD`** | ?string | `MYSQL_PASSWORD` | + | **`CP_DATABASE_PREFIX`** | ?string | `"cp_"` | + - **castopod/app** | Variable name | Type (`default`) | Default |