This commit is contained in:
wotnak 2024-02-19 20:02:20 -07:00 committed by GitHub
commit 76b945d4d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 180 additions and 130 deletions

View File

@ -34,10 +34,23 @@ jobs:
run: |
echo "FARMOS_VERSION=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
echo "FARMOS_REPO=${{ github.event.pull_request.head.repo.full_name }}" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and save farmOS Docker image
run: |
docker build --build-arg FARMOS_REPO=https://github.com/${FARMOS_REPO} --build-arg FARMOS_VERSION=${FARMOS_VERSION} -t farmos/farmos:3.x docker
docker save farmos/farmos:3.x > /tmp/farmos.tar
uses: docker/build-push-action@v5
with:
push: false
context: docker
build-args: |
FARMOS_REPO=https://github.com/${{ env.FARMOS_REPO }}
FARMOS_VERSION=${{ env.FARMOS_VERSION }}
GIT_COMMIT=${{ github.sha }}
tags: farmos/farmos:3.x
cache-from: type=gha,scope=prod
cache-to: type=gha,scope=prod
outputs: type=docker,dest=/tmp/farmos.tar
- name: Cache farmOS Docker image
uses: actions/cache@v3
with:
@ -47,9 +60,21 @@ jobs:
# but notably it does NOT override the default PROJECT_VERSION, so the
# farmOS Composer project 3.x branch is always used.
- name: Build and save farmOS dev Docker image
run: |
docker build --build-arg FARMOS_REPO=https://github.com/${FARMOS_REPO} --build-arg FARMOS_VERSION=${FARMOS_VERSION} -t farmos/farmos:3.x-dev docker/dev
docker save farmos/farmos:3.x-dev > /tmp/farmos-dev.tar
uses: docker/build-push-action@v5
with:
push: false
context: docker
target: dev
build-args: |
FARMOS_REPO=https://github.com/${{ env.FARMOS_REPO }}
FARMOS_VERSION=${{ env.FARMOS_VERSION }}
GIT_COMMIT=${{ github.sha }}
tags: farmos/farmos:3.x-dev
cache-from: |
type=gha,scope=prod
type=gha,scope=dev
cache-to: type=gha,scope=dev
outputs: type=docker,dest=/tmp/farmos-dev.tar
- name: Cache farmOS dev Docker image
uses: actions/cache@v3
with:

View File

