From f310943c1c1d82a64ee7a70a225eeef067f61c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20de=20Saint=20Martin?= Date: Mon, 29 May 2023 23:16:37 +0200 Subject: [PATCH 1/5] feat(docker): add basic docker support --- .dockerignore | 50 ++++++++++++++++++++++++++++++++++++++++++++++ Dockerfile | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..d283a30d55 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,50 @@ +documentation +.dockerignore +Dockerfile +.git +.git* +*.md + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events.json +speed-measure-plugin.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +.history/* + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +# testing +junit.xml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..505106c9be --- /dev/null +++ b/Dockerfile @@ -0,0 +1,55 @@ +### Stage 1: build client +FROM node:18 as client-builder +WORKDIR /client-builder + +# Install node packages +COPY package.json . +COPY client/package.json client/ +COPY client/package-lock.json client/ +RUN npm run install-dependencies:client + +# Build client +COPY client/ client/ +RUN npm run build + + +### Stage 2: final container +FROM php:8.2-apache +RUN apt-get update \ + && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y cron unzip libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ + && update-ca-certificates --fresh \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* + +RUN docker-php-ext-configure gd \ + && docker-php-ext-install gd mbstring pdo_pgsql pdo_mysql tidy + +RUN a2enmod headers rewrite + +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php composer-setup.php \ + && php -r "unlink('composer-setup.php');" \ + && mv composer.phar /usr/local/bin/composer + +# Install dependencies +COPY composer.json . +COPY composer.lock . +RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --optimize-autoloader --no-dev + +# Setup cron +RUN echo '* * * * * curl http://localhost/update' | tee /etc/cron.d/selfoss \ + && chmod 0644 /etc/cron.d/selfoss \ + && crontab /etc/cron.d/selfoss + +WORKDIR /var/www/html + +COPY . . + +COPY --from=client-builder /client-builder/public /var/www/html/public + +RUN chown -R www-data:www-data /var/www/html/data + +# Overload default command to run cron in the background +RUN sed -i 's/^exec /service cron start\n\nexec /' /usr/local/bin/apache2-foreground + +VOLUME /var/www/html/data From e6d264c61bce88490dba94918fd12fecbab7ddb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20de=20Saint=20Martin?= Date: Thu, 2 Nov 2023 22:34:41 +0100 Subject: [PATCH 2/5] changes following review. --- .dockerignore | 70 ++++++++++++++++++--------------------------------- Dockerfile | 44 ++++++++++++++++---------------- 2 files changed, 46 insertions(+), 68 deletions(-) diff --git a/.dockerignore b/.dockerignore index d283a30d55..b92e03c762 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,50 +1,28 @@ -documentation +# Taken from .gitignore +/assets/.parcel-cache +/data/favicons/*.png +/data/favicons/*.jpg +/data/thumbnails/*.png +/data/thumbnails/*.jpg +/data/cache/*.spc +/data/logs/*.log +/data/sqlite/*.db +/public +docs/public/ +docs/static/processed_images/ +user.css +user.js +*.ini +node_modules +.env +vendor/ +.php_cs.cache +__pycache__ + +# Regular docker ignore .dockerignore Dockerfile .git -.git* +.github +.gitignore *.md - -# compiled output -/dist -/tmp -/out-tsc -# Only exists if Bazel was run -/bazel-out - -# dependencies -/node_modules - -# profiling files -chrome-profiler-events.json -speed-measure-plugin.json - -# IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# IDE - VSCode -.vscode/* -.history/* - -# misc -/.sass-cache -/connect.lock -/coverage -/libpeerconnection.log -npm-debug.log -yarn-error.log -testem.log -/typings - -# System Files -.DS_Store -Thumbs.db - -# testing -junit.xml diff --git a/Dockerfile b/Dockerfile index 505106c9be..942e5b8770 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ +# syntax=docker/dockerfile:1 + ### Stage 1: build client -FROM node:18 as client-builder +FROM node:20 as client-builder WORKDIR /client-builder # Install node packages @@ -15,41 +17,39 @@ RUN npm run build ### Stage 2: final container FROM php:8.2-apache -RUN apt-get update \ - && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y cron unzip libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ +# Install runtime & development package dependencies & php extensions +# then clean-up dev package dependencies +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt update \ + && apt install -y --no-install-recommends \ + unzip \ + libjpeg62-turbo libpng16-16 libpq5 libonig5 libtidy5deb1 \ + libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ && update-ca-certificates --fresh \ + && docker-php-ext-configure gd --with-jpeg \ + && docker-php-ext-install gd mbstring pdo_pgsql pdo_mysql tidy \ + && apt remove -y libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ + && apt autoremove -y \ && apt clean \ && rm -rf /var/lib/apt/lists/* -RUN docker-php-ext-configure gd \ - && docker-php-ext-install gd mbstring pdo_pgsql pdo_mysql tidy - +# Install Apache modules RUN a2enmod headers rewrite -RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ - && php composer-setup.php \ - && php -r "unlink('composer-setup.php');" \ - && mv composer.phar /usr/local/bin/composer - -# Install dependencies +# Install Selfoss PHP dependencies +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer COPY composer.json . COPY composer.lock . RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --optimize-autoloader --no-dev +RUN rm /usr/bin/composer -# Setup cron -RUN echo '* * * * * curl http://localhost/update' | tee /etc/cron.d/selfoss \ - && chmod 0644 /etc/cron.d/selfoss \ - && crontab /etc/cron.d/selfoss - +# Install Selfoss and copy frontend from the first stage WORKDIR /var/www/html - COPY . . - COPY --from=client-builder /client-builder/public /var/www/html/public +# Use www-data user as owner and drop root user RUN chown -R www-data:www-data /var/www/html/data - -# Overload default command to run cron in the background -RUN sed -i 's/^exec /service cron start\n\nexec /' /usr/local/bin/apache2-foreground +USER www-data VOLUME /var/www/html/data From b405f3a603ee4a13879f66764ede17ee304c955d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20de=20Saint=20Martin?= Date: Sun, 21 Jul 2024 11:58:06 +0200 Subject: [PATCH 3/5] use more modern syntax, upgrade to php 8.3 --- Dockerfile | 54 ++++++++++++++++++++++++++++------------------------ package.json | 1 + 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Dockerfile b/Dockerfile index 942e5b8770..b3a97cb543 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,47 +1,51 @@ -# syntax=docker/dockerfile:1 +# syntax=docker/dockerfile:1.9@sha256:5510f694edfe648d961b59dcf217026485e560d2663c73e45067b8c8d7a6d247 ### Stage 1: build client -FROM node:20 as client-builder +FROM node:20 AS client-builder WORKDIR /client-builder # Install node packages -COPY package.json . -COPY client/package.json client/ -COPY client/package-lock.json client/ -RUN npm run install-dependencies:client +RUN --mount=type=bind,source=package.json,target=package.json \ + --mount=type=bind,source=client/package.json,target=client/package.json \ + --mount=type=bind,source=client/package-lock.json,target=client/package-lock.json \ + --mount=type=cache,sharing=locked,id=npmcache,mode=0777,target=/root/.npm \ + npm run install-dependencies-ci:client # Build client COPY client/ client/ -RUN npm run build +RUN --mount=type=bind,source=package.json,target=package.json \ + --mount=type=bind,source=client/package.json,target=client/package.json \ + --mount=type=bind,source=client/package-lock.json,target=client/package-lock.json \ + --mount=type=cache,sharing=locked,id=npmcache,mode=0777,target=/root/.npm \ + npm run build ### Stage 2: final container -FROM php:8.2-apache +FROM php:8.3-apache # Install runtime & development package dependencies & php extensions # then clean-up dev package dependencies RUN export DEBIAN_FRONTEND=noninteractive \ - && apt update \ - && apt install -y --no-install-recommends \ - unzip \ - libjpeg62-turbo libpng16-16 libpq5 libonig5 libtidy5deb1 \ - libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ - && update-ca-certificates --fresh \ - && docker-php-ext-configure gd --with-jpeg \ - && docker-php-ext-install gd mbstring pdo_pgsql pdo_mysql tidy \ - && apt remove -y libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ - && apt autoremove -y \ - && apt clean \ - && rm -rf /var/lib/apt/lists/* + && apt update \ + && apt install -y --no-install-recommends \ + unzip \ + libjpeg62-turbo libpng16-16 libpq5 libonig5 libtidy5deb1 \ + libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ + && update-ca-certificates --fresh \ + && docker-php-ext-configure gd --with-jpeg \ + && docker-php-ext-install -j$(nproc) gd mbstring pdo_pgsql pdo_mysql tidy \ + && apt remove -y libjpeg62-turbo-dev libpng-dev libpq-dev libonig-dev libtidy-dev \ + && apt autoremove -y \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* # Install Apache modules RUN a2enmod headers rewrite # Install Selfoss PHP dependencies -COPY --from=composer:2 /usr/bin/composer /usr/bin/composer -COPY composer.json . -COPY composer.lock . -RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --optimize-autoloader --no-dev -RUN rm /usr/bin/composer +RUN --mount=type=bind,source=composer.json,target=composer.json \ + --mount=type=bind,source=composer.lock,target=composer.lock \ + --mount=type=bind,from=composer:2,source=/usr/bin/composer,target=/usr/bin/composer \ + COMPOSER_ALLOW_SUPERUSER=1 composer install --optimize-autoloader --no-dev # Install Selfoss and copy frontend from the first stage WORKDIR /var/www/html diff --git a/package.json b/package.json index 3a73a66792..a3da3a8e13 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "fix:helpers:cs": "black utils/ tests/", "install-dependencies": "npm run install-dependencies:client && npm run install-dependencies:server", "install-dependencies:client": "npm install --production=false --prefix client/", + "install-dependencies-ci:client": "npm ci --production=false --prefix client/", "install-dependencies:server": "composer install --dev", "test:server": "composer run-script test", "test:integration": "python3 tests/integration/run.py", From e83ad76a35124914785363ec4c6a9bb5cb5dd9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20de=20Saint=20Martin?= Date: Sun, 21 Jul 2024 12:11:05 +0200 Subject: [PATCH 4/5] Introduce github workflow --- .github/workflows/publish-container.yml | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/publish-container.yml diff --git a/.github/workflows/publish-container.yml b/.github/workflows/publish-container.yml new file mode 100644 index 0000000000..3615c6057a --- /dev/null +++ b/.github/workflows/publish-container.yml @@ -0,0 +1,46 @@ +# According to https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-ghcrio +name: Create and publish a Container image + +on: + push: + tags: + - '*' + branches: + - master + - docker + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.1 + + - name: Log in to the Container registry + uses: docker/login-action@v3.2.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5.0.0 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + push: true + file: Dockerfile + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 0bf1e20b669e4a876652f83d0ed8e151ceff20ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20de=20Saint=20Martin?= Date: Tue, 20 Aug 2024 09:42:42 +0200 Subject: [PATCH 5/5] changes following review (again). --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a3da3a8e13..35e71fdafc 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "fix:helpers:cs": "black utils/ tests/", "install-dependencies": "npm run install-dependencies:client && npm run install-dependencies:server", "install-dependencies:client": "npm install --production=false --prefix client/", - "install-dependencies-ci:client": "npm ci --production=false --prefix client/", + "install-dependencies-ci:client": "npm ci --prefix client/", "install-dependencies:server": "composer install --dev", "test:server": "composer run-script test", "test:integration": "python3 tests/integration/run.py",