As outlined in the Hyland Alfresco support policy, pre-built container images are intended as reference for creating your own customized images, incorporating deployment guidelines, security best practices, and any necessary custom extensions. While this policy remains unchanged, we are supporting the community further by open-sourcing the Alfresco Dockerfiles Bakery, a tool designed to simplify the deployment of the Alfresco platform and assist you in building tailored container images, with the help of Docker Bake.
- Alfresco Dockerfiles Bakery π
Building images requires the following tools:
- A recent enough Docker installation (with
buildxsupport) - Credentials to access the Alfresco artifacts (Nexus server), if building Enterprise images
- Some common unix tools:
jq,yq,make - Python 3 with pyyaml (
pip install pyyaml) for fetching artifacts via thefetch-artifacts.pyscript
Alternatively, you can use the provided Vagrantfile to create a dedicated VM with all the required tools installed. This is useful if you want to build the images without installing the tools on your local machine.
Vagrant is the command line utility for managing the lifecycle of virtual machines.
To use the provided Vagrantfile, you need to have Vagrant and VirtualBox installed on your machine. You can follow the instructions below to install them:
- Install vagrant
- Install VirtualBox
Then run from the main folder of this project:
vagrant upVagrant will create an ubuntu 24.04 virtual machine in VirtualBox, fetch all the required Bakery dependencies, and then you can enter the environment by running:
vagrant sshThen you can proceed running the make commands as described later in this
document.
Configuring the authentication to Alfresco Nexus server requires setting up
credentials in the standard ~/.netrc authentication file.
Using your preferred editor, create ~/.netrc with the following contents:
machine nexus.alfresco.com
login myuser
password mypasswordMake sure to make the file non-world readable:
chmod 600 ~/.netrcIf you do not plan on applying specific customizations but just want to get Alfresco images updated (e.g. with the latest OS security patches), you can simply run the command below from the root of this project:
make enterpriseor for Community edition:
make communityThis command will build locally all the docker images this project offers.
For more information on the available images, browse the top level folders,
excluding artifacts_cache, scripts and test.
For more information on the available targets, run:
make helpBelow are some environment variables which can be used to customize the build process:
REGISTRY: The registry where the images will be pushed (authentication is ensured by themakewrapper)REGISTRY_NAMESPACE: The namespace where the images will be pushed (e.g. REGISTRY/REGISTRY_NAMESPACE/IMAGE_NAME:TAG)TAG: The tag to use for the images (default islatest)TARGETARCH: The architecture to build the images for (default is the architecture of the system where the build is run). See Supported Architectures for more information.BAKE_NO_CACHE: Set to1to disable the cache during the build processBAKE_NO_SBOM: Set to1to not attach an SBOM attestation to the images when pushing them to a registry. See Software Bill of Materials for more information.BAKE_PROVENANCE: Provenance attestation to attach to the images when pushing them to a registry, disabled (false) by default. Set tomode=minormode=maxto describe your own build. See Build provenance for more information.
For example, to build multi-arch images for ARM64 and X86_64 and push them to a custom registry, you can run the following command:
export REGISTRY=myecr.domain.tld REGISTRY_NAMESPACE=myalfrescobuilds TARGETARCH=linux/amd64,linux/arm64
make allAll the images running a Java web application are built on the Alfresco base
Tomcat image. The servlet container they embed is configured with the TOMCAT_*
environment variables documented in tomcat/README.md.
The Alfresco Content Repository image can be customized by adding files into specific folders:
- Alfresco Module Packages (AMPs) files in the amps
folder for both Enterprise and Community editions
- For Enterprise-only AMPs files in the amps-enterprise folder
- For Community-only AMPs files in the amps-community folder
- Simple Module (JAR) files in the simple_modules folder
- Additional JAR files for the JRE in the libs folder
These sources use named Docker Bake build contexts with the folders above as
their defaults. Each source can be customized independently with --set:
docker buildx bake repository \
--set repository.contexts.repo_libs=./custom-libsRepository contexts are repo_amps, repo_amps_edition, repo_libs, and
repo_simple_modules. The replacement directory is used as the root of the
corresponding build context.
The Share image can be customized by adding files into specific folders:
- Alfresco Module Packages (AMPs) files in the amps folder
- Share Simple Module (JAR) files in the simple_modules folder
These sources use named Docker Bake build contexts with the folders above as
their defaults. Each source can be customized independently with --set:
docker buildx bake share \
--set share.contexts.share_amps=./custom-share-ampsShare contexts are share_amps and share_simple_modules. The replacement
directory is used as the root of the corresponding build context.
The Community Batch Indexing image (search_batch_indexing) packages the
Alfresco Elasticsearch community connector for Elasticsearch-based Community
Edition deployments. Batch indexing is currently available for ACS 26.
Set ACS_VERSION to select the ACS version when building directly. For example,
build the batch indexing image for ACS 26:
ACS_VERSION=26 docker buildx bake search_batch_indexingTo build all Community Edition images for a selected ACS version, use:
make community ACS_VERSION=26For ACS 23 and ACS 25, the community group builds the Solr-based Search
Service instead of batch indexing.
Runtime behaviour can be controlled via environment variables passed to the container and via standard Spring externalized configuration (e.g. mounted config files). See search/community/README.md for the full list of supported variables and customization options.
Depending on the environment where you plan to run the docker images you build, it is possible to build Alfresco images the following architectures:
- X86_64 (linux/amd64): Regular intel processor based systems
- ARM64 (linux/arm64): ARM processor based systems (e.g. Apple Silicon or AWS Graviton)
By default, the images are built for the architecture of the system where the build is run.
To build images for a specific architecture, you can set the TARGETARCH
environment variable to the desired architecture.
For example, to build all Alfresco images for ARM64, you can run the following
command:
export TARGETARCH=linux/arm64
make allTo build just a specific image use you'll need to use docker buildx bake
directly, but the TARGETARCH environment variable also works:
export TARGETARCH=linux/arm64
docker buildx bake tengine_imagemagickImages can be built with multi-arch support. This is done by using the same environment variable as above, and passing target architectures as a comma-separated list. By doing so, you're not solely build an image and its manifest, but a list of manifests for each target architecture. That makes it possible to reference the same image name and tag, and have the right image pulled for the right architecture.
export TARGETARCH=linux/amd64,linux/arm64
make allIt's important to note that building multi-arch images requires the use of Docker BuildKit, which is enabled by default in Docker 20.10 and later and also requires images to be pushed to a registry that supports multi-arch.
docker exporter in BuildKit.
In order to produce multi-arch images one needs to:
- Set the REGISTRY environment variable to the target registry
- Set the REGISTRY_NAMESPACE environment variable to the target namespace
The make wrapper would handle the authentication part for you:
export REGISTRY=myecr.domain.tld REGISTRY_NAMESPACE=myalfrescobuilds TARGETARCH=linux/amd64,linux/arm64
make repositoryYou can also run bake directly but you need to be sure to have done the
authentication before running the docker buildx bake command with an
additional argument to tell the tool to push the images to the registry:
export REGISTRY=myecr.domain.tld REGISTRY_NAMESPACE=myalfrescobuilds TARGETARCH=linux/amd64,linux/arm64
docker buildx bake repository --set *.output=type=registry,push=trueVersions of artifacts being downloaded specific to the ACS version are defined
in artifacts-XX.yaml files for each component.
To build a specific ACS version, pass the ACS_VERSION env to either make
or docker buildx bake.
- ACS 26 (current default) -
ACS_VERSION=26- Will useartifacts-26.yamlfiles - ACS 25 -
ACS_VERSION=25- Will useartifacts-25.yamlfiles - ACS 23 -
ACS_VERSION=23- Will useartifacts-23.yamlfiles
make enterprise ACS_VERSION=23ACS_VERSION=23 docker buildx bake enterpriseTomcat values are selected automatically from docker-bake.hcl based on
ACS_VERSION.
If needed, you can still override Tomcat values explicitly using --set.
Before switching build to other version clean the artifacts using make clean
then fetch correct version with e.g.:
make clean prepare ACS_VERSION=23Superseded versions of an artifact are also pruned automatically from its
target folder as soon as the new version is fetched, so re-running with a
different ACS_VERSION (or after bumping a version in an artifacts-XX.yaml
file) without make clean first will not leave stale files behind.
Artifacts set in the artifacts file are fetched from the Nexus repository and
their checksum is verified, provided the artifact has a checksum value which is
a concatenation of the algorithm and optionally the checksum in the format
<algorithm>:<checksum>. If the checksum is not provided, the script will
try to fetch it from the Nexus repository reusing the computed artifact url and
appending the .algorithm extension to it.
Once the images are built, you can test them locally using either Helm or Docker Compose.
Follow the general instructions for installing Alfresco on
KinD
until the point where you have to run helm install.
If the images has not been pushed to a remote repository, you can easily load all the locally built images in the local KinD cluster with:
kind load docker-image $(docker images --format "{{.Repository}}" | grep "^localhost/alfresco" | xargs)Before running the helm install command, you need adjust the registry and
image namespace references in the provided
test-overrides.yaml file:
REGISTRY=localhost REGISTRY_NAMESPACE=alfresco TAG=latest
sed -i "s|localhost/alfresco/|${REGISTRY}/${REGISTRY_NAMESPACE}/|g" test/helm/test-overrides.yaml
sed -i "s|tag: latest|tag: ${TAG}|g" test/helm/test-overrides.yamlIf you are testing the community edition, you also need to adjust the image references for the Share and Repository images:
sed -i "s|/alfresco-content-repository|/alfresco-content-repository-community|g" test/helm/test-overrides.yaml
sed -i "s|/alfresco-share|/alfresco-share-community|g" test/helm/test-overrides.yamlThen you can finally run helm install passing as values the provided files.
For enterprise edition:
helm install acs alfresco/alfresco-content-services \
--values=test/helm/enterprise-integration-test-values.yaml \
--values=test/helm/test-overrides.yaml \
--values=test/helm/test-overrides-enterprise.yaml \
--atomic \
--timeout 10m0s \
--namespace alfrescoFor community edition:
helm install acs alfresco/alfresco-content-services \
--values=test/helm/community_values.yaml \
--values=test/helm/community-integration-test-values.yaml \
--values=test/helm/test-overrides.yaml \
--values=test/helm/test-overrides-community.yaml \
--set global.search.sharedSecret=$(openssl rand -hex 24) \
--atomic \
--timeout 10m0s \
--namespace=alfrescoYou can use Docker Compose to test the built images locally as follows:
-
Fetch upstream compose definitions from acs-deployment repository:
git clone https://github.com/Alfresco/acs-deployment.git
-
Copy the compose files from the acs-deployment repository to the test folder of this repository:
cp -r acs-deployment/docker-compose/* test/ -
Run compose together with one of the available override files, which allow you to easily reference built images using
$REGISTRY/$REGISTRY_NAMESPACE/component-name:$TAGformat:export REGISTRY=localhost REGISTRY_NAMESPACE=alfresco TAG=latest docker compose -f test/compose.yaml -f test/enterprise-override.yaml up -dFor community edition instead:
export REGISTRY=localhost REGISTRY_NAMESPACE=alfresco TAG=latest docker compose -f test/community-compose.yaml -f test/community-override.yaml up -d
The images built by this project may be scanned for vulnerabilities using Grype,
if the grype binary is available in the PATH.
Grype is an open-source scanner for container images, ideal for identifying recent vulnerabilities, especially within base OS images. While it supports application libraries, it lacks reachability analysis, meaning it cannot confirm whether vulnerabilities are actually exploitable in the context of the application. For accurate insights, refer to Alfresco Security bulletins and contact Hyland support, as these sources provide vetted information after manual triaging of scanner findings within the application code. Remember to always assess findings within the context of your specific deployment.
If you want to run the security scan manually, you can use the following command:
make grype GRYPE_TARGET=repository GRYPE_OPTS="-f high --only-fixed --ignore-states wont-fix"GRYPE_TARGET accepts any docker-bake.hcl target or group name (e.g. repository,
share, community, enterprise).
You can pass GRYPE_OPTS to override the default options passed to Grype, which
by default exit with a non-zero status if any vulnerability greater than high is
found and is filtering out known issues for which a fix is not available (yet or
ever).
Set GRYPE_OUTPUT_DIR to write each image's scan output to a file in that directory
instead of printing it to stdout, and GRYPE_OUTPUT_FORMAT to pick the format (see
Grype's -o/--output flag), e.g. to collect SARIF reports for upload elsewhere:
make grype GRYPE_TARGET=repository GRYPE_OPTS="--only-fixed --ignore-states wont-fix" GRYPE_OUTPUT_DIR=sarif GRYPE_OUTPUT_FORMAT=sarifYou can also run grype automatically at the end of the build process by setting
GRYPE_ONBUILD:
make all GRYPE_ONBUILD=1Images pushed to a registry carry an SPDX Software Bill of Materials, attached as a BuildKit SBOM attestation, with one attestation per image and per platform.
Getting an SBOM requires REGISTRY to be set, since the docker exporter used
when loading images locally cannot carry attestations:
export REGISTRY=myecr.domain.tld REGISTRY_NAMESPACE=myalfrescobuilds
make repositoryWhen calling bake directly instead of going through the make wrapper, pass
--sbom=true yourself:
docker buildx bake repository --set *.output=type=registry,push=true --sbom=trueSet BAKE_NO_SBOM=1 to turn SBOM generation off, for instance when targeting a
registry which does not support OCI attestation manifests.
To retrieve the SBOM of an image (the registry below is a placeholder, use your own):
docker buildx imagetools inspect myecr.domain.tld/myalfrescobuilds/alfresco-content-repository:<tag> --format '{{ json .SBOM }}'For a multi-arch image the output is keyed by platform, so pick one to get a plain SPDX document:
docker buildx imagetools inspect myecr.domain.tld/myalfrescobuilds/alfresco-content-repository:<tag> --format '{{ json (index .SBOM "linux/amd64").SPDX }}'The resulting document can be fed to any SPDX-aware tooling, for example to scan it without pulling the image:
docker buildx imagetools inspect myecr.domain.tld/myalfrescobuilds/alfresco-content-repository:<tag> --format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sbom.spdx.json
grype sbom:sbom.spdx.jsonProvenance records how and where an image was built: the repository and commit
it was built from, the job which built it and the build parameters used. It is
attached to images pushed to a registry as a BuildKit provenance
attestation,
one attestation per image and per platform. This repository's CI builds attach
it in mode=max.
Provenance is disabled by default, since a record only describes the build which
produced it, and says nothing to whoever consumes the image unless they know the
build environment it points at. If you build your own images and want
provenance, describe your own build by setting BAKE_PROVENANCE:
export REGISTRY=myecr.domain.tld REGISTRY_NAMESPACE=myalfrescobuilds BAKE_PROVENANCE=mode=max
make repositoryAs with the SBOM, this requires REGISTRY to be set, since the docker
exporter used when loading images locally cannot carry attestations. When
calling bake directly instead of going through the make wrapper, pass
--provenance yourself:
docker buildx bake repository --set *.output=type=registry,push=true --provenance=mode=maxUse mode=min for the invocation details only, or leave provenance disabled
when targeting a registry which does not support OCI attestation manifests.
To retrieve the provenance of an image, picking one platform out of the per-platform map (the registry below is a placeholder, use your own):
docker buildx imagetools inspect myecr.domain.tld/myalfrescobuilds/alfresco-content-repository:<tag> --format '{{ json (index .Provenance "linux/amd64").SLSA }}'The interesting fields of the resulting SLSA
v1 statement are
runDetails.builder.id, which points at the CI job which produced the image,
and the vcs:source / vcs:revision build request arguments, which hold the
repository and the commit it was built from. The mode=max statement also
carries every build argument, the Dockerfile itself and the resolved base image
digests. To check which repository, commit and job an image comes from:
docker buildx imagetools inspect myecr.domain.tld/myalfrescobuilds/alfresco-content-repository:<tag> \
--format '{{ json (index .Provenance "linux/amd64").SLSA }}' \
| jq '{builder: .runDetails.builder.id,
source: .buildDefinition.externalParameters.request.root.request.args["vcs:source"],
revision: .buildDefinition.externalParameters.request.root.request.args["vcs:revision"]}'A Python script to download artifacts from the Alfresco Nexus repository based on YAML configuration files.
We recommend using
makefor local operations on this repository but if you want to only leverage the fetching script here is the explanation
python3 scripts/fetch_artifacts.py [targets...] [options]You can specify one or more targets:
- No arguments: Processes the entire repository (only files matching
artifacts-*.yaml) - Directory path: Searches for artifact files in the specified directory
(only files matching
artifacts-*.yamlin that directory) - File path: Processes a specific artifact YAML file
- Glob pattern: Uses wildcards to match multiple files/directories
--log-level {DEBUG,INFO,WARNING,ERROR}- Set logging verbosity (default: INFO)--log-file FILE- Write logs to a file (in addition to console output)
python3 scripts/fetch_artifacts.py
python3 scripts/fetch_artifacts.py repository
python3 scripts/fetch_artifacts.py repository share aps
python3 scripts/fetch_artifacts.py "**/artifacts-26.yaml"
python3 scripts/fetch_artifacts.py repository --log-level DEBUG
python3 scripts/fetch_artifacts.py repository --log-file download.logACS_VERSION- Alfresco Content Services version (default: "26")NEXUS_USERNAME- Nexus repository usernameNEXUS_PASSWORD- Nexus repository passwordMAVEN_FQDN- Maven repository FQDN (default: "nexus.alfresco.com")MAVEN_REPO- Full Maven repository URL
For authentication check out nexus authentication
- When building
alltarget withmake, which is meant to build onlyacs, the fetching script will also try to download the artifacts related toaps. Build will proceed as it will use thedefaultbake target which points toenterpriseandcommunitytargets.
- Check if acs and aps charts need to be updated in
.github/actions/acs-deploymentand.github/actions/aps-deployment
respectively. - Ensure that the supported-matrix reflects the status of the currently released Alfresco products and update if necessary before proceeding.
- Ensure that in every
artifacts-*.yamlfile for bothrepositoryandshareimages, theupdatecli_amps_release_branchkey refer the latest minor version for every major acs version by inspecting the currently available release branches in acs-packaging repository. - Run the updatecli workflow and review the changes.
- Merge all the eventual dependabot and updatecli PRs (for nginx and tomcat base images)
- Agree on a name for the release and make sure to add it to the release notes.
Once everything has been merged to master, you can proceed to create a release with:
gh release create v0.2.0 -t "π Fougasse v0.2.0" --generate-notes -dFinally review the autogenerated release notes, remove not so interesting changes (e.g. GHA tuning and dependabot), highlight most interesting ones for the end users and publish the release.