@ -1,7 +1,14 @@
# Use the official Drupal 10 image to build GEOS PHP extension.
FROM drupal:10.1 as php-dependencies
# Use the official Drupal 10 as base image.
FROM drupal:10.1 as baseimage
# Define common paths.
ENV FARMOS_PATH=/var/farmOS
ENV DRUPAL_PATH=/opt/drupal
##
# Build PHP extensions, GEOS and bcmath.
FROM baseimage as php-dependencies
# Build and install the GEOS PHP extension.
# See https://git.osgeo.org/gitea/geos/php-geos
ARG PHP_GEOS_VERSION=e77d5a16abbf89a59d947d1fe49381a944762c9d
ADD https://github.com/libgeos/php-geos/archive/${PHP_GEOS_VERSION}.tar.gz /opt/php-geos.tar.gz
@ -17,51 +24,127 @@ RUN apt-get update && apt-get install -y libgeos-dev \
# Install the BCMath PHP extension.
RUN docker-php-ext-install bcmath
# Inherit from the official Drupal 10 image.
FROM drupal:10.1
# Setup dependencies and sources for composer installations.
FROM baseimage as composer-file
# Set the farmOS and composer project repository URLs and versions.
ARG FARMOS_REPO=https://github.com/farmOS/farmOS.git
ARG FARMOS_VERSION=3.x
ARG PROJECT_REPO=https://github.com/farmOS/composer-project.git
ARG PROJECT_VERSION=3.x
ARG PROJECT_REPO=https://github.com/farmOS/composer-project/raw/${PROJECT_VERSION}/composer.json
# Set the COMPOSER_MEMORY_LIMIT environment variable to unlimited.
ENV COMPOSER_MEMORY_LIMIT=-1
# Allow root to install plugins.
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV COMPOSER_NO_INTERACTION=1
# Install apt dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends\
# Install git and unzip (needed by Composer).
git unzip
# Add the build-farmOS.sh script.
COPY build-farmOS.sh /usr/local/bin/
# Setup composer file for non interactive installation.
WORKDIR ${FARMOS_PATH}
RUN build-farmOS.sh
##
# Create layer with farmOS sources.
FROM composer-file as farmos-sources
# Declare the git commit hash argument used for build cache invalidation between
# different commits on the same branch in GitHub actions.
ARG GIT_COMMIT=unknown
# Install sources.
RUN composer install --no-dev
# Set the version in farm.info.yml.
RUN sed -i "s|version: 3.x|version: ${FARMOS_VERSION}|g" ${FARMOS_PATH}/web/profiles/farm/farm.info.yml
##
# Create layer with farmOS dev sources.
FROM farmos-sources as farmos-dev-sources
# Install sources.
RUN composer update
##
# Dependencies layer.
FROM baseimage as farmos-baseimage
# Set Apache ServerName directive globally to suppress AH00558 message.
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
# Install and enable geos.
# Enable PHP dependencies.
COPY --from=php-dependencies /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
RUN docker-php-ext-enable geos bcmath
# Add custom PHP configurations.
COPY conf.d/ /usr/local/etc/php/conf.d
# Install apt dependencies.
RUN apt-get update && apt-get install -y \
# Install git and unzip (needed by Composer).
git unzip \
# Install apt dependencies and clean up.
RUN apt-get update && apt-get install -y --no-install-recommends\
# Install postgresql-client so Drush can connect to the database.
postgresql-client \
# Install libgeos-c1v5 so geos php extension can use libgeos_c.so.1.
libgeos-c1v5 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
# Set the COMPOSER_MEMORY_LIMIT environment variable to unlimited.
ENV COMPOSER_MEMORY_LIMIT=-1
# Add the build-farmOS.sh script.
COPY build-farmOS.sh /usr/local/bin/
RUN chmod a+x /usr/local/bin/build-farmOS.sh
# Build the farmOS codebase in /var/farmoS with the --no-dev flag.
# Change the ownership of the sites directory and copy the farmOS codebase into /opt/drupal.
RUN mkdir /var/farmOS \
&& /usr/local/bin/build-farmOS.sh --no-dev \
&& chown -R www-data:www-data /var/farmOS/web/sites \
&& rm -r /opt/drupal && cp -rp /var/farmOS /opt/drupal
# Install git and unzip (needed by Composer).
git unzip \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean \
# Clean up ${DRUPAL_PATH}.
&& rm -r ${DRUPAL_PATH} \
&& mkdir ${DRUPAL_PATH}
# Set the entrypoint.
COPY docker-entrypoint.sh /usr/local/bin/
COPY --chown=www-data docker-entrypoint.sh /usr/local/bin/
# Set the working directory, entrypoint and command.
WORKDIR ${DRUPAL_PATH}
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["apache2-foreground"]
##
# Development base image.
FROM farmos-baseimage as farmos-dev-baseimage
# Change the user/group IDs of www-data inside the image to match the ID of the
# developer's user on the host machine. This allows Composer to create files
# owned by www-data inside the container, while keeping those files editable by
# the developer outside of the container.
# This defaults to 1000, based on the assumption that the developer is running
# as UID 1000 on the host machine. It can be overridden at image build time with:
# --build-arg WWW_DATA_ID=$(id -u)
ARG WWW_DATA_ID=1000
RUN usermod -u ${WWW_DATA_ID} www-data && groupmod -g ${WWW_DATA_ID} www-data
# Install and configure XDebug.
RUN yes | pecl install xdebug \
&& docker-php-ext-enable xdebug
# Add opcache revalidation frequency configuration.
COPY dev/conf.d/ /usr/local/etc/php/conf.d
# Add Configurations for PHP CodeSniffer, PHPStan
COPY --chown=www-data:www-data ./dev/files/ ${FARMOS_PATH}
##
# Development image.
FROM farmos-dev-baseimage as dev
# Add farmOS dev sources.
COPY --from=farmos-dev-sources --chown=www-data:www-data ${FARMOS_PATH} ${FARMOS_PATH}
# Configure PHPUnit.
RUN ${FARMOS_PATH}/phpunit.sh
##
# Production image.
FROM farmos-baseimage
# Add farmOS sources.
COPY --from=farmos-sources --chown=www-data:www-data ${FARMOS_PATH} ${DRUPAL_PATH}

35
docker/build-farmOS.sh Normal file → Executable file
View File

@ -2,26 +2,18 @@
set -e
###
# This script will build the farmOS codebase in /var/farmOS.
# This script will build the farmOS codebase in ${FARMOS_PATH},
# by default it is /var/farmOS.
###
# If /var/farmOS is not empty, bail.
if [ "$(ls -A /var/farmOS/)" ]; then
# If ${FARMOS_PATH} is not empty, bail.
if [ "$(ls -A ${FARMOS_PATH})" ]; then
echo "The ${FARMOS_PATH} is not empty, terminate."
exit 1
fi
# Make /var/farmOS the working directory.
cd /var/farmOS
# Generate an empty Composer project project and checkout a specific version.
git clone ${PROJECT_REPO} project
mv project/.git ./.git
rm -rf project
git checkout ${PROJECT_VERSION}
git reset --hard
# Create a temporary Composer cache directory.
export COMPOSER_HOME="$(mktemp -d)"
# Fetch composer template
curl -L ${PROJECT_REPO} -o composer.json
# If FARMOS_VERSION is a valid semantic versioning string, we assume that it is
# a tagged version.
@ -61,16 +53,3 @@ allowedPlugins=(
for plugin in ${allowedPlugins[@]}; do
composer config --no-plugins allow-plugins.$plugin true
done
# Run composer install with optional arguments passed into this script.
if [ $# -eq 0 ]; then
composer install
else
composer install "$*"
fi
# Set the version in farm.info.yml.
sed -i "s|version: 3.x|version: ${FARMOS_VERSION}|g" /var/farmOS/web/profiles/farm/farm.info.yml
# Remove the Composer cache directory.
rm -rf "$COMPOSER_HOME"

View File

@ -1,63 +0,0 @@
# Inherit from the farmOS 3.x image.
FROM farmos/farmos:3.x
# Set the farmOS and composer project repository URLs and versions.
ARG FARMOS_REPO=https://github.com/farmOS/farmOS.git
ARG FARMOS_VERSION=3.x
ARG PROJECT_REPO=https://github.com/farmOS/composer-project.git
ARG PROJECT_VERSION=3.x
# Install and enable XDebug extension.
RUN yes | pecl install xdebug \
&& docker-php-ext-enable xdebug
# Add opcache revalidation frequency configuration.
COPY conf.d/ /usr/local/etc/php/conf.d
# Change the user/group IDs of www-data inside the image to match the ID of the
# developer's user on the host machine. This allows Composer to create files
# owned by www-data inside the container, while keeping those files editable by
# the developer outside of the container.
# This defaults to 1000, based on the assumption that the developer is running
# as UID 1000 on the host machine. It can be overridden at image build time with:
# --build-arg WWW_DATA_ID=$(id -u)
ARG WWW_DATA_ID=1000
RUN usermod -u ${WWW_DATA_ID} www-data && groupmod -g ${WWW_DATA_ID} www-data
# Create a fresh /var/farmOS directory owned by www-data.
# We do this in two steps because of a known issue with Moby.
# @see https://github.com/farmOS/farmOS/pull/440
RUN rm -r /var/farmOS
RUN mkdir /var/farmOS && chown www-data:www-data /var/farmOS
# Change to the www-data user.
USER www-data
# Build the farmOS codebase in /var/farmOS.
RUN /usr/local/bin/build-farmOS.sh
# Add Configurartions for PHP CodeSniffer, PHPStan.
COPY --chown=www-data ./files/ /var/farmOS/
# Configure PHPUnit.
RUN cp -p /var/farmOS/web/core/phpunit.xml.dist /var/farmOS/phpunit.xml \
&& sed -i 's|bootstrap="tests/bootstrap.php"|bootstrap="web/core/tests/bootstrap.php"|g' /var/farmOS/phpunit.xml \
&& sed -i '/failOnWarning="true"/a \ failOnIncomplete="true"' /var/farmOS/phpunit.xml \
&& sed -i '/failOnWarning="true"/a \ failOnSkipped="true"' /var/farmOS/phpunit.xml \
&& sed -i 's|name="SIMPLETEST_BASE_URL" value=""|name="SIMPLETEST_BASE_URL" value="http://www"|g' /var/farmOS/phpunit.xml \
&& sed -i 's|name="SIMPLETEST_DB" value=""|name="SIMPLETEST_DB" value="pgsql://farm:farm@db/farm"|g' /var/farmOS/phpunit.xml \
&& sed -i 's|name="BROWSERTEST_OUTPUT_DIRECTORY" value=""|name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/sites/simpletest/browser_output"|g' /var/farmOS/phpunit.xml \
&& sed -i 's|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\'''\''|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\''["chrome", { "chromeOptions": { "w3c": false, "args": ["--disable-gpu","--headless", "--no-sandbox"] } }, "http://chrome:4444/wd/hub"]'\''|g' /var/farmOS/phpunit.xml \
&& sed -i 's|\./|\./web/core/|g' /var/farmOS/phpunit.xml \
&& sed -i 's|\.\./web/core/|\./web/|g' /var/farmOS/phpunit.xml \
&& sed -i 's| </php>| <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>'"\n"' </php>|g' /var/farmOS/phpunit.xml \
&& mkdir -p /var/farmOS/web/sites/simpletest/browser_output
# Change back to the root user.
USER root
# Copy the farmOS codebase into /opt/drupal.
RUN rm -r /opt/drupal && cp -rp /var/farmOS /opt/drupal
# Create a Composer config directory for the www-data user.
RUN mkdir /var/www/.composer && chown www-data:www-data /var/www/.composer

19
docker/dev/files/phpunit.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env sh
cp -p ${FARMOS_PATH}/web/core/phpunit.xml.dist ${FARMOS_PATH}/phpunit.xml
sed -i 's|bootstrap="tests/bootstrap.php"|bootstrap="web/core/tests/bootstrap.php"|g' ${FARMOS_PATH}/phpunit.xml
sed -i '/failOnWarning="true"/a \ failOnIncomplete="true"' ${FARMOS_PATH}/phpunit.xml
sed -i '/failOnWarning="true"/a \ failOnSkipped="true"' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="SIMPLETEST_BASE_URL" value=""|name="SIMPLETEST_BASE_URL" value="http://www"|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="SIMPLETEST_DB" value=""|name="SIMPLETEST_DB" value="pgsql://farm:farm@db/farm"|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="BROWSERTEST_OUTPUT_DIRECTORY" value=""|name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/html/sites/simpletest/browser_output"|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\'''\''|name="MINK_DRIVER_ARGS_WEBDRIVER" value='\''["chrome", { "chromeOptions": { "w3c": false, "args": ["--disable-gpu","--headless", "--no-sandbox"] } }, "http://chrome:4444/wd/hub"]'\''|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|\./|\./web/core/|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's|\.\./web/core/|\./web/|g' ${FARMOS_PATH}/phpunit.xml
sed -i 's| </php>| <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>'"\n"' </php>|g' ${FARMOS_PATH}/phpunit.xml
# Create output directory for phpunit tests and permissions for testing user.
mkdir -p ${FARMOS_PATH}/web/sites/simpletest/browser_output
chown -R www-data:www-data ${FARMOS_PATH}/web/sites/simpletest
rm ${FARMOS_PATH}/phpunit.sh

View File

@ -8,15 +8,15 @@ set -e
###
# If the Drupal directory is empty, populate it from pre-built files.
if [ -d /opt/drupal ] && ! [ "$(ls -A /opt/drupal/)" ]; then
if [ -d ${DRUPAL_PATH} ] && ! [ "$(ls -A ${DRUPAL_PATH}/)" ]; then
echo "farmOS codebase not detected. Copying from pre-built files in the Docker image."
cp -rp /var/farmOS/. /opt/drupal
cp -rp ${FARMOS_PATH}/. ${DRUPAL_PATH}
fi
# If the sites directory is empty, populate it from pre-built files.
if [ -d /opt/drupal/web/sites ] && ! [ "$(ls -A /opt/drupal/web/sites/)" ]; then
if [ -d ${DRUPAL_PATH}/web/sites ] && ! [ "$(ls -A ${DRUPAL_PATH}/web/sites/)" ]; then
echo "farmOS sites directory not detected. Copying from pre-built files in the Docker image."
cp -rp /var/farmOS/web/sites/. /opt/drupal/web/sites
cp -rp ${FARMOS_PATH}/web/sites/. ${DRUPAL_PATH}/web/sites
fi
if [ -n "$FARMOS_FS_READY_SENTINEL_FILENAME" ]; then

View File

@ -17,7 +17,9 @@ Available arguments and their default values are described below:
check out.
- Default: `3.x`
The `3.x-dev` image also provides the following:
## Development image
The `3.x-dev` image also provides the following build arguments:
- `WWW_DATA_ID` - The ID to use for the `www-data` user and group inside the
image. Setting this to the ID of the developer's user on the host machine
@ -26,3 +28,8 @@ The `3.x-dev` image also provides the following:
container. If your user ID is not `1000`, build the image with:
`--build-arg WWW_DATA_ID=$(id -u)`
- Default: `1000`
To build the development image, you will have to define the target dev,
for example:
`docker build --build-arg WWW_DATA_ID=$(id -u) -t farmos/farmos:3.x-dev --target dev docker`