Skip navigation
All Places > Alfresco Content Services (ECM) > Blog
1 2 3 Previous Next

Alfresco Content Services (ECM)

378 posts

Recently I have been involved in an investigation task about the Alfresco Tracker Subsystem, with a specific focus on the Content Tracker. This post is the output of the analysis, which can also be found in the SearchServices repository, under the documentation folder.   

The ContentTracker is part of the Alfresco Tracker Subsystem which is composed by the following members:

  • ModelTracker: for listening on model changes
  • ContentTracker: described in this post
  • MetadataTracker: for tracking changes in metadata nodes
  • AclTracker: for listening on ACLs changes
  • CascadeTracker: which manages cascade updates (i.e. updates related with the nodes hierarchy)
  • CommitTracker: which provides commit and rollback capabilities

Each Solr that composes your search infrastructure (regardless it holds a monolithic core or a shard) has a singleton instance of each tracker type, which is registered, configured and scheduled at SolrCore startup. The SolrCore holds a TrackerRegistry for maintaining a list of all "active" tracker instances.

The ContentTracker queries for documents with "unclean" content (i.e. data whose content has been modified in Alfresco), and then updates them. Periodically, at a configurable frequency, the ContentTracker checks for transactions containing nodes that have been marked as "Dirty" (changed) or "New". Then,

  • it retrieves the cached version of that data from the ContentStore
  • it retrieves the corresponding (text) content from Alfresco
  • it updates the ContentStore
  • it re-indexes the data in the hosting Solr instance

 

Later, the CommitTracker will persist those changes. 

 

The Tracking Subsystem

The class diagram below provides a high-level overview about the main classes involved in the Tracker Subsystem.

As you can see from the diagram, there's an abstract interface definition (Tracker) which declares what is expected by a Tracker and a Layer Supertype (AbstractTracker) which adopts a TemplateMethod [1] approach. It provides the common behavior and features inherited by all trackers, mainly in terms of:

  • Configuration
  • State definition (e.g. isSlave, isMaster, isInRollbackMode, isShutdown)
  • Constraints (e.g. there must be only one running instance of a given tracker type in a given moment)
  • Locking: the two Semaphore instances depicted in the diagram used for a) implementing the constraint described in the previous point b) providing an inter-trackers synchronisation mechanism.

The Tracker behavior is defined in the track() method that each tracker must implement. As said above, the AbstractTracker forces a common behaviour on all trackers by declaring a final version of that method, and then it delegates to the concrete trackers (subclasses) the specific logic by requiring them the implementation of the doTrack() method.

Each tracker is a stateful object which is initialized, registered in a TrackerRegistry and scheduled at startup in the SolrCoreLoadRegistration class. The other relevant classes depicted in the diagram are:

  • SolrCore: the dashed dependency relationship means that a Tracker doesn't hold a stable reference to the SolrCore: it obtains that reference each time it's needed.
  • ThreadHandler: The ThreadExecutionPool manager which holds a pool of threads needed for scheduling asynchronous tasks (i.e. unclean content reindexing)
  • TrackerState: being a shared instance across all trackers, it would have been called something like TrackersState or TrackerSubsystemState. It is used for holding the trackers state (e.g. lastTxIdOnServer, trackerCycles, lastStartTime)
  • TrackerStats: maintains a global stats about all trackers. Following the same approach of the TrackerState, it is a shared instance and therefore the name is a little bit misleading because it is related to all trackers
  • SOLRAPIClient: this is the HTTP proxy / facade towards Alfresco REST API: in the sequence diagrams these interactions are depicted in green
  • SolrInformationServer: The Solr binding for the InformationServer interface, which defines the abstract contract of the underlying search infrastructure

Startup and Shutdown

The Trackers startup and registration flow is depicted in the following sequence diagram:

Solr provides, through the interface SolrEventListener, a notification mechanism for registering custom plugins during a SolrCorelifecycle. The Tracker Subsystem is initialized, configured and scheduled in the SolrCoreLoadListener which delegates the concrete work to SolrCoreLoadRegistration. Here, a new instance of each tracker is created, configured, registered and then scheduled by means of a Quartz Scheduler. Trackers can share a common frequency (as defined in the alfresco.cronproperty) or they can have a specific configuration (e.g. alfresco.content.tracker.cron).

The SolrCoreLoadRegistration also registers a shutdown hook which makes sure all registered trackers will follow the same hosting SolrCore lifecycle.

Content Tracking

The sequence diagram below details what happens in a single tracking task executed by the ContentTracker: 

 

 

At a given frequency (which again, can be the same for each tracker or overriden per tracker type) the Quartz Scheduler invokes the doTrack() method of the ContentTracker. Prior to that, the logic in the AbstractTracker is executed following the TemplateMethod [1] described above; specifically the "Running" lock is acquired and the tracker is put in a "Running" state.

 

Then the ContentTracker does the following:

  • get documents with "unclean" content
  • if that list is not empty, each document is scheduled (asynchronously) for being updated, in the content store and in the index

 

In order to do that, the ContentTracker never uses directly the proxy towards ACS (i.e. the SOLRAPIClient instance); instead, it delegates that logic to the SolrInformationServer class. The first step (getDocsWithUncleanContent) searches in the local index all transactions which are associated to documents that have been marked as "Dirty" or "New". The field where this information is recorded is FTSSTATUS; it could have one of the following values:

 

  • Dirty: content has been updated / changed
  • New: content is new
  • Clean: content is up to date, there's no need to refresh it

 

The "Dirty" documents are returned as triples containing the tenant, the ACL identifier and the DB identifier.

 

NOTE: this first phase uses only the local Solr index, no remote call is involved.

 

If the list of Tenant/ACLID/DBID triples is not empty, that means we need to fetch and update the text content of the corresponding documents. In order to do that, each document is wrapped in a Runnable object and submitted to a thread pool executor. That makes each document content processing asynchronous.

 

The ContentIndexWorkerRunnable, once executed, delegates the actual update to the SolrInformationServer which, as said above, contains the logic needed for dealing with the underlying Solr infrastructure; specifically:

 

  • the document that needs to be refreshed, uniquely identified by the tenant and the db identifier, is retrieved from the local content store. In case the cached document cannot be found in the content store, the /api/solr/metadata remote API is contacted in order to rebuild the document (only metadata) from scratch.
  • the api/solr/textContent is called in order to fetch the text content associated with the node, plus the transformation metadata (e.g, status, exception, elapsed time)
  • if the alfresco.fingerprint configuration property is set to true and the retrieved text is not empty the fingerprint is computed and stored in the MINHASH field of the document
  • the content fields are set
  • the document is marked as clean (i.e. FTSSTATUS = "Clean") since its content is now up to date
  • the cached version is overwritten in the content store with the up to date definition
  • the document (which is a SolrInputDocument instance) is indexed in Solr

 

Rollback

The Rollback sequence diagram illustrates how the rollback process works:

The commit/rollback process is a responsibility of the CommitTracker, so the ContentTracker is involved in these processes only indirectly.

When it is executed, the CommitTracker acquires the execution locks from the MetadataTracker and the AclTracker. Then it checks if one of them is in a rollback state. As we can imagine, that check will return true if some unhandled exception has occurred during indexing.

If one of the two trackers above reports an active rollback state, the CommitTracker lists all trackers, invalidates their state and issues a rollback command to Solr. That means any update sent to Solr by any tracker will be reverted.

How does the ContentTracker work in shard mode?

The only source that the ContentTracker checks in order to determine the "unclean" content that needs to be updated is the local index. As consequence of that, the ContentTracker behavior is the same regardless the search infrastructure shape and the context where the hosting Solr instance lives. That is, if we are running a standalone Solr instance there will be one a ContentTracker for each core watching the corresponding (monolithic) index. If instead we are in a sharded scenario, each shard will have a ContentTracker instance that will use the local shard index.

 

How does the ContentTracker work in Master/Slave mode?

In order to properly work in a Master/Slave infrastructure, the Tracker Subsystem (not the only ContentTracker) needs to be

  • enabled on Master(s)
  • disabled on Slaves

The only exceptions to that rule are about:

  • The MetadataTracker: only if the search infrastructure uses dynamic sharding [2] the Metadata tracker is in charge to register the Solr instance (the Shard) to Alfresco so it will be included in the subsequent queries. The tracker itself, in this scenario, won't track anything.
  • The ModelTracker: each Solr instance pulls, by means of this tracker, the custom models from Alfresco, so it must be enabled in any case.

The document file in the SearchService repository provides an additional paragraph with the configuration attributes related with the Tracker subsystem. I didn't put that long table in this post because it doesn't add any information: if you need to configure the trackers just have a look at the end of that document.     

 

What's next?

The Tracker Subsystem is one of the main areas where the Search Team is devolving analysis and investigation efforts: that will allow to find a space for introducing further improvements in the architecture. 

 

-------

[1] Template Method 

[2] Dynamic Sharding

I'm pleased to announce the availability of SDK 4.0 and 3.1.

 

The artifacts have been released to Maven Central. It might be a few days until the global archetype catalog updates, but read on for more details on how to get started today!

 

This release will enable developers to extend and customize Alfresco Content Services 6.0 and 6.1. In addition, the SDK 3.1 release brings a number of bug fixes as well as a few highly requested features.

 

Please note

SDK 4.0 is only compatible with ACS 6.0 and 6.1.

If you wish to extend and customize ACS 5.2 or older, please use SDK 3.1.

 

Building on top of the first beta of 4.0  that we released in January, we received a lot of feedback and we appreciate all the involvement, contributions and feedback.

 

SDK 4.0 brings changes to the underlying logic for running and testing your customizations. This means that the SDK now leverage containers to launch the full suite of Alfresco Content Services. By leveraging Docker containers we make it easy to start additional services, such as Transform Service, Search Services and much more.

 

If you are already familiar with SDK 3.X you will feel right at home. We still offer the All-in-one archetype, as well as platform-jar and share-jar archetypes. The project structure changed slightly to accommodate for the Docker setup, and the pom.xml has changed.

 

Key changes and improvements:

  • Two new sub modules introduced for All-in-one: platform-docker and share-docker. These modules provides the required setup in order to extend the ACS Docker containers with your customizations
  • A new Docker folder contains a docker-compose.yml file. This file is filtered by Maven to easily enable switching between versions
  • SDK 4 no longer depends on the Alfresco Maven Plugin since all runner logic is moved to Docker
  • Full support for ACS 6.0 and 6.1, both Enterprise and Community
  • Submodules are now renamed to be prefixed with the project
  • Full support for JRebel for hot reloading
  • More commands via run.sh / run.bat

 

Getting Started

We have a new getting started guide in the documentation, if you just can't wait to get your hands into the code here are a few things you need:

  1. Java 11
  2. Maven 3.3+ (we always recommend using the latest version)
  3. Docker

 

Note: If you are on Windows 7, you will need to install Docker Toolbox.

 

Once you have all three installed you can create an All-in-one with the following command:

mvn archetype:generate -DarchetypeGroupId=org.alfresco.maven.archetype -DarchetypeArtifactId=alfresco-allinone-archetype -DarchetypeVersion=4.0.0

 

In a few days once the global archetype catalog gets updated you'll be able to use the same old command: mvn

archetype:generate -Dfilter=org.alfresco:

 

Please have a look at the documentation and feel free to ask questions or raise an issue (or even better, a pull request!)

 

SDK 3.1

In addition to releasing SDK 4.0, we have also issued a minor release of the 3.x branch.

 

You can view the full list of closed issues here, but the main highlight here is that there is now a new goal in the Alfresco Maven Plugin which will only build the WAR files with your customizations applied.

 

Furthermore, SDK 3.1 now allows you to control the order AMPs are applied to the WAR file. When you define your platformModules and shareModules in your pom, the last defined will be the last to be applied.

 

If you have existing SDK 3.0 projects you can easily upgrade by simple changing the <alfresco.sdk.version /> property in your pom.

 

I want to thank everyone who contributed, we received a record number of pull requests from our wonderful community. We really appreciate it!

In this blog post I would like to share the upcoming changes to the contribution process for Alfresco components. In short, the well known ALF project (https://issues.alfresco.com/jira/projects/ALF) in our Jira is going to be archived.

For quite a while the ALF project was serving as a home of all the contributions from Community members, accommodating the feature requests, bug descriptions and patches. The world around it has changed and the project is no longer the easiest way for us to listen to Community and for Community to talk to us. We would like to propose to use GitHub as the place for collaboration, to be as close to the code as possible.

This is how it can look like.

The process will include a smaller number of steps to make the contribution easier to submit and approve:

 

How to find the right repository?

 

Alfresco Content Services has a lot of components, so it might be quite hard to find the right one to submit your issue. The following list contains all of the relevant repositories and short description of each of them.

If you are unsure which one to select if you experience an issue in Alfresco application, you can use one of the packaging projects to raise the issue. If you know exactly where the issue occurs, please create an issue in the relevant project instead of packaging projects. Needless to say that it is a lot easier for us to review and approve the PR with exact changes than reacting to an issue description without any points to code. Although we will try our best to pay attention to all of them.

Please keep in mind that this list may change over time.


If the feedback will be positive, we will gradually make the following changes:

Here's a brief overview of the new Alfresco Transform Service that is being introduced as an option for Alfresco Content Services (ACS) 6.1. It also includes evolutionary changes to the ACS Repository.

 
For those that missed DevCon 2019 you can also refer to following slides Transforming Transformers in ACS 6.1 and beyond.
Transforming Transformersfor ACS 6.1 and beyond !Jan VonkaArchitect & Product Owner@ Alfresco
 
The video can be found here:
 
I will try to come back and update this blog post with links to other related slides & videos such as:
 
If you've been closely following the ACS reference deployment projects, you may already have noticed the new Transform Service. This is available now alongside the ACS 6.1 release.
 
Helm Deployment Components
 
The Transform Service is an optional component that is enabled by default in the ACS reference deployments, whether using Docker Compose, Helm / Kubernetes or the AWS EKS stack.
 
  
Alternatively, you can access via ACS download trial.
 
Overview of the Transform Service
 
The following overview is extracted from the documentation. Thanks Adelaide Nxumalo.
 
The Transform Service handles the essential transforms, such as Microsoft Office documents, images, and PDFs. These include PNG for thumbnails, PDF and JPEG for downloads and previews.
 
The following diagram shows a simple representation of the Transform Service components:
  

This shows an example implementation of how you can deploy into AWS, using a number of managed services:

  • Amazon EKS - Elastic Container Service for Kubernetes
  • Amazon MQ - Managed message broker service for Apache ActiveMQ
  • Amazon EFS - Amazon Elastic File System
You can replace the AWS services (EKS, MQ, and EFS) with a self-managed Kubernetes cluster, ActiveMQ (configured with failover), and a shared file store, such as NFS.

The main components of the Transform Service are:

  • Content Repository (ACS): This is the repository where documents and other content resides. The repository produces and consumes events destined for the message broker (such as ActiveMQ or Amazon MQ). It also reads and writes documents to the shared file store.
  • ActiveMQ: This is the message broker (either a self-managed ActiveMQ instance or Amazon MQ), where the repository and the Transform Router send image transform requests and responses. These JSON-based messages are then passed to the Transform Router.
  • Transform Router: The Transform Router allows simple (single-step) and pipeline (multi-step) transforms that are passed to the Transform Engines. The Transform Router (and The Transform Engines) run as independently scalable Docker containers.
  • Transform Engines: The Transform Engines transform files sent by the repository. Here are some example transformation for each Transform Engine (this is not an exhaustive list):
    • LibreOffice (e.g. docx to pdf)
    • ImageMagick (e.g. resize)
    • Alfresco PDF Renderer (e.g. pdf to png)
    • Tika (e.g. docx to plain text)
  • Shared File Store: This is used as temporary storage for the original source file (stored by the repository), intermediate files (or multi-step transforms), and the final transformed target file. The target file is retrieved by the repository after it's been processed by one or more of the Transform Engines.

For more details, please refer to the Transform Service documentation:

 

 

Please try out try out ACS 6.1 reference deployments with the new Transform Service.

 

We look forward to your feedback. Please free to contact Preeti Nirwal or myself.

 

Thanks,

 

Jan Vonka & the INT team (Integrations n Transformations)

 

 

Motivation

Alfresco 6.0 switching to container deployment is a good thing, but Docker has efficiency issues on Mac. What's wrong with a well configured stand-alone Alfresco Community 6.0? Nothing!

 

Download Three Files

The attached Bash script automates the installation of Alfresco Community 6.0. It looks for 3 downloaded files in the same folder of the script or a folder specified as the script's first parameter.

The above links are for Tomcat 8.5.37, ACS 6.0.7-ga, Search Services 1.3.0.

 

Run The Install Script

Create an empty folder into which a stand-alone Alfresco Community will be installed. Be sure to set the environment variable JAVA_HOME. Then run the installation script, assuming everything else is in the parent folder:

mkdir 6.0.7-ga
cd 6.0.7-ga
../install-alfresco-6x.sh

The script will install all three archives, create or modify configuration files and startup scripts, download MySQL JDBC driver and the missing PDF renderer for Mac, start Solr6. It also applies the Share module for alfresco.war, which will ask you to press a few keys in between.

 

Create Your MySQL Schema

The script creates file tomcat/shared/classes/alfresco-global.properties with these MySQL database settings:

  • Schema name:  alf607ce
  • User name:  alfresco
  • Password:  alfresco

Here are the MySQL commands to create the schema:

$ mysql -u root
create schema alf607ce default character set utf8;
grant all on alf607ce.* to 'alfresco'@'localhost' identified by 'alfresco' with grant option;

 

Start and Stop Alfresco

./alfresco.sh start
./alfresco.sh jpda start # Start with debug
./alfresco.sh stop

 

Start and Stop Solr 6

The install script already starts Solr 6 for you. Subsequent start and stop commands are:

search-services/solr/bin/solr start
search-services/solr/bin/solr stop

 

Other Versions of Alfresco

This install script also works for 6.1.1. There is a bug in 6.1.2-ga that prevents alfresco.war from fully deployed and run in Tomcat. Just don't use it.

.

It is an exciting time here at Alfresco. We are working on a lot of improvements to the product, especially the way developers integrate and extend our products. In this brave new world of containers, micro services, message queues, cloud connectors and REST APIs we are laying out the foundation of the developer experience of the future.

While the future looks more like what we call "out of process extensions", we recognise that it's a process that we are going through, and we do not have all the answers yet and there is still a need to make in-process extensions to the platform.

 

There are several ways to build extensions to Alfresco Content Services, but a popular approach has been using the "Alfresco SDK". Updates to the SDK to accommodate for the changes in ACS 6.X have been delayed - until now.

 

I'm happy to announce that we have released the first beta of the SDK, and we're hoping to get some feedback before the final release!

 

This beta release targets ACS 6.0 Community and Enterprise. We are actively working on support for 6.1, but this is not included in this first beta release.

The ACS SDK 4.0 brings some changes, so I wanted to write a blog post to give some details on some of the decisions and reasons behind.

 

Embracing containers and Docker

Previously the SDK relied on starting an embedded H2 database and using the Apache Tomcat Maven Plugin.

The first issue we hit was due to changes in the database layer of ACS. This meant that we cannot leverage H2 anymore and to work around this, an external database is required for running ACS.

The second issue we hit was the Tomcat plugin. Essentially it is stuck on Tomcat 7.X, which starts to give a lot of issues with Java 9 and 11. The plugin has not been updated in years, and while we could technically manage something to work for ACS 6.0 Community edition, some upstream dependencies in ACS 6.0 and 6.1 Enterprise impacted it. By leveraging Docker to spin up the repository we make a more future proof solution.

Alfresco Search Services is already an executable on its own, and since we provide containers for it already and we're embracing Docker in the SDK, it was a no-brainer to spin up search too. Same goes for Transform Services (Enterprise only).

By embracing this approach we have reduced a lot of the "magic" that happens inside the SDK. We have been able to remove hundreds of lines to deal with unpacking Solr, H2 DB Scripts and Tomcat configuration. This means the SDK is more maintainable moving forward.

 

Project structure

If you've previously used SDK 3.0 you should feel right at home. We provide roughly the same project structure, except instead of packaging the WAR file with modules applied to it, we now have a docker module that builds a custom Docker image for ACS with your module applied.

We still feature the same three archetypes: All-in-one, Platform JAR and Share JAR.

In addition, we had to put more logic into the run.sh / run.bat files, to accommodate for Docker.

Previously, you could use the Alfresco Maven Plugin to start the repository using "mvn install alfresco:run". In SDK 4.0 you will need to either manually start Docker Compose, or use the run utilities to do it for you. You can read more about it here.

 

Getting Started

We have a new getting started guide on GitHub. Please note this is still work in progress, feedback and contributions are welcome!

Here is the short version:
You need Java 8 or 11 along with Maven and Docker for Desktop.
- If you are on Windows 7 you will need the Docker Toolbox because Docker for Desktop is not supported for Windows 7. Docker Toolbox will work just fine.

Fire up a terminal and generate your project:

mvn archetype:generate -Dfilter=org.alfresco:


You can now select the archetype you wish, then make sure you select the version "4.0.0-beta-1":

Choose archetype:
1: remote -> org.alfresco.maven.archetype:activiti-jar-archetype (Sample project with full support for lifecycle and rapid development of Activiti JARs)
2: remote -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco platform. Includes modules for Platform/Repository JAR and Share JAR)
3: remote -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of Repository AMPs (Alfresco Module Packages))
4: remote -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))
5: remote -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module
        Packages))
6: remote -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module
        Packages))
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 2
Choose org.alfresco.maven.archetype:alfresco-allinone-archetype version:
1: 2.0.0-beta-1
2: 2.0.0-beta-2
3: 2.0.0-beta-3
4: 2.0.0-beta-4
5: 2.0.0
6: 2.1.0
7: 2.1.1
8: 2.2.0
9: 3.0.0
10: 3.0.1
11: 4.0.0-beta-1
12: 4.0.0-SNAPSHOT
Choose a number: 12: 11

 

Fill out the groupId, artifactId and so on. Once your project is generated you can simply execute

./run.sh build_start

If you're on Windows simply use run.bat.

We have done tests on macOS, Linux, Windows 7 and Windows 10 and so far the results have been positive.

As mentioned above we are targeting ACS 6.0 for this first beta release.

 

We plan to release the final SDK 4.0 version around the same time as ACS 6.1, which of course means we will include full support for both 6.0 and 6.1 in the final release.

 

Stay tuned for more updates on this topic - we are iterating rapidly and hope the next beta will include support for ACS 6.1 as well as a number of enhancements, documentation and more. 

 

We welcome all kinds of feedback, feel free to open issues on GitHub or ask questions below.

For any contributions, please raise pull requests against the “sdk-4.0” branch on GitHub.

 

UPDATE Jan 28: Github links updated, some links were pointing to some feature branches which have now been merged. 

Introduction

Sometimes you need to use a 3rd party Java library when you develop Alfresco extensions. Meaning a library that is not available as part of the standard Alfresco installation. So you cannot just specify a provided dependency in the Maven POM and expect the library to be available in webapps/[alfresco|share]/WEB-INF/lib during runtime, you need to supply the 3rd party JAR file as part of the installation. This can be achieved by using what’s called an AMP file for the distribution of the extension. An AMP file can contain other JAR files and they are then installed automatically into the webapps/[alfresco|share]/WEB-INF/lib directory when you install the extension.

 

In this article we will use a 3rd party library called Jsoup that can be used to parse and create HTML. It’s not by default part of an Alfresco installation, so we need to supply this library via an AMP. To make sure the 3rd party library can be called and works we will create a Repository Web Script with a Java controller that uses the Jsoup library.

 

Alfresco SDK 3.0 can be used to build extensions for Alfresco version 4.2, 5.1, and 5.2. We are going to work with the default settings, which assumes version 5.2.

Source Code

Source code for this article can be found here: https://github.com/gravitonian/repo-ext-3rd-party-lib

Generating an Alfresco SDK 3.0 project

We need an Alfresco SDK 3.0 project to work with so let’s generate a Repository extension project. This is a project that can be used to develop extensions that should be applied to the alfresco.war file, such as a Repository Web Script.

 

Here is how to generate this SDK project:

 

$ mvn archetype:generate -Dfilter=org.alfresco:

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building Maven Stub Project (No POM) 1

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] <<< maven-archetype-plugin:3.0.1:generate (default-cli) < generate-sources @ standalone-pom<<<

[INFO]

[INFO]

[INFO] --- maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom---

[INFO] Generating project in Interactive mode

[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)

Choose archetype:

1: remote -> org.alfresco.maven.archetype:activiti-jar-archetype (Sample project with full support for lifecycle and rapid development of Activiti JARs)

2: remote -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample multi-module project for All-in-One development on the Alfresco plaftorm. Includes modules for Platform/Repository JAR and Share JAR)

3: remote -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of Repository AMPs (Alfresco Module Packages))

4: remote -> org.alfresco.maven.archetype:alfresco-platform-jar-archetype (Sample project with full support for lifecycle and rapid development of Platform/Repository JARs and AMPs (Alfresco Module Packages))

5: remote -> org.alfresco.maven.archetype:alfresco-share-jar-archetype (Share project with full support for lifecycle and rapid development of JARs and AMPs (Alfresco Module

       Packages))

6: remote -> org.alfresco.maven.archetype:share-amp-archetype (Share project with full support for lifecycle and rapid development of AMPs (Alfresco Module

       Packages))

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 4

Choose org.alfresco.maven.archetype:alfresco-platform-jar-archetype version:

1: 3.0.0

2: 3.0.1

Choose a number: 2:

Define value for property 'groupId': org.alfresco.training

Define value for property 'artifactId':repo-ext-3rd-party-lib

[INFO] Using property: version = 1.0-SNAPSHOT

Define value for property 'package' org.alfresco.training: :

Confirm properties configuration:

groupId: org.alfresco.training

artifactId: aio-3rd-party-lib

version: 1.0-SNAPSHOT

package: org.alfresco.training

Y: :

 

From the Maven archetype list choose alfresco-platform-jar-archetype, then select SDK version 3.0.1, and finally specify the group and artifact IDs for the project.

 

This generates an SDK project with the following files:

 

$ cd repo-ext-3rd-party-lib/

repo-ext-3rd-party-lib mbergljung$ tree

.

├── README.md

├── debug.bat

├── debug.sh

├── pom.xml

├── run.bat

├── run.sh

└── src

   ├── main

   │ ├── assembly

   │ │   ├── amp.xml

   │ │   ├── file-mapping.properties

   │ │   └── web

   │ │       └── README.md

   │ ├── java

   │ │   └── org

   │ │       └── alfresco

   │ │           └── training

   │ │               └── platformsample

   │ │                   ├── Demo.java

   │ │                   ├── DemoComponent.java

   │   │                └── HelloWorldWebScript.java

   │ └── resources

   │    ├── META-INF

   │    │ └── resources

   │    │ └── test.html

   │    └── alfresco

   │        ├── extension

   │        │ └── templates

   │        │ └── webscripts

   │        │ └── alfresco

   │        │    └── tutorials

   │        │        ├── helloworld.get.desc.xml

   │        │        ├── helloworld.get.html.ftl

   │        │        └── helloworld.get.js

   │        └── module

   │            └── repo-ext-3rd-party-lib

   │                ├── alfresco-global.properties

   │                ├── context

   │                │ ├── bootstrap-context.xml

   │                │ ├── service-context.xml

   │                │ └── webscript-context.xml

   │                ├── messages

   │                │ └── content-model.properties

   │                ├── model

   │                │ ├── content-model.xml

   │                │ └── workflow-model.xml

   │                ├── module-context.xml

   │                ├── module.properties

   │                └── workflow

   │                    └── sample-process.bpmn20.xml

   └── test

       ├── java

       │ └── org

       │ └── alfresco

       │    └── training

       ├── license

       │ └── README.md

       ├── properties

       │ └── local

       │ ├── alfresco-global-enterprise.properties

       │ ├── alfresco-global-h2.properties

       │ ├── alfresco-global-mysql.properties

       │ └── alfresco-global-postgresql.properties

       └── resources

           ├── alfresco

           │ └── extension

           │ ├── dev-log4j.properties

           │ └── disable-webscript-caching-context.xml

           ├── platform-hotswap-agent.properties

           └── tomcat

               └── context-solr.xml

 

Note that the Repository extension project comes with a Hello World Web Script that has a Java Controller. So we don’t need to create a new Web Script for our exercise, we can just extend the Hello World Web Script.

Add the 3rd Party Library Dependency

Before we can start using a 3rd party library we need to add a dependency to it in the Maven POM. Open up the repo-ext-3rd-party-lib/pom.xml project file and add a dependency to the JSoup library as follows:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>org.alfresco.training</groupId>
<artifactId>repo-ext-3rd-party-lib</artifactId>
<version>1.0-SNAPSHOT</version>
<name>repo-ext-3rd-party-lib Platform Jar Module - SDK 3</name>
<description>Platform JAR Module (to be included in the alfresco.war) - SDK 3</description>
<packaging>jar</packaging>

...

<dependencies>
<dependency>
<!-- jsoup HTML parser library @ https://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
...

If your IDE auto imports new Maven dependencies, then we should now be ready to use this library in our Web Script Java Controller.

Using the 3rd Party Lib in the Hello World Web Script Java Controller

Now, let’s use the Jsoup library in the Web Script’s Java Controller. Open up the repo-ext-3rd-party-lib/src/main/java/org/alfresco/training/platformsample/HelloWorldWebScript.java file and make changes so it looks like this:

 

package org.alfresco.training.platformsample;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class HelloWorldWebScript extends DeclarativeWebScript {
private static Log logger = LogFactory.getLog(HelloWorldWebScript.class);

protected Map<String, Object> executeImpl(
WebScriptRequest req, Status status, Cache cache) {
Map<String, Object> model = new HashMap<String, Object>();

Connection.Response html = null;
try {
html = Jsoup.connect("http://www.example.com/").execute();
} catch (IOException e) {
e.printStackTrace();
}

model.put("fromJava", "HelloFromJava(" + html.body() + ")");

logger.debug("Your 'Hello World' Web Script was called!");

return model;
}
}

 

Test it with the SDK 3.0 Runner

We can now test this out and see if it works by using the SDK 3.0 Runner, which is built into the Alfresco Maven Plugin. We can kick off Tomcat with the Repository extension applied to the alfresco.war as follows:

 

repo-ext-3rd-party-lib mbergljung$ mvn clean install alfresco:run

 

Now we can access the Web Script on the http://localhost:8080/alfresco/s/sample/helloworld URL, we should see the following response:

 

 

So that worked nicely.

Create a distribution AMP for the extension

If you look in the repo-ext-3rd-party-lib/target directory you will see the repo-ext-3rd-party-lib-1.0-SNAPSHOT.jar file, which contains the extension code (i.e. the Hello World Web Script files). But it does not contain the Jsoup library, so it will not work to just drop this file into an Alfresco 5.2 installation. We need to provide an AMP with this extension JAR and the Jsoup JAR.

 

Enable AMP file generation by uncommenting the maven-assembly-plugin in the repo-ext-3rd-party-lib/pom.xml project file:

 

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>org.alfresco.training</groupId>
<artifactId>repo-ext-3rd-party-lib</artifactId>
<version>1.0-SNAPSHOT</version>
<name>repo-ext-3rd-party-lib Platform Jar Module - SDK 3</name>
<description>Platform JAR Module (to be included in the alfresco.war) - SDK 3</description>
<packaging>jar</packaging>
...
<build>
<plugins>
...
<!--
Build an AMP if 3rd party libs are needed by the extensions
JARs are the default artifact produced in your modules, if you want to build an amp for each module
you have to enable this plugin and inspect the src/main/assembly.xml file if you want to customize
the layout of your AMP. The end result is that Maven will produce both a JAR file and an AMP with your
module.
-->

<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>build-amp-file</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptor>src/main/assembly/amp.xml</descriptor>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.alfresco.maven.plugin</groupId>
<artifactId>alfresco-maven-plugin</artifactId>
<version>${alfresco.sdk.version}</version>
</dependency>
</dependencies>
</plugin>
...

 

 

Now execute the build again to create also an AMP:

 

repo-ext-3rd-party-lib mbergljung$mvn clean package

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building repo-ext-3rd-party-lib Platform Jar Module - SDK 3 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ repo-ext-3rd-party-lib---

[INFO] Deleting /Users/mbergljung/IDEAProjects/sdk-test/repo-ext-3rd-party-lib/target

[INFO]

[INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ repo-ext-3rd-party-lib---

[INFO] Using 'UTF-8' encoding to copy filtered resources.

[INFO] Copying 14 resources

[INFO]

[INFO] --- jrebel-maven-plugin:1.1.6:generate (generate-rebel-xml) @ repo-ext-3rd-party-lib---

[INFO] Processing org.alfresco.training:repo-ext-3rd-party-lib with packaging jar

[INFO]

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ repo-ext-3rd-party-lib---

[INFO] Changes detected - recompiling the module!

[INFO] Compiling 3 source files to /Users/mbergljung/IDEAProjects/sdk-test/repo-ext-3rd-party-lib/target/classes

[INFO]

[INFO] --- maven-resources-plugin:3.0.1:testResources (default-testResources) @ repo-ext-3rd-party-lib---

[INFO] Using 'UTF-8' encoding to copy filtered resources.

[INFO] Copying 4 resources

[INFO]

[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ repo-ext-3rd-party-lib---

[INFO] Nothing to compile - all classes are up to date

[INFO]

[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ repo-ext-3rd-party-lib---

[INFO]

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ repo-ext-3rd-party-lib---

[INFO] Building jar: /Users/mbergljung/IDEAProjects/sdk-test/repo-ext-3rd-party-lib/target/repo-ext-3rd-party-lib-1.0-SNAPSHOT.jar

[INFO]

[INFO] --- maven-assembly-plugin:2.6:single (build-amp-file) @ repo-ext-3rd-party-lib---

[INFO] Building amp: /Users/mbergljung/IDEAProjects/sdk-test/repo-ext-3rd-party-lib/target/repo-ext-3rd-party-lib-1.0-SNAPSHOT.amp

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 6.121 s

[INFO] Finished at: 2018-12-19T11:44:33Z

[INFO] Final Memory: 50M/529M

[INFO] ------------------------------------------------------------------------

 

We can see in the console logs that the target/repo-ext-3rd-party-lib-1.0-SNAPSHOT.amp

AMP file was created. Looking inside the AMP (it’s just a ZIP) we can see it contains the following files:

 

repo-ext-3rd-party-lib-1.0-SNAPSHOT mbergljung$ tree

.

├── file-mapping.properties

├── lib

│   ├── jsoup-1.11.3.jar

│   └── repo-ext-3rd-party-lib-1.0-SNAPSHOT.jar

├── module.properties

└── web

 

So we should be ready to distribute this AMP file and use it to install the extension into any Alfresco 5.2 server.

Deploy the AMP to an Alfresco Server

We now got a tested Repository Extension that uses a third party library. Time to deploy it to a real Alfresco server. But before we do that, what would happen if we just dropped the repo-ext-3rd-party-lib-1.0-SNAPSHOT.jar into the <ALFRESCO_INSTALL_DIR>/tomcat/webapps/alfresco/WEB-INF/lib directory and restarted. We would see an error like follows when calling the Web Script:

 

Caused by: java.lang.NoClassDefFoundError: org/jsoup/Jsoup

at org.alfresco.training.platformsample.HelloWorldWebScript.executeImpl(HelloWorldWebScript.java:47)

at org.springframework.extensions.webscripts.DeclarativeWebScript.execute(DeclarativeWebScript.java:64)

... 36 more

Caused by: java.lang.ClassNotFoundException: org.jsoup.Jsoup

at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)

at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)

... 38 more

 

This is because the extension JAR does not contain the 3rd party library that is needed, so we really need to install the AMP to get everything needed for the extension. I got a 5.2 installation locally and I can use the Alfresco Module Management tool to install the AMP as follows (note that I have stopped the server and I have copied the AMP to the tomcat/webapps directory):

 

acs5211 mbergljung$ ./alfresco.sh stop

Using CATALINA_BASE:   /Applications/acs5211/tomcat

Using CATALINA_HOME:   /Applications/acs5211/tomcat

Using CATALINA_TMPDIR: /Applications/acs5211/tomcat/temp

Using JRE_HOME:        /Applications/acs5211/java

Using CLASSPATH:       /Applications/acs5211/tomcat/bin/bootstrap.jar:/Applications/acs5211/tomcat/bin/tomcat-juli.jar

Using CATALINA_PID:    /Applications/acs5211/tomcat/temp/catalina.pid

Tomcat stopped.

/Applications/acs5211/tomcat/scripts/ctl.sh : tomcat stopped

waiting for server to shut down.... done

server stopped

/Applications/acs5211/postgresql/scripts/ctl.sh : postgresql stopped

 

acs5211 mbergljung$ cd tomcat/webapps/

webapps mbergljung$ cp ~/IDEAProjects/sdk-test/repo-ext-3rd-party-lib/target/repo-ext-3rd-party-lib-1.0-SNAPSHOT.amp .

 

webapps mbergljung$rm -rf alfresco

 

webapps mbergljung$ ls -l

total 694472

drwxr-xr-x   9 mbergljung admin        288 4 Jul 13:58 ROOT

-rw-r--r--   1 mbergljung admin     274599 19 Sep 2017 ROOT.war

drwxr-xr-x   5 mbergljung admin        160 4 Jul 13:58 _vti_bin

-rw-rw-r--   1 mbergljung admin     763917 6 Apr 2017 _vti_bin.war

-rw-r--r--   1 mbergljung admin  168007175 26 Feb 2018 alfresco.war

drwxr-xr-x   7 mbergljung admin        224 26 Feb 2018 host-manager

drwxr-xr-x   8 mbergljung admin        256 26 Feb 2018 manager

-rw-r--r--@  1 mbergljung admin     383139 19 Dec 13:08 repo-ext-3rd-party-lib-1.0-SNAPSHOT.amp

drwxr-xr-x  18 mbergljung  admin 576  4 Jul 13:58 share

-rw-r--r--   1 mbergljung admin   73494142 26 Feb 2018 share.war

drwxr-xr-x  10 mbergljung  admin 320  4 Jul 13:58 solr4

-rw-r--r--   1 mbergljung admin  100394429 19 Sep 2017 solr4.war

 

webapps mbergljung$ java -jar ../../bin/alfresco-mmt.jar install repo-ext-3rd-party-lib-1.0-SNAPSHOT.amp alfresco.war

 

webapps mbergljung$ ls -l

total 1023360

drwxr-xr-x   9 mbergljung admin        288 4 Jul 13:58 ROOT

-rw-r--r--   1 mbergljung admin     274599 19 Sep 2017 ROOT.war

drwxr-xr-x   5 mbergljung admin        160 4 Jul 13:58 _vti_bin

-rw-rw-r--   1 mbergljung admin     763917 6 Apr 2017 _vti_bin.war

-rw-r--r--   1 mbergljung admin  168389519 19 Dec 13:10 alfresco.war

-rw-r--r--   1 mbergljung admin  168007175 26 Feb 2018 alfresco.war-1545225046395.bak

drwxr-xr-x   7 mbergljung admin        224 26 Feb 2018 host-manager

drwxr-xr-x   8 mbergljung admin        256 26 Feb 2018 manager

-rw-r--r--@  1 mbergljung admin     383139 19 Dec 13:08 repo-ext-3rd-party-lib-1.0-SNAPSHOT.amp

drwxr-xr-x  18 mbergljung  admin 576  4 Jul 13:58 share

-rw-r--r--   1 mbergljung admin   73494142 26 Feb 2018 share.war

drwxr-xr-x  10 mbergljung  admin 320  4 Jul 13:58 solr4

-rw-r--r--   1 mbergljung admin  100394429 19 Sep 2017 solr4.war

 

Note also that I removed the exploded /alfresco WAR directory, so we are sure the newly generated WAR will be deployed instead.

 

Now start it all up again:

 

webapps mbergljung$ cd ..

tomcat mbergljung$ cd ..

acs5211 mbergljung$ ./alfresco.sh start

waiting for server to start.... done

server started

/Applications/acs5211/postgresql/scripts/ctl.sh : postgresql  started at port 5432

Using CATALINA_BASE:   /Applications/acs5211/tomcat

Using CATALINA_HOME:   /Applications/acs5211/tomcat

Using CATALINA_TMPDIR: /Applications/acs5211/tomcat/temp

Using JRE_HOME:        /Applications/acs5211/java

Using CLASSPATH:       /Applications/acs5211/tomcat/bin/bootstrap.jar:/Applications/acs5211/tomcat/bin/tomcat-juli.jar

Using CATALINA_PID:    /Applications/acs5211/tomcat/temp/catalina.pid

Tomcat started.

/Applications/acs5211/tomcat/scripts/ctl.sh : tomcat started

acs5211 mbergljung$ tail -f tomcat/logs/catalina.out

...


You should now be able to hit the Web Script URL again with a successful response:  http://localhost:8080/alfresco/s/sample/helloworld

Introduction

The way you deploy and run the Alfresco Content Services (ACS) solution has changed significantly in version 6.0. Traditionally you would download an installer that would install Java, Tomcat, Database, WARs, tools, etc, and things would be configured to work together. Then you would use a script to kick things off. That’s no longer the case and there are no installers available. We will be working with Docker containers instead.

 

It’s now possible to kick off an ACS 6.0 solution from a number of Docker images. These images are available in the https://hub.docker.com repository. However, kicking off individual Docker containers based on these images, and configuring them to work together, might not be the most productive way to get up and running with ACS. To make things easier, and achieve a one-click to deploy and run solution, a Docker compose file is available to quickly deploy and run the ACS solution when you need to test something or work on a proof-of-concept (PoC).

 

There are also Helm Charts available to deploy the ACS solution in production as a Kubernetes cluster in for example AWS, this is not covered in this article.

Source Code and Tools

The source code for this article can be downloaded here. It will become useful when you read the section about creating custom ACS images.

 

There is now an Alfresco Extension Project generator that implements a lot of the concepts discussed in this article around building extensions and deploying them to containers. 

Concepts and Technologies

The following is a list of concepts (terms) and technologies that you will come in contact with when deploying and using the Alfresco Content Services version 6.0. If you know all about Docker, then you can skip this part.

Virtual Machine Monitor (Hypervisor)

A Hypervisor is used to run other OS instances on your local host machine. Typically it's used to run a different OS on your machine, such as Windows on a Mac. When you run another OS on your host it is called a guest OS, and it runs in a so called Virtual Machine (VM).

Image

An image is a number of layers that can be used to instantiate a container. This could be, for example, Java + Apache Tomcat. You can find all kinds of Docker Images on the public repository called Docker Hub. There are also private image repositories (for things like commercial enterprise images), such as the one Alfresco uses called Quay.  

Container

An instance of an image is called a container. You have an image, which is a set of layers as described. If you start this image, you have a running container of this image. You can have many running containers of the same image.

Docker

Docker is one of the most popular container platforms. Docker provides functionality for deploying and running applications in containers based on images.

Docker Compose

When you have many containers making up your solution, such as with ACS, and you need to configure each one of the containers so they work nicely together, then you need a tool for this.

Docker Compose is such a tool for defining and running multi-container Docker applications locally. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.

Dockerfile

A Dockerfile is a script containing a successive series of instructions, directions, and commands which are to be executed to form a new Docker image. Each command executed translates to a new layer in the image, forming the end product. They replace the process of doing everything manually and repeatedly. When a Dockerfile is finished executing, you end up having built a new image, which then you use to start a new Docker container.

Difference between Containers and Virtual Machines

It is important to understand the difference between using containers and using VMs. Here is a picture from What is a Container | Docker  that illustrates:

 

 

The main difference is that when you are running a container you are not kicking off a complete new OS instance. And this makes containers much more lightweight and quicker to start. A container is also taking up much less space on your hard-disk as it does not have to ship the whole OS.

Installing Software Required to Deploy ACS

Before we can deploy and run the Alfresco Content Services it is necessary to install the technologies that it uses.

Docker

You probably already have Docker installed as everything these days is easily accessible and run as containers. If you don't, go to the Docker Store and download the latest stable community edition (CE). Make sure the Docker daemon is running:

 

mbergljung$ docker -v

Docker version 17.09.0-ce, build afdb6d4

 

Also, verify that you have the recommended Docker version for running ACS, which is at least 17.09. You also want to verify the Docker Compose version, which should be at least 1.16.1:

$ docker-compose -v

docker-compose version 1.18.0, build 8dd22a9

 

If you are on Windows make sure that you are executing Docker commands from Windows PowerShell:

 

Getting to know the public Alfresco Docker Images

To find out about all the Alfresco images that are available at the Docker Hub registry go to https://hub.docker.com/u/alfresco/ and you will see a list of images belonging to the alfresco user. You should see something similar to the following screenshot (note: not all images are visible in the screenshot):

 

 

As we can see, a number of Docker images are available that relate to ACS:

 

  • alfresco/alfresco-share - the Alfresco Share web interface (i.e. share.war) running on Apache Tomcat
  • alfresco/alfresco-search-services - the Solr 6 based search service running on Jetty
  • alfresco/alfresco-content-repository-community - the Alfresco Repository app (i.e. alfresco.war) running on Apache Tomcat

 

There are also other supporting features available, such as Docker images for image and document transformation:

 

  • alfresco/alfresco-docker-imagemagick
  • alfresco/alfresco-docker-libreoffice
  • alfresco/alfresco-docker-alfresco-pdf-renderer

To build the alfresco/alfresco-content-repository-community image Alfresco uses the GitHub - Alfresco/acs-community-packaging  project. This project does not include any deployment templates. The GitHub - Alfresco/acs-community-deployment project contains deployment templates and instructions. It includes a Docker Compose script that can be used to launch a demo, test, or PoC ACS 6.0 system. You can customize this script if you like in order to run with different versions than those set by default, which are usually the latest versions.

When the ACS system is up and running you will have the following containers running:

  • Alfresco Community Repository 6.0 with:
    • Alfresco Share Services AMP
    • Alfresco Office Services (AOS) AMP
    • Alfresco vti-bin war - that helps with AOS integration
    • Alfresco Google Docs Integration Repo AMP
  • Alfresco Share 6.0 with:
    • Alfresco Google Docs Integration Share AMP
  • Alfresco Search Services (Solr 6)
  • A Postgres Database

 

To build custom images based on these Alfresco images in Docker Hub you need to create some Docker files. While doing this you can include custom AMPs and JARs. We will see how to do that later in the article. Before we do that we will walk through how to start an ACS system with Docker Compose and how to start an ACS system container by container.

Introduction to the Alfresco ACS Community Packaging Project

As mentioned, this is the project that is used to build Alfresco Community Repository artifacts, such as the Docker Image for ACS 6.0 Repo. Clone the ACS Community Packaging project so we can have a look at it:

 

$ git clone https://github.com/Alfresco/acs-community-packaging.git

 

$ cd acs-community-packaging/

 

Now, let’s look at what the different directories contain:

 

$ tree

.

├── CONTRIBUTING.md

├── LICENSE

├── README.md

 

(Contains a build script to create a Distribution ZIP with Repo, Share, and Solr4 etc, so you can install manually or facilitate upgrades)

├── distribution

│   ├── pom.xml

│   └── src

│       ├── assembly

│       │ └── distribution.xml

│       └── main

│           └── resources

│               ├── README.txt

│               ├── bin

│               │ ├── apply_amps.bat

│               │ ├── apply_amps.sh

│               │ ├── clean_tomcat.bat

│               │ └── clean_tomcat.sh

│               ├── licenses

│               │ ├── 3rd-party

...

│               │ ├── license.txt

│               │ └── notice.txt

│               └── web-server

│                   ├── conf-Tomcat7

│                   │   └── Catalina

│                   │       └── localhost

│                   │           └── alfresco.xml

│                   └── conf-Tomcat8

│                       └── Catalina

│                           └── localhost

│                               └── alfresco.xml

 

(Contains the Dockerfile to build the Alfresco Repo Docker image - alfresco/alfresco-content-repository-community)

├── docker-alfresco

│   ├── Dockerfile

│   ├── pom.xml

│   └── test

│       ├── docker-compose.yml

│       └── test.env

  

(Builds the alfresco.war)

├── war

 

As we can see, there’s no Alfresco Share or Search Service docker files. They reside in their own projects:

 

 

Note: We don’t need these projects for this article but it good to know about them to get an idea of how the images are produced.

 

If you are interested in the ACS 6.0 Enterprise packaging, then have a look at the http://github.com/Alfresco/acs-packaging project.

Introduction to the Alfresco ACS Community Deployment Project

This project contains the Docker Compose file that we will use in this article to start up an ASC Community 6.0 environment locally. If you are interested in the Kubernetes Helm charts to be able to deploy ACS Community with Kubernetes, then this is included in this project as well (Note: Kubernetes deployment is not covered in this article).

 

Clone the ACS Community Deployment project so we can have a look at it:

 

$ git clone https://github.com/Alfresco/acs-community-deployment.git 

 

$ cd acs-community-deployment/

 

Now, let’s look at what the different directories contain:

 

acs-community-deployment mbergljung$ tree

.

├── CONTRIBUTING.md

├── LICENSE

├── README.md

 

(Contains the Docker Compose YAML file to be able to start a full ACS 6.0 environment with Repo, Share, Solr, PostgreSQL)

├── docker-compose

│   ├── docker-compose.yml

│   └── test.env

 

(Contains Helm Charts to be able to deploy ACS Kubernetes cluster to AWS or locally via Minikube) 

└── helm

    └── alfresco-content-services-community

        ├── Chart.yaml

        ├── requirements.yaml

        ├── templates

        │   ├── NOTES.txt

        │   ├── _helpers.tpl

        │   ├── config-repository.yaml

        │   ├── config-share.yaml

        │   ├── deployment-repository.yaml

        │   ├── deployment-share.yaml

        │   ├── ingress-repository.yaml

        │   ├── ingress-share.yaml

        │   ├── svc-repository.yaml

        │   ├── svc-share.yaml

        └── values.yaml

 

If you are interested in the ACS 6.0 Enterprise deployment, then have a look at the http://github.com/Alfresco/acs-deployment project.

 

Deploying the ACS system with Docker Compose

Let’s see how easy it is to kick off a demo, test, or PoC ACS 6.0 solution with the supplied Docker Compose file. It will be similar to using the old installer and the shell script, except it will now be a whole lot easier to remove the installation and to keep several installations in parallel.

Using the Docker Compose file to start the ACS solution

After you have cloned the ACS Community Packaging project it’s time to get started.

Make sure the local machine has ports 5432, 8080, 8082, and 8083 free as they are used in the docker-compose.yml file.

Step into the directory where you cloned the acs-community-deployment project, then navigate into the docker-compose sub-directory, followed by command docker-compose up (if on Windows use Windows PowerShell):

 

acs-community-deployment mbergljung$ cd docker-compose/

docker-compose mbergljung$docker-compose up

 

Creating network "dockercompose_default" with the default driver

Pulling solr6 (alfresco/alfresco-search-services:1.1.1)...

1.1.1: Pulling from alfresco/alfresco-search-services

6fd64836e300: Already exists

8ff6188dadfc: Already exists

d1b16fb40528: Already exists

fed33e3ce39c: Already exists

96f24514a7b3: Pull complete

6f415ea07e70: Pull complete

e2f858f39b3d: Pull complete

Digest: sha256:be7bf1463c55ced0058becdcd9ad952b3f770213e55b82c119d0eca95e70c7d8

Status: Downloaded newer image for alfresco/alfresco-search-services:1.1.1

Pulling alfresco (alfresco/alfresco-content-repository-community:6.0.5-ea)...

6.0.5-ea: Pulling from alfresco/alfresco-content-repository-community

18b8eb7e7f01: Already exists

f9d093c4cd43: Pull complete

05b40fb97183: Pull complete

6afa3ee9ddb6: Pull complete

 

...

Digest: sha256:9ab9496c2e3f6f26877f27db1c003b64d7b3ffe0aefc0ffd123dbfa6cddd8f5a

Status: Downloaded newer image for alfresco/alfresco-content-repository-community:6.0.5-ea

Creating dockercompose_solr6_1    ... done

Creating dockercompose_share_1    ... done

Creating dockercompose_alfresco_1 ... done

Creating dockercompose_postgres_1 ... done

Attaching to dockercompose_share_1, dockercompose_alfresco_1, dockercompose_solr6_1, dockercompose_postgres_1

share_1     | Replace 'REPO_HOST' with 'alfresco' and 'REPO_PORT' with '8080'

share_1     | 23-May-2018 07:15:34.483 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.23

 

...

share_1     | 23-May-2018 07:15:34.850 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]

share_1     | 23-May-2018 07:15:34.897 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read

share_1     | 23-May-2018 07:15:34.905 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]

share_1     | 23-May-2018 07:15:34.911 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read

share_1     | 23-May-2018 07:15:34.912 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1286 ms

share_1     | 23-May-2018 07:15:34.976 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]

share_1     | 23-May-2018 07:15:34.977 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.23

share_1     | 23-May-2018 07:15:34.998 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/manager]

postgres_1  | The files belonging to this database system will be owned by user "postgres".

postgres_1  | This user must also own the server process.

postgres_1  |

postgres_1  | The database cluster will be initialized with locale "en_US.utf8".

postgres_1  | The default database encoding has accordingly been set to "UTF8".

postgres_1  | The default text search configuration will be set to "english".

postgres_1  |

postgres_1  | Data page checksums are disabled.

postgres_1  |

postgres_1  | fixing permissions on existing directory /var/lib/postgresql/data ... ok

postgres_1  | creating subdirectories ... ok

postgres_1  | selecting default max_connections ... 100

postgres_1  | selecting default shared_buffers ... 128MB

postgres_1  | selecting dynamic shared memory implementation ... posix

postgres_1  | creating configuration files ... ok

postgres_1  | running bootstrap script ... ok

share_1     | 23-May-2018 07:15:36.158 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/manager] has finished in [1,157] ms

share_1     | 23-May-2018 07:15:36.160 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/docs]

share_1     | 23-May-2018 07:15:36.186 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/docs] has finished in [26] ms

share_1     | 23-May-2018 07:15:36.187 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/examples]

alfresco_1  | 23-May-2018 07:15:36.245 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.28

 

...

 

alfresco_1  | 23-May-2018 07:15:37.284 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]

share_1     | 23-May-2018 07:15:37.320 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/ROOT] has finished in [86] ms

share_1     | 23-May-2018 07:15:37.321 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/share]

 

...

alfresco_1  | 23-May-2018 07:15:37.490 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]

alfresco_1  | 23-May-2018 07:15:37.490 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.28

alfresco_1  | 23-May-2018 07:15:37.586 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/ROOT.war]

alfresco_1  | 23-May-2018 07:15:37.693 WARNING [localhost-startStop-1] org.apache.catalina.startup.SetContextPropertiesRule.begin [SetContextPropertiesRule]{Context} Setting property 'debug' to '100' did not find a matching property.

...

postgres_1  | waiting for server to start....2018-05-23 07:15:37.855 UTC [39] LOG:  listening on IPv4 address "127.0.0.1", port 5432

...

org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/alfresco]

solr6_1     | 2018-05-23 07:15:44.592 INFO  (main) [   ] o.e.j.s.Server jetty-9.3.8.v20160314

solr6_1     | 2018-05-23 07:15:45.800 INFO  (main) [   ] o.a.s.s.SolrDispatchFilter  ___      _       Welcome to Apache Solr? version 6.3.0

solr6_1     | 2018-05-23 07:15:45.812 INFO  (main) [   ] o.a.s.s.SolrDispatchFilter / __| ___| |_ _   Starting in standalone mode on port 8983

solr6_1     | 2018-05-23 07:15:45.813 INFO  (main) [   ] o.a.s.s.SolrDispatchFilter \__ \/ _ \ | '_|  Install dir: /opt/alfresco-search-services/solr

solr6_1     | 2018-05-23 07:15:46.072 INFO  (main) [   ] o.a.s.s.SolrDispatchFilter |___/\___/_|_|    Start time: 2018-05-23T07:15:45.817Z

solr6_1     | 2018-05-23 07:15:48.368 INFO  (main) [   ] o.e.j.s.ServerConnector Started ServerConnector@71687585{HTTP/1.1,[http/1.1]}{0.0.0.0:8983}

solr6_1     | 2018-05-23 07:15:48.382 INFO  (main) [   ] o.e.j.s.Server Started @5374ms

share_1     | 23-May-2018 07:15:49.439 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.

share_1     | May 23, 2018 7:15:49 AM org.apache.catalina.core.ApplicationContext log

share_1     | INFO: No Spring WebApplicationInitializer types detected on classpath

share_1     | May 23, 2018 7:15:49 AM org.apache.catalina.core.ApplicationContext log

share_1     | INFO: Initializing Spring root WebApplicationContext

share_1     | 2018-05-23 07:15:56,036  INFO  [config.packaging.ModulePackageManager] [localhost-startStop-1] Found 1 module package(s)

share_1     |  2018-05-23 07:15:56,043  INFO  [config.packaging.ModulePackageManager] [localhost-startStop-1] Alfresco / Google Docs Share Module, 3.0.4.2, The Share side artifacts of the Alfresco / Google Docs Integration.

share_1     |

share_1     |  2018-05-23 07:15:56,735  INFO  [extensions.webscripts.TemplateProcessorRegistry] [localhost-startStop-1] Registered template processor freemarker for extension ftl

share_1     |  2018-05-23 07:15:56,741  INFO  [extensions.webscripts.ScriptProcessorRegistry] [localhost-startStop-1] Registered script processor javascript for extension js

share_1     |  2018-05-23 07:15:56,753  INFO  [extensions.webscripts.TemplateProcessorRegistry] [localhost-startStop-1] Registered template processor freemarker for extension ftl

share_1     |  2018-05-23 07:15:56,755  INFO  [extensions.webscripts.ScriptProcessorRegistry] [localhost-startStop-1] Registered script processor javascript for extension js

alfresco_1  | 23-May-2018 07:15:57.311 INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.

alfresco_1  | May 23, 2018 7:15:57 AM org.apache.catalina.core.ApplicationContext log

alfresco_1  | INFO: No Spring WebApplicationInitializer types detected on classpath

alfresco_1  | May 23, 2018 7:15:57 AM org.apache.catalina.core.ApplicationContext log

alfresco_1  | INFO: Initializing Spring root WebApplicationContext

share_1     |  2018-05-23 07:16:01,063  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 393 Web Scripts (+0 failed), 411 URLs

share_1     |  2018-05-23 07:16:01,063  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 8 Package Description Documents (+0 failed)

share_1     |  2018-05-23 07:16:01,064  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 0 Schema Description Documents (+0 failed)

share_1     |  2018-05-23 07:16:01,148  INFO  [extensions.webscripts.AbstractRuntimeContainer] [localhost-startStop-1] Initialised Surf Container Web Script Container (in 4380.056ms)

share_1     |  2018-05-23 07:16:01,178  INFO  [extensions.webscripts.TemplateProcessorRegistry] [localhost-startStop-1] Registered template processor freemarker for extension ftl

share_1     |  2018-05-23 07:16:01,185  INFO  [extensions.webscripts.ScriptProcessorRegistry] [localhost-startStop-1] Registered script processor javascript for extension js

share_1     |  May 23, 2018 7:16:02 AM org.apache.catalina.core.ApplicationContext log

share_1     | INFO: org.tuckey.web.filters.urlrewrite.UrlRewriteFilter INFO: loaded (conf ok)

share_1     | May 23, 2018 7:16:02 AM org.apache.catalina.core.ApplicationContext log

share_1     | INFO: Initializing Spring FrameworkServlet 'Spring Surf Dispatcher Servlet'

share_1     | 23-May-2018 07:16:02.147 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/share] has finished in [24,826] ms

share_1     | 23-May-2018 07:16:02.161 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]

share_1     | 23-May-2018 07:16:02.178 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]

share_1     | 23-May-2018 07:16:02.189 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 27277 ms

solr6_1     | 2018-05-23 07:16:02.717 WARN  (Thread-12) [   x:alfresco] o.a.s.h.c.AlfrescoSolrClusteringComponent No default engine for document clustering.

solr6_1     | 2018-05-23 07:16:03.890 WARN  (Thread-12) [   x:archive] o.a.s.h.c.AlfrescoSolrClusteringComponent No default engine for document clustering.

alfresco_1  | 2018-05-23 07:16:10,967  INFO  [domain.schema.SchemaBootstrap] [localhost-startStop-1] Ignoring script patch (post-Hibernate): patch.db-V4.2-metadata-query-indexes

alfresco_1  |  2018-05-23 07:16:10,969  INFO  [domain.schema.SchemaBootstrap] [localhost-startStop-1] Ignoring script patch (post-Hibernate): patch.db-V5.1-metadata-query-indexes

alfresco_1  |  2018-05-23 07:16:10,969  INFO  [domain.schema.SchemaBootstrap] [localhost-startStop-1] Ignoring script patch (post-Hibernate): patch.db-V5.2-remove-jbpm-tables-from-db

alfresco_1  |  2018-05-23 07:16:11,335  INFO  [alfresco.repo.admin] [localhost-startStop-1] Using database URL 'jdbc:postgresql://postgres:5432/alfresco' with user 'alfresco'.

alfresco_1  |  2018-05-23 07:16:11,336  INFO  [alfresco.repo.admin] [localhost-startStop-1] Connected to database PostgreSQL version 10.1

alfresco_1  |  2018-05-23 07:16:18,048  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'Authentication' subsystem, ID: [Authentication, managed, alfrescoNtlm1]

alfresco_1  |  2018-05-23 07:16:18,198  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'Authentication' subsystem, ID: [Authentication, managed, alfrescoNtlm1] complete

alfresco_1  |  2018-05-23 07:16:21,173  INFO  [extensions.webscripts.TemplateProcessorRegistry] [localhost-startStop-1] Registered template processor Repository Template Processor for extension ftl

alfresco_1  |  2018-05-23 07:16:21,179  INFO  [extensions.webscripts.ScriptProcessorRegistry] [localhost-startStop-1] Registered script processor Repository Script Processor for extension js

alfresco_1  |  2018-05-23 07:16:24,280  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'ContentStore' subsystem, ID: [ContentStore, managed, unencrypted]

alfresco_1  |  2018-05-23 07:16:24,315  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'ContentStore' subsystem, ID: [ContentStore, managed, unencrypted] complete

alfresco_1  |  2018-05-23 07:16:24,369  INFO  [domain.schema.SchemaBootstrap] [localhost-startStop-1] Connecting to database: jdbc:postgresql://postgres:5432/alfresco, UserName=alfresco, PostgreSQL JDBC Driver

alfresco_1  |  2018-05-23 07:16:24,370  INFO  [domain.schema.SchemaBootstrap] [localhost-startStop-1] Schema managed by database dialect org.alfresco.repo.domain.dialect.PostgreSQLDialect.

alfresco_1  |  2018-05-23 07:16:24,507  WARN  [domain.schema.SchemaBootstrap] [localhost-startStop-1] Schema validation found 85 potential problems, results written to: /usr/local/tomcat/temp/Alfresco/Alfresco-PostgreSQLDialect-Validation-Pre-Upgrade-alf_-1930649379894062897.txt

 

...

alfresco_1  |  2018-05-23 07:16:33,528  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'Search' subsystem, ID: [Search, managed, solr6]

alfresco_1  |  2018-05-23 07:16:33,902  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'Search' subsystem, ID: [Search, managed, solr6] complete

alfresco_1  |  2018-05-23 07:16:37,234  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'thirdparty' subsystem, ID: [thirdparty, default]

alfresco_1  |  2018-05-23 07:16:37,322  INFO  [transform.pdfrenderer.AlfrescoPdfRendererContentTransformerWorker] [localhost-startStop-1] Using Alfresco PDF Renderer: Alfresco PDF Renderer Version 1.1 [5b0e0b81dt] 2018-02-20 15:34:00 using Pdfium [e53460ff] 2018-02-19 18:34:00 CEST

alfresco_1  |  2018-05-23 07:16:37,410  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'thirdparty' subsystem, ID: [thirdparty, default] complete

alfresco_1  |  2018-05-23 07:16:37,410  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'OOoJodconverter' subsystem, ID: [OOoJodconverter, default]

alfresco_1  |  May 23, 2018 7:16:37 AM org.artofsolving.jodconverter.office.ProcessPoolOfficeManager <init>

alfresco_1  | INFO: ProcessManager implementation is LinuxProcessManager

alfresco_1  | May 23, 2018 7:16:37 AM org.artofsolving.jodconverter.office.OfficeProcess start

alfresco_1  | INFO: Using original OpenOffice command: [/opt/libreoffice5.4/program/soffice.bin, -accept=socket,host=127.0.0.1,port=8100;urp;, -env:UserInstallation=file:///usr/local/tomcat/temp/.jodconverter_socket_host-127.0.0.1_port-8100, -headless, -nocrashreport, -nodefault, -nofirststartwizard, -nolockcheck, -nologo, -norestore]

alfresco_1  | May 23, 2018 7:16:37 AM org.artofsolving.jodconverter.office.OfficeProcess start

alfresco_1  | INFO: starting process with acceptString 'socket,host=127.0.0.1,port=8100,tcpNoDelay=1' and profileDir '/usr/local/tomcat/temp/.jodconverter_socket_host-127.0.0.1_port-8100'

alfresco_1  | May 23, 2018 7:16:37 AM org.artofsolving.jodconverter.office.OfficeProcess start

alfresco_1  | INFO: started process; pid = 81

alfresco_1  | May 23, 2018 7:16:39 AM org.artofsolving.jodconverter.office.ManagedOfficeProcess$6 attempt

alfresco_1  | WARNING: office process died with exit code 81; restarting it

alfresco_1  | May 23, 2018 7:16:39 AM org.artofsolving.jodconverter.office.OfficeProcess start

alfresco_1  | INFO: Using original OpenOffice command: [/opt/libreoffice5.4/program/soffice.bin, -accept=socket,host=127.0.0.1,port=8100;urp;, -env:UserInstallation=file:///usr/local/tomcat/temp/.jodconverter_socket_host-127.0.0.1_port-8100, -headless, -nocrashreport, -nodefault, -nofirststartwizard, -nolockcheck, -nologo, -norestore]

alfresco_1  | May 23, 2018 7:16:39 AM org.artofsolving.jodconverter.office.OfficeProcess start

alfresco_1  | INFO: starting process with acceptString 'socket,host=127.0.0.1,port=8100,tcpNoDelay=1' and profileDir '/usr/local/tomcat/temp/.jodconverter_socket_host-127.0.0.1_port-8100'

alfresco_1  | May 23, 2018 7:16:39 AM org.artofsolving.jodconverter.office.OfficeProcess start

alfresco_1  | INFO: started process; pid = 92

alfresco_1  | May 23, 2018 7:16:39 AM org.artofsolving.jodconverter.office.OfficeConnection connect

alfresco_1  | INFO: connected: 'socket,host=127.0.0.1,port=8100,tcpNoDelay=1'

alfresco_1  | 2018-05-23 07:16:40,021  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'OOoJodconverter' subsystem, ID: [OOoJodconverter, default] complete

alfresco_1  |  2018-05-23 07:16:40,025  WARN  [repo.admin.ConfigurationChecker] [localhost-startStop-1] The 'dir.root' property is set to a relative path './alf_data'.  'dir.root' should be overridden to point to a specific folder.

alfresco_1  |  2018-05-23 07:16:40,026  INFO  [repo.admin.ConfigurationChecker] [localhost-startStop-1] The root data directory ('dir.root') is: ./alf_data

alfresco_1  |  2018-05-23 07:16:40,042  INFO  [admin.patch.PatchExecuter] [localhost-startStop-1] Checking for patches to apply ...

alfresco_1  |  2018-05-23 07:16:40,172  WARN  [admin.patch.PatchExecuter] [localhost-startStop-1] Patch description is not available: Patch[ id=patch.contentFormFolderType, description=patch.contentFormFolderType.description, fixesFromSchema=0, fixesToSchema=36, targetSchema=37, ignored=false]

alfresco_1  |  2018-05-23 07:16:40,199  WARN  [admin.patch.PatchExecuter] [localhost-startStop-1] Patch description is not available: Patch[ id=patch.redeploySubmitProcess, description=patch.redeploySubmitProcess.description, fixesFromSchema=0, fixesToSchema=57, targetSchema=58, ignored=false]

alfresco_1  |  2018-05-23 07:16:40,722  INFO  [admin.patch.PatchExecuter] [localhost-startStop-1] Applying patch 'patch.exampleJavaScript' (Loads sample Javascript file into datadictionary scripts folder).

alfresco_1  |  2018-05-23 07:16:40,764  INFO  [admin.patch.PatchExecuter] [localhost-startStop-1] Applying patch 'patch.siteLoadPatch.swsdp' (Loads a sample site into the repository.).

alfresco_1  |  2018-05-23 07:16:40,840  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'sysAdmin' subsystem, ID: [sysAdmin, default]

alfresco_1  |  2018-05-23 07:16:40,865  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'sysAdmin' subsystem, ID: [sysAdmin, default] complete

 

...

alfresco_1  |  2018-05-23 07:16:44,159  INFO  [repo.module.ModuleServiceImpl] [localhost-startStop-1] Found 4 module package(s).

alfresco_1  |  2018-05-23 07:16:44,178  INFO  [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'alfresco-aos-module' version 1.2.0-RC2.

alfresco_1  |  2018-05-23 07:16:44,197  INFO  [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'org.alfresco.integrations.google.docs' version 3.1.0-RC1.

alfresco_1  |  2018-05-23 07:16:44,221  INFO  [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'alfresco-share-services' version 6.0.0.

alfresco_1  |  2018-05-23 07:16:44,243  INFO  [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'alfresco-trashcan-cleaner' version 2.3.

alfresco_1  |  2018-05-23 07:16:44,264  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'fileServers' subsystem, ID: [fileServers, default]

alfresco_1  |  2018-05-23 07:16:44,759  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'fileServers' subsystem, ID: [fileServers, default] complete

alfresco_1  |  2018-05-23 07:16:44,760  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'imap' subsystem, ID: [imap, default]

alfresco_1  |  2018-05-23 07:16:44,898  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'imap' subsystem, ID: [imap, default] complete

alfresco_1  |  2018-05-23 07:16:44,898  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'email' subsystem, ID: [email, outbound]

alfresco_1  |  2018-05-23 07:16:45,075  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'email' subsystem, ID: [email, outbound] complete

alfresco_1  |  2018-05-23 07:16:45,075  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'email' subsystem, ID: [email, inbound]

alfresco_1  |  2018-05-23 07:16:45,135  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'email' subsystem, ID: [email, inbound] complete

alfresco_1  |  2018-05-23 07:16:45,135  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'Subscriptions' subsystem, ID: [Subscriptions, default]

alfresco_1  |  2018-05-23 07:16:45,159  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'Subscriptions' subsystem, ID: [Subscriptions, default] complete

alfresco_1  |  2018-05-23 07:16:45,189  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'Synchronization' subsystem, ID: [Synchronization, default]

alfresco_1  |  2018-05-23 07:16:45,336  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'Synchronization' subsystem, ID: [Synchronization, default] complete

alfresco_1  |  2018-05-23 07:16:45,354  INFO  [service.descriptor.DescriptorService] [localhost-startStop-1] Alfresco JVM - v1.8.0_161-b12; maximum heap size 878.500MB

alfresco_1  |  2018-05-23 07:16:45,355  INFO  [service.descriptor.DescriptorService] [localhost-startStop-1] Server Mode :UNKNOWN

alfresco_1  |  2018-05-23 07:16:45,359  INFO  [service.descriptor.DescriptorService] [localhost-startStop-1] Alfresco Content Services started (Community Early Access). Current version: 6.0.5 (r1c848a2d-b73) schema 10,201. Originally installed version: 6.0.5 (r1c848a2d-b73) schema 10,201.

alfresco_1  |  2018-05-23 07:16:45,374  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'ActivitiesFeed' subsystem, ID: [ActivitiesFeed, default]

alfresco_1  |  2018-05-23 07:16:45,733  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'ActivitiesFeed' subsystem, ID: [ActivitiesFeed, default] complete

alfresco_1  |  2018-05-23 07:16:45,734  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'Replication' subsystem, ID: [Replication, default]

alfresco_1  |  2018-05-23 07:16:45,779  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'Replication' subsystem, ID: [Replication, default] complete

alfresco_1  |  2018-05-23 07:16:46,914  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Starting 'googledocs' subsystem, ID: [googledocs, drive]

alfresco_1  |  2018-05-23 07:16:47,053  INFO  [management.subsystems.ChildApplicationContextFactory] [localhost-startStop-1] Startup of 'googledocs' subsystem, ID: [googledocs, drive] complete

alfresco_1  |  2018-05-23 07:16:50,438  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 396 Web Scripts (+0 failed), 543 URLs

alfresco_1  |  2018-05-23 07:16:50,445  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 1 Package Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:50,445  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 0 Schema Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,235  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 396 Web Scripts (+0 failed), 543 URLs

alfresco_1  |  2018-05-23 07:16:51,235  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 1 Package Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,236  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 0 Schema Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,240  INFO  [extensions.webscripts.AbstractRuntimeContainer] [localhost-startStop-1] Initialised Repository Web Script Container (in 3933.765ms)

alfresco_1  |  2018-05-23 07:16:51,284  INFO  [extensions.webscripts.TemplateProcessorRegistry] [localhost-startStop-1] Registered template processor freemarker for extension ftl

alfresco_1  |  2018-05-23 07:16:51,296  INFO  [extensions.webscripts.ScriptProcessorRegistry] [localhost-startStop-1] Registered script processor javascript for extension js

alfresco_1  |  2018-05-23 07:16:51,833  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 396 Web Scripts (+0 failed), 543 URLs

alfresco_1  |  2018-05-23 07:16:51,833  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 1 Package Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,834  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 0 Schema Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,914  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 14 Web Scripts (+0 failed), 103 URLs

alfresco_1  |  2018-05-23 07:16:51,914  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 0 Package Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,915  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 0 Schema Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,967  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 14 Web Scripts (+0 failed), 103 URLs

alfresco_1  |  2018-05-23 07:16:51,967  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 0 Package Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,967  INFO  [extensions.webscripts.DeclarativeRegistry] [localhost-startStop-1] Registered 0 Schema Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,969  INFO  [extensions.webscripts.AbstractRuntimeContainer] [localhost-startStop-1] Initialised Public Api Web Script Container (in 631.7979ms)

alfresco_1  |  2018-05-23 07:16:51,993  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 14 Web Scripts (+0 failed), 103 URLs

alfresco_1  |  2018-05-23 07:16:51,993  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 0 Package Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:51,993  INFO  [extensions.webscripts.DeclarativeRegistry] [asynchronouslyRefreshedCacheThreadPool1] Registered 0 Schema Description Documents (+0 failed)

alfresco_1  |  2018-05-23 07:16:52,105  WARN  [scripts.servlet.X509ServletFilterBase] [localhost-startStop-1] clientAuth does not appear to be set for Tomcat. clientAuth must be set to 'want' for X509 Authentication

alfresco_1  |  2018-05-23 07:16:52,105  WARN  [scripts.servlet.X509ServletFilterBase] [localhost-startStop-1] Attempting to set clientAuth=want through JMX...

alfresco_1  |  2018-05-23 07:16:52,117  WARN  [scripts.servlet.X509ServletFilterBase] [localhost-startStop-1] Unable to set clientAuth=want through JMX.

alfresco_1  |  23-May-2018 07:16:56.806 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/alfresco] has finished in [72,893] ms

alfresco_1  | 23-May-2018 07:16:56.815 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]

alfresco_1  | 23-May-2018 07:16:56.831 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]

alfresco_1  | 23-May-2018 07:16:56.841 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 79493 ms

share_1     | 2018-05-23 07:17:05,651  INFO  [web.site.EditionInterceptor] [http-nio-8080-exec-3] Successfully retrieved license information from Alfresco.

alfresco_1  | 2018-05-23 07:17:20,434  INFO  [management.subsystems.ChildApplicationContextFactory] [http-nio-8080-exec-1] Starting 'Transformers' subsystem, ID: [Transformers, default]

alfresco_1  |  2018-05-23 07:17:20,845  INFO  [management.subsystems.ChildApplicationContextFactory] [http-nio-8080-exec-1] Startup of 'Transformers' subsystem, ID: [Transformers, default] complete

share_1     |  2018-05-23 07:17:29,731  INFO  [web.scripts.ImapServerStatus] [http-nio-8080-exec-10] Successfully retrieved IMAP server status from Alfresco: disabled

As we can see, the logs from each container are available as an aggregated console log so we can follow exactly what is happening. Note the AMPs that are applied by default: Alfresco AOS Service, Google Docs Integration, Alfresco Share Services, and the Trashcan Cleaner.

Accessing the Alfresco Share web application

We can now access the Web UI at http://localhost:8080/share. The login credentials are: admin/admin.

Inspecting the Docker Compose file

We have seen how easy it is to deploy and run the ACS system with Docker Compose, next we will look at the Compose YAML file that made it happen. It’s located in the acs-community-deployment/docker-compose directory and looks like the following:

 

version: "3"

services:
alfresco:
image: alfresco/alfresco-content-repository-community:6.0.5-ea
environment:
JAVA_OPTS : "
-Ddb.driver=org.postgresql.Driver
-Ddb.username=alfresco
-Ddb.password=alfresco
-Ddb.url=jdbc:postgresql://postgres:5432/alfresco
-Dsolr.host=solr6
-Dsolr.port=8983
-Dsolr.secureComms=none
-Dsolr.base.url=/solr
-Dindex.subsystem.name=solr6
-Ddeployment.method=DOCKER_COMPOSE
"
ports:
- 8082:8080 #Browser port

share:
image: alfresco/alfresco-share:6.0.a
environment:
- REPO_HOST=alfresco
- REPO_PORT=8080
ports:
- 8080:8080

postgres:
image: postgres:10.1
environment:
- POSTGRES_PASSWORD=alfresco
- POSTGRES_USER=alfresco
- POSTGRES_DB=alfresco
ports:
- 5432:5432

solr6:
image: alfresco/alfresco-search-services:1.1.1
environment:
#Solr needs to know how to register itself with Alfresco
- SOLR_ALFRESCO_HOST=alfresco
- SOLR_ALFRESCO_PORT=8080
#Alfresco needs to know how to call solr
- SOLR_SOLR_HOST=solr6
- SOLR_SOLR_PORT=8983
#Create the default alfresco and archive cores
- SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
ports:
- 8083:8983 #Browser port

Image configuration

The image property tells Docker Compose what Docker Image to fetch, what version, and from where. If it just specifies the image name and version, as in the above specification, then the images are assumed to reside in https://hub.docker.com. If the image property value looks something like quay.io/alfresco/alfresco-content-services:latest, then it is most likely an Enterprise Edition image and you will need to login to get that.

 

At the end of the image property value is the version specification. You can update the version to fit your requirements. Browse Docker Hub for available versions. It is quite easy to list available versions for Alfresco images, or tags as Docker Hub calls them, with a URL like https://hub.docker.com/r/<user>/<image name>/tags/. To list the available Alfresco Search Services image versions/tags use https://hub.docker.com/r/alfresco/alfresco-search-services/tags/:

 

Environment configuration

The environment property is used to configure the container. For example, it can be used to configure the Repository container with the location of the database and where the Solr server is running. It can also be used to tell the Share container about the location of the Repository server. The Solr and Database containers are also configured using this property.

 

We can look at the environment property configuration and see what properties we can use when starting the containers manually, which is what we will be doing in the next section.

Networking

By default Docker Compose sets up a single network for our ACS solution. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name. For example, the Repo container knows about the Database and Solr containers via the following configuration:

 

-Ddb.url=jdbc:postgresql://postgres:5432/alfresco
-Dsolr.host=solr6

 

Where postgres and solr6 are the container names for those services.

Listing Docker images and containers

When you are using Docker for deployment it’s good to know how to list the local images and containers that you are working with.

 

To list images that have been downloaded to your computer:

 

$ docker image ls

REPOSITORY                                       TAG                 IMAGE ID            CREATED             SIZE

alfresco/alfresco-content-repository-community   6.0.5-ea            cacbb9510bfe        4 weeks ago         1.72GB

 

alfresco/alfresco-search-services                1.1.1               d6e6a058b986        6 weeks ago         890MB

alfresco/alfresco-share                          6.0.a               9aaa0425fc95        8 weeks ago         709MB

alfresco/alfresco-search-services                1.1.0               56575d75dd82        3 months ago        884MB

postgres                                         10.1                ec61d13c8566        5 months ago        287MB

Here we can see the Alfresco images that were downloaded from Docker Hub when we kicked off the ACS solution with Docker Compose. 

To list running and stopped containers (if you leave out -a, then you will see only running containers):

mbergljung$ docker container ls -a

CONTAINER ID        IMAGE                                                     COMMAND                  CREATED             STATUS                      PORTS                    NAMES

18d33e6734ac        alfresco/alfresco-share:6.0.a                             "/usr/local/tomcat/s…"   21 minutes ago      Up About a minute           0.0.0.0:8080->8080/tcp   dockercompose_share_1

04e553c18cc6        postgres:10.1                                             "docker-entrypoint.s…"   21 minutes ago      Up About a minute           0.0.0.0:5432->5432/tcp   dockercompose_postgres_1

c7f1baae3b55        alfresco/alfresco-search-services:1.1.1                   "/opt/alfresco-searc…"   21 minutes ago      Up About a minute           0.0.0.0:8083->8983/tcp   dockercompose_solr6_1

556e87db8438        alfresco/alfresco-content-repository-community:6.0.5-ea   "catalina.sh run"        21 minutes ago      Up About a minute           0.0.0.0:8082->8080/tcp   dockercompose_alfresco_1

 

d0b6270afeeb        alfresco/alfresco-search-services:1.1.0                   "/opt/alfresco-searc…"   5 weeks ago         Exited (255) 4 weeks ago    0.0.0.0:8983->8983/tcp   alf-search

64d5c9ac4005        postgres:10.1                                             "docker-entrypoint.s…"   5 weeks ago         Exited (255) 4 weeks ago    0.0.0.0:5432->5432/tcp   alf-postgres

062598c1feab        zeppelin:1.0.0-EA                                         "/usr/bin/tini -- bi…"   2 months ago        Exited (255) 2 months ago   0.0.0.0:80->9090/tcp     zeppelin

4eb93b7a4101        alfresco/process-services:1.7.0                           "/root/entrypoint.sh"    4 months ago        Exited (137) 4 months ago                            aps170

3721d2d8bf0f        sonatype/nexus3                                           "sh -c ${SONATYPE_DI…"   4 months ago        Exited (255) 4 months ago   0.0.0.0:8081->8081/tcp   nexus

 

Note how all containers started by Docker Compose will be named as dockercompose_<docker compose file service name>_<instance number>.

Stopping the ACS solution

You can stop all the containers by pressing Ctrl+C at the console (or from another shell you can do docker-compose down). 

 

Here is how it looks like when doing Ctrl-C:

 

...

alfresco_1  | 05-Apr-2018 07:29:21.043 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]

alfresco_1  | 05-Apr-2018 07:29:21.054 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]

alfresco_1  | 05-Apr-2018 07:29:21.056 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 51634 ms

alfresco_1  | 2018-04-05 07:29:21,209  INFO [management.subsystems.ChildApplicationContextFactory] [http-nio-8080-exec-1] Starting 'Search' subsystem, ID: [Search, managed, solr6]

alfresco_1  | 2018-04-05 07:29:21,573  INFO [management.subsystems.ChildApplicationContextFactory] [http-nio-8080-exec-1] Startup of 'Search' subsystem, ID: [Search, managed, solr6] complete

share_1     | 2018-04-05 07:29:36,290  INFO [web.site.EditionInterceptor] [http-nio-8080-exec-3] Successfully retrieved license information from Alfresco.

share_1     | 2018-04-05 07:29:54,625  INFO [web.scripts.ImapServerStatus] [http-nio-8080-exec-9] Successfully retrieved IMAP server status from Alfresco: disabled

share_1     | 2018-04-05 07:30:11,807  INFO [web.scripts.DictionaryQuery] [http-nio-8080-exec-1] Successfully retrieved Data Dictionary from Alfresco.

 

^CGracefully stopping... (press Ctrl+C again to force)

Stopping dockercompose_alfresco_1 ... done

Stopping dockercompose_postgres_1 ... done

Stopping dockercompose_solr6_1    ... done

Stopping dockercompose_share_1    ... done

There is a big difference between doing Ctrl-C and doing docker-compose down. The latter one also removes the containers and any content created:

$ docker-compose down

Stopping dockercompose_share_1    ... done

Stopping dockercompose_postgres_1 ... done

Stopping dockercompose_solr6_1    ... done

Stopping dockercompose_alfresco_1 ... done

Removing dockercompose_share_1    ... done

Removing dockercompose_postgres_1 ... done

Removing dockercompose_solr6_1    ... done

Removing dockercompose_alfresco_1 ... done

To check there are no containers running:

$ docker container ls

CONTAINER ID        IMAGE COMMAND             CREATED STATUS PORTS               NAMES

To list the stopped containers (you will only see these if you did Ctrl-C to stop):

$ docker container ls -a

CONTAINER ID        IMAGE                                      COMMAND CREATED STATUS                PORTS NAMES

e5a1c8a74a75        alfresco/alfresco-content-repository-community:6.0.5-ea   "catalina.sh run" 41 hours ago Exited (143) 4 minutes ago                            dockercompose_alfresco_1

ae1e982c13d5        postgres:10.1                                      "docker-entrypoint.s…" 41 hours ago Exited (0) 4 minutes ago                              dockercompose_postgres_1

b67a5c11215f        alfresco/alfresco-search-services:1.1.0                   "/opt/alfresco-searc…" 41 hours ago Exited (143) 4 minutes ago                            dockercompose_solr6_1

1c372a4cac98        alfresco/alfresco-share:6.0.a                             "/usr/local/tomcat/s…" 41 hours ago Exited (137) 4 minutes ago                            dockercompose_share_1

Removing/Uninstalling the ACS solution

When we are finished with the demo, test, PoC, or whatever we were doing, then we can remove the ACS solution from the computer in an easy way with the following Docker Compose command (this is not necessary if you did docker-compose down):

 

docker-compose mbergljung$ docker-compose rm

Going to remove dockercompose_alfresco_1, dockercompose_postgres_1, dockercompose_solr6_1, dockercompose_share_1

Are you sure? [yN] y

Removing dockercompose_alfresco_1 ... done

Removing dockercompose_postgres_1 ... done

Removing dockercompose_solr6_1    ... done

Removing dockercompose_share_1    ... done

List the running and stopped containers to make sure they are gone:

$ docker container ls -a

CONTAINER ID        IMAGE              COMMAND CREATED           STATUS PORTS        NAMES

Deploying the ACS system Container by Container

Docker Compose is a convenient way of getting an ACS system up and running quickly for testing and PoC purposes. It does however hide all the details about starting and stopping the Docker container. For our purposes it is useful to be able to configure and deploy each container individually because it allows us to get a bit more detail about how Docker works.

 

We are going to deploy and run the same thing we did via the Docker Compose file. But now we are going to start and configure each container manually.

Create a network for the containers

Before we can start any containers we need to create a network for them to communicate over. We need to do this because you can’t use localhost inside a container to connect to another container. We can then connect to this new network when we create a new container.

 

Create a new network called alf-net as follows:

 

$ docker network create alf-net

3393bff64289dffae0e36fde8c7b32c51160b565afd376598c9d191d91d42b32

The response is the long ID for the new network. But we will refer to it as alf-net.

Deploy and Run the Database container

The Alfresco Repo is going to connect to a PostgreSQL database called ‘alfresco’ where the Repository can store the metadata for the content files. We can easily fire up a PostgreSQL database with images available at https://hub.docker.com/_/postgres/.

 

We know from the Docker Compose file what environment variables we can use to configure the database image. Deploy it as follows and give the new container the name alf-postgres (if you already have a container with this name then pick another name, or you can remove the container with the following command if you don’t need to keep it: $ docker container rm alf-postgres):

 

$ docker run --network alf-net --name alf-postgres -p 5432:5432 -e POSTGRES_USER=alfresco -e POSTGRES_PASSWORD=alfresco -e POSTGRES_DB=alfresco -d postgres:10.1  

0f5394598a21c095784646664244d2edb4a13dcda1c4aecfaf7a62e836f6d4c0

 

The --networkoption must be specified directly after run. It cannot, for example, be at the end of the command.

 

Here we start a PostgreSQL container with user/pwd alfresco/alfresco and tell it to create the default database with the name alfresco, which is what the repository needs. The database server is available externally on port 5432. We also connect the container to the alf-net network we created earlier on. The command returns the new container’s ID.

 

Test that it all worked by logging into the container and accessing the database (note that we use the short ID for the container):

 

$ docker container ls

CONTAINER ID        IMAGE COMMAND                  CREATED STATUS PORTS                    NAMES

0f5394598a21        postgres:10.1 "docker-entrypoint.s…"   About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp   alf-postgres

 

$ docker container exec -it 0f5394598a21 /bin/bash

root@0f5394598a21:/# psql alfresco alfresco

psql (10.1)

Type "help" for help.

 

alfresco=# \q

root@0f5394598a21:/# exit

exit

Check that the Database container is connected to the network

At this point it might be a good idea to check that the PostgreSQL database container is actually connected to the custom network alf-net that we created.

 

To check the network use the following command:

 

$ docker network inspect alf-net

[

   {

       "Name": "alf-net",

       "Id": "3393bff64289dffae0e36fde8c7b32c51160b565afd376598c9d191d91d42b32",

       "Created": "2018-04-04T14:00:57.557180066Z",

       "Scope": "local",

       "Driver": "bridge",

       "EnableIPv6": false,

       "IPAM": {

           "Driver": "default",

           "Options": {},

           "Config": [

               {

                   "Subnet": "172.21.0.0/16",

                   "Gateway": "172.21.0.1"

               }

           ]

       },

       "Internal": false,

       "Attachable": false,

       "Ingress": false,

       "ConfigFrom": {

           "Network": ""

       },

       "ConfigOnly": false,

       "Containers": {

           "5661dc60a832e7c620842f88d8107d55546fc9a76e63005b73b8c799db562384": {

               "Name": "alf-postgres",

               "EndpointID": "24a246b1007d7f704dab4cf6ab343b9755e5cfda114692b4176e526a756e04d4",

               "MacAddress": "02:42:ac:15:00:02",

               "IPv4Address": "172.21.0.2/16",

               "IPv6Address": ""

           }

       },

       "Options": {},

       "Labels": {}

   }

]

As we can see, the database container is available on the network on IP 172.21.0.2. We will be able to access the database container under a hostname that is the same as the container name alf-postgres.

Deploy and Run the Alfresco Search Services container

The Alfresco Repo is going to use the Search Services with Apache Solr 6.0 for all search related features. The alfresco/alfresco-search-services image is available for us on Docker Hub. Kick it off as follows and give the new container the name alf-search:

 

$ docker run --network alf-net --name alf-search -p 8983:8983 -e SOLR_ALFRESCO_HOST=alf-repo -e SOLR_ALFRESCO_PORT=8080 -e SOLR_SOLR_HOST=alf-search -e SOLR_SOLR_PORT=8983 -e SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive -d alfresco/alfresco-search-services:1.1.1 

2cc7fda1f64385ee028ad486210544ed708900099431574b6e11fba3358cd6e6

 

There are a number of environment variables we need to pass to the container. The first two tells Apache Solr where Alfresco Repo is running so it can call back for text content. The next two just tells Solr itself where it is running. And the last variable tells Solr to create two cores (i.e. indexes) for live content (alfresco) and archived content (archive).

 

The container will run on the standard Solr port 8983.

 

Now review the logs:

 

$ docker container logs 2cc7fda1f64385ee028ad486210544ed708900099431574b6e11fba3358cd6e6

2018-04-04 15:10:17.370 INFO  (main) [ ] o.e.j.s.Server jetty-9.3.8.v20160314

2018-04-04 15:10:17.756 INFO  (main) [ ] o.a.s.s.SolrDispatchFilter  ___ _ Welcome to Apache Solr? version 6.3.0

2018-04-04 15:10:17.757 INFO  (main) [ ] o.a.s.s.SolrDispatchFilter / __| ___| |_ _   Starting in standalone mode on port 8983

2018-04-04 15:10:17.757 INFO  (main) [ ] o.a.s.s.SolrDispatchFilter \__ \/ _ \ | '_|  Install dir: /opt/alfresco-search-services/solr

2018-04-04 15:10:17.841 INFO  (main) [ ] o.a.s.s.SolrDispatchFilter |___/\___/_|_|    Start time: 2018-04-04T15:10:17.759Z

2018-04-04 15:10:18.699 INFO  (main) [ ] o.e.j.s.ServerConnector Started ServerConnector@4608325d{HTTP/1.1,[http/1.1]}{0.0.0.0:8983}

2018-04-04 15:10:18.699 INFO  (main) [ ] o.e.j.s.Server Started @2098ms

2018-04-04 15:10:30.672 WARN  (Thread-12) [ x:alfresco] o.a.s.h.c.AlfrescoSolrClusteringComponent No default engine for document clustering.

2018-04-04 15:10:31.065 WARN  (Thread-12) [ x:archive] o.a.s.h.c.AlfrescoSolrClusteringComponent No default engine for document clustering.

2018-04-04 15:10:31.536 ERROR (searcherExecutor-7-thread-1-processing-x:alfresco) [   x:alfresco] o.a.s.t.AbstractTracker Model tracking failed

java.net.UnknownHostException: alf-repo

We will see an error when the Search Services are trying to connect to the Alfresco Repository as it is not yet up an running. We will start them next.

Check the Solr UI on http://localhost:8983:

 

 

In the UI we can check that the two cores have been created by clicking on the Core Selector drop down to the left.

Deploy and Run the Alfresco Repository container

The standard Alfresco Repository image (i.e. alfresco.war) is available in Docker Hub under the name alfresco/alfresco-content-repository-community. We want to use the same version of it as was specified in the Docker Compose environment, which was 6.0.4-ea. Start the container as follows and call it alf-repo:

 

$ docker run --network alf-net --name alf-repo -p 8080:8080 -e JAVA_OPTS='-Ddb.driver=org.postgresql.Driver -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.url=jdbc:postgresql://alf-postgres:5432/alfresco -Dsolr.host=alf-search -Dsolr.port=8983 -Dsolr.secureComms=none -Dsolr.base.url=/solr -Dindex.subsystem.name=solr6' -d alfresco/alfresco-content-repository-community:6.0.5-ea

0c3819df858273f5ed55e973a8ef5dbdeeb78f024a3e500334d1bc843c2f6886

 

We publish the Repo on port 8080 instead of port 8082 as in the Docker Compose file. The environment configuration is pretty much taken from the Docker Compose file. The hostnames have been updated to match the container names.

 

Review the logs as follows by using the container ID:

 

$ docker container logs 0c3819df858273f5ed55e973a8ef5dbdeeb78f024a3e500334d1bc843c2f6886

. . .

08-Mar-2018 13:55:38.508 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/alfresco] has finished in [73,821] ms

08-Mar-2018 13:55:38.515 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]

08-Mar-2018 13:55:38.529 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]

08-Mar-2018 13:55:38.535 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 74678 ms

If you see the logs above it means the server has started up properly.

If you are experiencing problems and want to stop and remove the container to be able to start over you can do this by running the following command:

 

$docker container stop alf-repo

alf-repo

$ docker container rm alf-repo

alf-repo

Accessing the Alfresco Repo from a Browser

You should be able to access the Alfresco Repository from a browser. You can test WebDAV access via http://localhost:8080/alfresco/webdav:

 

 

If you are asked to login, use admin/admin.

Deploy and Run the Alfresco Share container

The Alfresco Share container is the last step required for the ACS solution setup and it provides the user interface. The alfresco/alfresco-share image is available for us on Docker Hub. Deploy it as follows and give the new container the name alf-share:

 

$ docker run --network alf-net --name alf-share -p 8081:8080 -e REPO_HOST=alf-repo -e REPO_PORT=8080 -d alfresco/alfresco-share:6.0.a

d9c24489267608d672ff67a30e28d9de5234568be2ea0afe99d9ba037a36674b

 

The only thing we need to tell Share is where the Repo is running. We run Share on port 8081 so it does not clash with the Repo.

 

Now review the logs:

 

$ docker container logs d9c24489267608d672ff67a30e28d9de5234568be2ea0afe99d9ba037a36674b

INFO: Initializing Spring FrameworkServlet 'Spring Surf Dispatcher Servlet'

05-Apr-2018 05:25:15.182 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/share] has finished in [10,485] ms

05-Apr-2018 05:25:15.188 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]

05-Apr-2018 05:25:15.203 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]

05-Apr-2018 05:25:15.207 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 11365 ms

Access the Share UI on http://localhost:8081/share and login with admin/admin:

 

Test the user interface by uploading some files, and searching etc so you can see that it all works properly.

Starting and Stopping the ACS solution

Now we have all the containers that make up the ACS solution running, and we have some new content added to the Repo, let’s stop the containers.

 

To stop the containers, use the following template: docker container stop <name>:

 

$ docker container stop alf-share

alf-share

$ docker container stop alf-repo

alf-repo

$ docker container stop alf-search

alf-search

$ docker container stop alf-postgres

alf-postgres

I stopped them in the opposite order to how they were started.

We can check that they really are stopped by using the following command:

 

$ docker container ls -a

CONTAINER ID        IMAGE                                                     COMMAND                  CREATED              STATUS                        PORTS                    NAMES

6a1b766a01ed        alfresco/alfresco-share:6.0.a                             "/usr/local/tomcat/s…"   About a minute ago   Exited (137) 24 seconds ago                            alf-share

d2d030b10f3f        alfresco/alfresco-content-repository-community:6.0.5-ea   "catalina.sh run"        3 minutes ago        Exited (143) 17 seconds ago                            alf-repo

f95b421ee73c        alfresco/alfresco-search-services:1.1.1                   "/opt/alfresco-searc…"   4 minutes ago        Exited (143) 11 seconds ago                            alf-search

d355deda2b57        postgres:10.1                                             "docker-entrypoint.s…"   5 minutes ago        Exited (0) 6 seconds ago                               alf-postgres

 

Now, let’s start it all up again and see if the content is still there:

$ docker container start alf-postgres

alf-postgres

$ docker container start alf-search

alf-search

$ docker container start alf-repo

alf-repo

$ docker container start alf-share

alf-share

Login to Share and verify that the content is still there. All the content is there and the search index is intact. Next we will look at how this works.

Where is the data stored?

When working with containers there are a couple of ways that data can be persisted. You can just store it inside the container or you can use something called Docker Volumes.

 

Storing it inside a container is a simple approach for demoing, testing, and PoC situations. However, it’s not ideal for a production environment as all content will be inside the container, which will make it very big. This means that there’s no way of having backup containers if something crashes. Also, it would not work if you wanted to cluster ACS. What you would use in production is Docker Volumes, which enable you to store the content outside the container.

 

To look at the Repository content we have to open a shell into the alf-repo container as follows and step into the alf_data directory (note, the container need to be started for this to work):

 

$ docker container exec -it alf-repo /bin/bash

[root@0c3819df8582 tomcat]# ls -l

total 184

-rw-r----- 1 root root 57092 Feb  6 23:12 LICENSE

-rw-r----- 1 root root  1723 Feb 6 23:12 NOTICE

-rw-r----- 1 root root  7138 Feb 6 23:12 RELEASE-NOTES

-rw-r----- 1 root root 16246 Feb  6 23:12 RUNNING.txt

drwxr-x--- 4 root root  4096 Apr 4 15:21 alf_data

drwxr-xr-x 1 root root  4096 Mar 27 13:28 alfresco-mmt

-rw-r----- 1 root root 22382 Apr  5 05:42 alfresco.log

-rw-r----- 1 root root 23311 Apr  4 15:22 alfresco.log.2018-04-04

drwxr-xr-x 1 root root  4096 Mar 27 13:28 amps

drwxr-x--- 2 root root  4096 Mar 26 11:14 bin

drwx------ 1 root root  4096 Apr 4 15:20 conf

drwxr-xr-x 3 root root  4096 Mar 26 11:14 include

drwxr-x--- 1 root root  4096 Mar 27 13:28 lib

drwxr-x--- 1 root root  4096 Apr 5 05:41 logs

drwxr-xr-x 3 root root  4096 Mar 26 11:14 native-jni-lib

drwxr-xr-x 1 root root  4096 Mar 27 13:28 shared

drwxr-x--- 1 root root  4096 Apr 5 05:42 temp

drwxr-x--- 1 root root  4096 Apr 4 15:20 webapps

drwxr-x--- 1 root root  4096 Apr 4 15:20 work

[root@0c3819df8582 tomcat]# cd alf_data/

[root@0c3819df8582 alf_data]# ls -l

total 8

drwxr-x--- 3 root root 4096 Apr  4 15:21 contentstore

drwxr-x--- 2 root root 4096 Apr  4 15:20 contentstore.deleted

[root@0c3819df8582 alf_data]# cd contentstore

[root@0c3819df8582 contentstore]# cd 2018/4/5/5/33/

[root@0c3819df8582 33]# ls -l

total 8

-rw-r----- 1 root root 3732 Apr  5 05:33 1d41a201-ad12-42f9-9f44-3e70597b5fa4.bin

-rw-r----- 1 root root   61 Apr 5 05:33 b1ba1f0f-db04-49fd-9e11-aa57d2ffc6e6.bin

[root@0c3819df8582 33]# exit

Note that when you do this you will have a different directory structure under contentstore as you will have uploaded content after this article was written.

Removing/Uninstalling the ACS solution

To remove everything from our computer make sure each container is stopped as discussed above. Then use the following template - docker container rm <name>(note, all data will be permanently deleted):

$ docker container rm alf-share

alf-share

$ docker container rm alf-repo

alf-repo

$ docker container rm alf-search

alf-search

$ docker container rm alf-postgres

alf-postgres

I removed them in the opposite order to how they were started.

Summary

Deploying and running an ACS solution by starting each container individually is a bit more work. But we were able to learn much more about how things work in a Docker container, and we got to know how to set up a network for the containers to communicate over.

 

However, when you want to get an ACS environment up a running for testing or a PoC project, it is probably more efficient to use Docker Compose.

Building and Deploying custom ACS Images

So far we have looked at how to run the standard ACS solution without any customizations. I’m sure you have customizations that you want to include in your ACS solution, such as a custom domain specific content model. Next we will look at how you build customizations for ACS 6.0.

 

The source code for this section can be downloaded and cloned from here.

Prerequisites

In order to build the projects discussed in this section you will need to have Java and Maven installed. See the instructions at the beginning of this page.

 

You will also need to update your Maven settings file (located at ~/.m2/settings.xml) with the location of the public Alfresco Nexus Repository:

 

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd"
>

<profiles>
<profile>
<id>alfresco.default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>alfresco-public</id>
<url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>alfresco-public</id>
<name>Alfresco</name>
<url>http://artifacts.alfresco.com/nexus/content/repositories/releases</url>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
</settings>

 

Building Repository extensions for ACS 6.0

At the moment there is no support for ACS 6.0 in the Alfresco SDK but we can still build extensions. We just have to do a bit of “engineering”. Assuming you have downloaded the source code for this section you will find as part of it a maven project called custom-repo-extension, which is laid out as a standard Alfresco Platform JAR extension.

 

This project contains a simple content model definition and the bootstrapping for it. It also contains a repository action so we can check that it works to compile against the Alfresco classes. This article is not primarily about building Alfresco extensions so I will not explain that code here.

 

The POM file for the project is the important part as it tells us how we can build against ACS 6.0, it looks like this:

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.alfresco</groupId>
<artifactId>acs-community-packaging</artifactId>
<version>6.0.5-ea</version>
<relativePath></relativePath>
</parent>

<groupId>org.alfresco.training</groupId>
<artifactId>custom-repo-extension</artifactId>
<version>1.0-SNAPSHOT</version>

<name>Custom repository extension JAR</name>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-repository</artifactId>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

 

The Maven POM file starts off with a definition of a Parent POM. This parent project is part of the acs-community-packaging project that we we cloned in the beginning of this article. If you open it up you will find all kinds of useful property definitions and dependency management declarations, for example:

 

 


<properties>
...
<dependency.alfresco-core.version>7.1</dependency.alfresco-core.version>
<dependency.alfresco-data-model.version>8.3</dependency.alfresco-data-model.version>
<dependency.alfresco-repository.version>6.41</dependency.alfresco-repository.version>
<dependency.alfresco-remote-api.version>6.27</dependency.alfresco-remote-api.version>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<version>${dependency.alfresco-core.version}</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<version>${dependency.alfresco-core.version}</version>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-data-model</artifactId>
<version>${dependency.alfresco-data-model.version}</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-jlan-embed</artifactId>
<version>${dependency.alfresco-jlan.version}</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-remote-api</artifactId>
<version>${dependency.alfresco-remote-api.version}</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-remote-api</artifactId>
<version>${dependency.alfresco-remote-api.version}</version>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-repository</artifactId>
<version>${dependency.alfresco-repository.version}</version>
</dependency>
...

 

This file contains version properties for the different libraries that are part of ACS 6.0.4-ea. So we don’t have to figure this out. It also contains dependencyManagement configurations for the different libraries that we might depend on when building, so we don’t have to specify versions for those in our project.

 

Our project depends on the alfresco-repository library so we can build the custom repository action. We also filter the resource directory so we can use property substitution variables like this: module.id=${project.artifactId} and have them converted to module.id=custom-repo-extension during the build.

 

Now build the extension:

 

custom-repo-extension mbergljung$ mvn clean install

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building Custom repository extension JAR 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-clean-plugin:3.0.0:clean (default-clean) @ custom-repo-extension ---

[INFO] Deleting /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/target

[INFO]

[INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ custom-repo-extension ---

[INFO] Using 'UTF-8' encoding to copy filtered resources.

[INFO] Copying 6 resources

[INFO]

[INFO] --- maven-compiler-plugin:3.6.0:compile (default-compile) @ custom-repo-extension ---

[INFO] Changes detected - recompiling the module!

[INFO] Compiling 1 source file to /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/target/classes

[INFO]

[INFO] --- maven-resources-plugin:3.0.1:testResources (default-testResources) @ custom-repo-extension ---

[INFO] Using 'UTF-8' encoding to copy filtered resources.

[INFO] skip non existing resourceDirectory /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/src/test/resources

[INFO]

[INFO] --- maven-compiler-plugin:3.6.0:testCompile (default-testCompile) @ custom-repo-extension ---

[INFO] No sources to compile

[INFO]

[INFO] --- maven-surefire-plugin:2.19.1:test (default-test) @ custom-repo-extension ---

[INFO] No tests to run.

[INFO]

[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ custom-repo-extension ---

[INFO] Building jar: /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/target/custom-repo-extension-1.0-SNAPSHOT.jar

[INFO]

[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ custom-repo-extension ---

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/target/custom-repo-extension-1.0-SNAPSHOT.jar to /Users/mbergljung/.m2/repository/org/alfresco/training/custom-repo-extension/1.0-SNAPSHOT/custom-repo-extension-1.0-SNAPSHOT.jar

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/pom.xml to /Users/mbergljung/.m2/repository/org/alfresco/training/custom-repo-extension/1.0-SNAPSHOT/custom-repo-extension-1.0-SNAPSHOT.pom

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 3.264 s

[INFO] Finished at: 2018-04-06T06:52:08+01:00

[INFO] Final Memory: 42M/339M

[INFO] ------------------------------------------------------------------------

We now have the platform/repo JAR extension in our local Maven repository, ready to be included in a custom Alfresco Repo Image.

Building a custom Repository Image

To build a custom image based on the standard alfresco/alfresco-content-repository-community image we have to create a Dockerfile. We will use a Maven project to bring together all the extensions (both JARs and AMPs) that we want to include in the custom image.

Maven project to assemble all Repository extensions

This project is part of the source code for this article and is called docker-alfresco-custom. It’s used to bring together all the repository extensions that we want to include in the custom Repository image (this Maven project could potentially be used to build the custom image with a plugin such as fabric8io, but this is not covered in this article):

 

The POM looks like this:

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.alfresco.training</groupId>
<artifactId>docker-alfresco-custom</artifactId>
<version>1.0-SNAPSHOT</version>
<name>JAR and AMP assembly under /target for use by Dockerfile</name>
<packaging>pom</packaging>

<dependencies>
<dependency>
<groupId>org.alfresco.training</groupId>
<artifactId>custom-repo-extension</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.softwareloop</groupId>
<artifactId>uploader-plus-repo</artifactId>
<version>1.6</version>
<type>amp</type>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-repo-extensions</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.alfresco.training</groupId>
<artifactId>custom-repo-extension</artifactId>
<version>1.0-SNAPSHOT</version>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/jars</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>com.softwareloop</groupId>
<artifactId>uploader-plus-repo</artifactId>
<version>1.6</version>
<type>amp</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/amps</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

 

In the dependencies section we define all the extensions that should be part of our custom repository image. In this case we define a dependency to the custom extension that we built in the previous section, and a dependency to an open source extension that customizes the upload functionality in Alfresco, so you can attach metadata while uploading.

 

The maven-dependency-plugin plugin is used to copy the extensions in under the /target directory. We can then pick them up from there when building the custom repository image.

 

Now build the project:

 

docker-alfresco-custom mbergljung$ mvn clean install

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building JAR and AMP assembly under /target for use by Dockerfile 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ docker-alfresco-custom ---

[INFO] Deleting /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom/target

[INFO]

[INFO] --- maven-dependency-plugin:3.0.2:copy (copy-repo-extensions) @ docker-alfresco-custom ---

[INFO] Configured Artifact: org.alfresco.training:custom-repo-extension:1.0-SNAPSHOT:jar

[INFO] Configured Artifact: com.softwareloop:uploader-plus-repo:1.6:amp

[INFO] Copying custom-repo-extension-1.0-SNAPSHOT.jar to /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom/target/jars/custom-repo-extension-1.0-SNAPSHOT.jar

[INFO] Copying uploader-plus-repo-1.6.amp to /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom/target/amps/uploader-plus-repo-1.6.amp

[INFO]

[INFO] --- maven-install-plugin:2.4:install (default-install) @ docker-alfresco-custom ---

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom/pom.xml to /Users/mbergljung/.m2/repository/org/alfresco/training/docker-alfresco-custom/1.0-SNAPSHOT/docker-alfresco-custom-1.0-SNAPSHOT.pom

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 1.271 s

[INFO] Finished at: 2018-04-06T07:45:33+01:00

[INFO] Final Memory: 12M/309M

[INFO] ------------------------------------------------------------------------

What you end up with is a target directory looking like this:

 

docker-alfresco-custom mbergljung$ tree

.

├── Dockerfile

├── pom.xml

└── target

   ├── amps

   │ └── uploader-plus-repo-1.6.amp

   └── jars

       └── custom-repo-extension-1.0-SNAPSHOT.jar

We can now code the Dockerfile to pick up the extensions from this location.

Create the Dockerfile for custom Repository image build

The Dockerfile that we will use to build our custom Repository is located in the same directory as the POM file that assembles the extensions. It looks like the following:

 

FROM alfresco/alfresco-content-repository-community:6.0.5-ea

ARG TOMCAT_DIR=/usr/local/tomcat

RUN mkdir -p $TOMCAT_DIR/amps

COPY target/amps $TOMCAT_DIR/amps
COPY target/jars $TOMCAT_DIR/webapps/alfresco/WEB-INF/lib

RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install \
$TOMCAT_DIR/amps $TOMCAT_DIR/webapps/alfresco -directory -nobackup -force

 

The first thing it does is define that the new image will be based on the standard alfresco/alfresco-content-repository-community image version 6.0.5-ea that is available in Docker Hub. Then it defines a local variable called TOMCAT_DIR, which points to where in the standard image the Apache Tomcat installation is located. We then make sure that the amps directory exists in the image.

 

The next command in the file is to copy AMPs and JARs into the image. JAR extensions are copied directly into the exploded webapp. AMP extensions are copied into the /amps directory from where they will be picked up by the Module Management Tool (MMT).

 

The last step is to use the MMT tool to apply the AMPs to the exploded webapp.

Currently it does not work to put stuff in the {TOMCAT_DIR}/modules/platform directory. JAR extensions are not picked up from this location at the moment.

Build the custom Repository Docker Image

Now the Dockerfile is ready and the AMP and JAR extensions are available, we can build the custom repository image as follows:

 

docker-alfresco-custom mbergljung$docker build . --tag my-acs-repo:6.0

Sending build context to Docker daemon  41.98kB

Step 1/6 : FROM alfresco/alfresco-content-repository-community:6.0.5-ea

---> df0b08d0d3a3

Step 2/6 : ARG TOMCAT_DIR=/usr/local/tomcat

---> Running in b9da89b41cd7

Removing intermediate container b9da89b41cd7

---> c3379ffbd749

Step 3/6 : RUN mkdir -p $TOMCAT_DIR/amps

---> Running in d5081fd4216c

Removing intermediate container d5081fd4216c

---> b64f819c98f6

Step 4/6 : COPY target/amps $TOMCAT_DIR/amps

---> 69e4c78b184c

Step 5/6 : COPY target/jars $TOMCAT_DIR/webapps/alfresco/WEB-INF/lib

---> 493379108de1

Step 6/6 : RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install               $TOMCAT_DIR/amps $TOMCAT_DIR/webapps/alfresco -directory -nobackup -force

---> Running in e5ed4cb90501

Removing intermediate container e5ed4cb90501

---> 3f4a2d48d03a

Successfully built 3f4a2d48d03a

Successfully tagged my-acs-repo:6.0

We call the custom image my-acs-repo and give it a version tag 6.0.

Verify that we have the new image locally:

$docker image ls

REPOSITORY                                       TAG IMAGE ID CREATED           SIZE

my-acs-repo                                      6.0 b282286605cb 2 minutes ago       1.74GB

alfresco/alfresco-content-repository-community   6.0.5-ea df0b08d0d3a3 8 days ago          1.72GB

alfresco/alfresco-share                          6.0.a 9aaa0425fc95 9 days ago          709MB

alfresco/alfresco-search-services                1.1.1 56575d75dd82 2 months ago        884MB

We can see our image called my-acs-repo and we also have the Docker Hub image that it is based on.

Running a container based on the custom Repository image

We now need to get a container running that is based on our new my-acs-repo image.

The new custom repo image will need a database and search engine so let’s create those first using the standard images as before. We assume here that the alf-net network is still available.

 

Starting with a PostgreSQL container (you might have to stop and remove the container first):

 

$ docker run --network alf-net --name alf-postgres -p 5432:5432 -e POSTGRES_USER=alfresco -e POSTGRES_PASSWORD=alfresco -e POSTGRES_DB=alfresco -d postgres:10.1  

 

And the Alfresco Search Services container (you might have to stop and remove the container first):

 

$ docker run --network alf-net --name alf-search -p 8983:8983 -e SOLR_ALFRESCO_HOST=alf-repo -e SOLR_ALFRESCO_PORT=8080 -e SOLR_SOLR_HOST=alf-search -e SOLR_SOLR_PORT=8983 -e SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive -d alfresco/alfresco-search-services:1.1.1

 

Now let’s start the custom Repo container (you might have to stop and remove the container first):

 

$ docker run --network alf-net --name alf-repo -p 8080:8080 -e JAVA_OPTS='-Ddb.driver=org.postgresql.Driver -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.url=jdbc:postgresql://alf-postgres:5432/alfresco -Dsolr.host=alf-search -Dsolr.port=8983 -Dsolr.secureComms=none -Dsolr.base.url=/solr -Dindex.subsystem.name=solr6' -d my-acs-repo:6.0

d52d18c57d366967f17425771bdc87f5931c2d5b5a6670052ac96b5434152c4a

 

Make sure to use the my-acs-repo:6.0 custom image that we just created. In the logs we should see the new AMP and JAR extension applied:

 

$ docker container logs d52d18c57d366967f17425771bdc87f5931c2d5b5a6670052ac96b5434152c4a

2018-04-06 05:19:31,016  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Found 6 module package(s).

2018-04-06 05:19:31,036  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'alfresco-aos-module' version 1.1.7.

2018-04-06 05:19:31,065  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'custom-repo-extension' version 1.0-SNAPSHOT.

2018-04-06 05:19:31,090  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'org.alfresco.integrations.google.docs' version 3.0.4.2.

2018-04-06 05:19:31,102  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'uploader-plus-repo' version 1.6.1801311724.

2018-04-06 05:19:31,121  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'alfresco-share-services' version 6.0.0.

2018-04-06 05:19:31,141  INFO [repo.module.ModuleServiceImpl] [localhost-startStop-1] Installing module 'alfresco-trashcan-cleaner' version 2.3.

...

 

In the log above we can verify that the two extensions (i.e. custom-repo-extension and uploader-plus-repo) we added have been installed successfully.

 

Check that you can access the Repository with http://localhost:8080/alfresco/webdav

Re-Building an Alfresco Repo Image

At some point you have to rebuild a custom image. You might have made a mistake in the first build, or you just want to add more extensions.

 

Start by listing your containers to find out which one is based on the custom image:

 

$ docker container ls

CONTAINER ID        IMAGE                      COMMAND CREATED   STATUS PORTS NAMES

d776612160c3        my-acs-repo:6.0                      "catalina.sh run" 5 minutes ago   Up 5 minutes 0.0.0.0:8080->8080/tcp alf-repo

c6e57ff6ca96        alfresco/alfresco-search-services:1.1.0   "/opt/alfresco-searc…" 17 hours ago   Up 17 hours 0.0.0.0:8983->8983/tcp alf-search

dcf89cd04192        postgres:10.1                      "docker-entrypoint.s…" 17 hours ago   Up 17 hours 0.0.0.0:5432->5432/tcp alf-postgres

Stop and remove the relevant containers:

 

$ docker container stop alf-repo alf-search alf-postgres

alf-repo

alf-search

alf-postgres

$ docker container rm alf-repo alf-search alf-postgres

alf-repo

alf-search

alf-postgres

Here we also remove the database and search containers as they are not in sync when restarting a container based on a new image. Any new content that was previously created will be gone when a new container is created based on a rebuilt image. The search service would still have an index for previous content and the database would still have metadata for previous new content. When developing solutions for ACS 6.0 it is a good idea to work with Docker Volumes as you are likely to have to rebuild the repository image a lot.

List all the images:

 

$ docker image ls

REPOSITORY                                       TAG IMAGE ID CREATED           SIZE

my-acs-repo                                      6.0 c133631019ac 7 minutes ago       1.74GB

alfresco/alfresco-content-repository-community   6.0.4-ea df0b08d0d3a3 9 days ago          1.72GB

alfresco/alfresco-share                          6.0.a 9aaa0425fc95 9 days ago          709MB

alfresco/alfresco-search-services                1.1.0 56575d75dd82 2 months ago        884MB

And remove the image that you plan to update:

 

$ docker image rm my-acs-repo:6.0

After this you will have to build the custom image again and restart the database, search, and repo containers.

Building Share extensions for ACS 6.0

At the moment there is no support for ACS 6.0 in the Alfresco SDK but we can still build extensions. We just have to do a bit of “engineering”. Assuming you have downloaded the source code for this section you will find as part of it a maven project called custom-share-extension, which is laid out as a standard Alfresco Share JAR extension.

This Share extension contains the UI labels, forms, and Advanced search configuration for the Repo extension we developed in the previous section. This article is not primarily about building Alfresco extensions so I will not explain that code here.

 

The POM file for the project is the important part as it tells us how we can build against ACS 6.0, it looks like this:

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.alfresco.training</groupId>
<artifactId>custom-share-extension</artifactId>
<version>1.0-SNAPSHOT</version>

<name>Custom share extension JAR</name>
<packaging>jar</packaging>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

 

The Maven POM file is very straight forward in this case as we just need to package up the files in the src directory. There is no need for any Java file compilation. At the end we also filter the resource directory so we can use property substitution variables like this module.id=${project.artifactId} and have them converted to module.id=custom-share-extension during the build.

 

To build the extension:

 

custom-share-extension mbergljung$ mvn clean install

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building Custom share extension JAR 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ custom-share-extension ---

[INFO]

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ custom-share-extension ---

[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!

[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!

[INFO] Copying 5 resources

[INFO]

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ custom-share-extension ---

[INFO] No sources to compile

[INFO]

[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ custom-share-extension ---

[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!

[INFO] skip non existing resourceDirectory /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-share-extension/src/test/resources

[INFO]

[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ custom-share-extension ---

[INFO] No sources to compile

[INFO]

[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ custom-share-extension ---

[INFO] No tests to run.

[INFO]

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ custom-share-extension ---

[INFO] Building jar: /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-share-extension/target/custom-share-extension-1.0-SNAPSHOT.jar

[INFO]

[INFO] --- maven-install-plugin:2.4:install (default-install) @ custom-share-extension ---

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-share-extension/target/custom-share-extension-1.0-SNAPSHOT.jar to /Users/mbergljung/.m2/repository/org/alfresco/training/custom-share-extension/1.0-SNAPSHOT/custom-share-extension-1.0-SNAPSHOT.jar

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-share-extension/pom.xml to /Users/mbergljung/.m2/repository/org/alfresco/training/custom-share-extension/1.0-SNAPSHOT/custom-share-extension-1.0-SNAPSHOT.pom

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 1.160 s

[INFO] Finished at: 2018-04-06T14:56:59+01:00

[INFO] Final Memory: 11M/245M

[INFO] ------------------------------------------------------------------------

We now have a Share JAR extension in our local Maven repository, which is ready to be included in a custom Alfresco Share Image.

Building a custom Share Image

To build a custom image based on the standard alfresco/alfresco-share image we have to create a Dockerfile. But we also have to figure out a way to bring together all the extensions (both JARs and AMPs) that we want to include in the custom image. We can do that with a new Maven project.

Maven project to assemble all Share extensions

This project is part of the source code for this article and is called docker-share-custom. It is used to bring together all the Share extensions that we want to include in the custom Share image (this Maven project could potentially also be used to build the custom image with a plugin such as fabric8io, but this is not covered in this article):.

The POM looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.alfresco.training</groupId>
<artifactId>docker-share-custom</artifactId>
<version>1.0-SNAPSHOT</version>
<name>JAR and AMP assembly under /target for use by Dockerfile</name>
<packaging>pom</packaging>

<dependencies>
<dependency>
<groupId>org.alfresco.training</groupId>
<artifactId>custom-share-extension</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.softwareloop</groupId>
<artifactId>uploader-plus-surf</artifactId>
<version>1.6</version>
<type>amp</type>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-share-extensions</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.alfresco.training</groupId>
<artifactId>custom-share-extension</artifactId>
<version>1.0-SNAPSHOT</version>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/jars</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>com.softwareloop</groupId>
<artifactId>uploader-plus-surf</artifactId>
<version>1.6</version>
<type>amp</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/amps_share</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

 

In the dependencies section we define all the extensions that should be part of our custom Share image. In this case we define a dependency to the custom extension that we built in the previous section, and a dependency to an open source extension that customizes the upload functionality in Alfresco so you can attach metadata while uploading.

 

The maven-dependency-plugin plugin is used to copy the extensions in under the /target directory. We can then pick them up from here when building the custom Share image.

 

To build the project:

 

docker-share-custom mbergljung$ mvn clean install

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building JAR and AMP assembly under /target for use by Dockerfile 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ docker-share-custom ---

[INFO] Deleting /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-share-custom/target

[INFO]

[INFO] --- maven-dependency-plugin:3.0.2:copy (copy-share-extensions) @ docker-share-custom ---

[INFO] Configured Artifact: org.alfresco.training:custom-share-extension:1.0-SNAPSHOT:jar

[INFO] Configured Artifact: com.softwareloop:uploader-plus-surf:1.6:amp

[INFO] Copying custom-share-extension-1.0-SNAPSHOT.jar to /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-share-custom/target/jars/custom-share-extension-1.0-SNAPSHOT.jar

[INFO] Copying uploader-plus-surf-1.6.amp to /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-share-custom/target/amps/uploader-plus-surf-1.6.amp

[INFO]

[INFO] --- maven-install-plugin:2.4:install (default-install) @ docker-share-custom ---

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-share-custom/pom.xml to /Users/mbergljung/.m2/repository/org/alfresco/training/docker-share-custom/1.0-SNAPSHOT/docker-share-custom-1.0-SNAPSHOT.pom

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 0.966 s

[INFO] Finished at: 2018-04-06T15:19:06+01:00

[INFO] Final Memory: 12M/309M

[INFO] ------------------------------------------------------------------------

You now have a target directory that looks like this:

docker-share-custom mbergljung$ tree

.

├── Dockerfile

├── pom.xml

└── target

   ├── amps_share

   │ └── uploader-plus-surf-1.6.amp

   └── jars

       └── custom-share-extension-1.0-SNAPSHOT.jar

We can now code the Dockerfile to pick these extensions up from here.

Create the Dockerfile for custom Share image build

The Dockerfile we will use to build our custom Share image will be located in the same directory as the POM file that assembles the extensions. Here is what it looks like:

 

FROM alfresco/alfresco-share:6.0.a

ARG TOMCAT_DIR=/usr/local/tomcat

RUN mkdir -p $TOMCAT_DIR/amps_share

COPY target/amps_share $TOMCAT_DIR/amps_share
COPY target/jars $TOMCAT_DIR/webapps/share/WEB-INF/lib

RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install \
$TOMCAT_DIR/amps_share $TOMCAT_DIR/webapps/share -directory -nobackup -force

 

The first thing it does is to define that the new image will be based on the standard alfresco/alfresco-share image version 6.0.a that is available in Docker Hub. Then it defines a local variable called TOMCAT_DIR, which points to where in the standard image the Apache Tomcat installation is located. We then make sure that the amps_share directory exists in the image.

 

The next command in the file is to copy AMPs and JARs into the image. JAR extensions are copied directly into the exploded webapp. AMP extensions are copied into the /amps_share directory from where they will be picked up by the Module Management Tool (MMT).

 

The last step is to use the MMT tool to apply the AMPs to the exploded webapp.

Currently it does not work to put stuff in the {TOMCAT_DIR}/modules/share directory. JAR extensions are not picked up from this location at the moment.

Build the custom Share Docker Image

Now when the Dockerfile is ready and the AMP and JAR extensions are available, we can build the custom repository image as follows:

 

docker-share-custom mbergljung$ docker build . --tag my-acs-share:6.0

Sending build context to Docker daemon    108kB

Step 1/6 : FROM alfresco/alfresco-share:6.0.a

---> 9aaa0425fc95

Step 2/6 : ARG TOMCAT_DIR=/usr/local/tomcat

---> Running in 56271fc4b1ff

Removing intermediate container 56271fc4b1ff

---> 91c88b57b1b2

Step 3/6 : RUN mkdir -p $TOMCAT_DIR/amps_share

---> Running in 5287e9a5e61d

Removing intermediate container 5287e9a5e61d

---> 14a48b64c760

Step 4/6 : COPY target/amps_share $TOMCAT_DIR/amps_share

---> 64d5ff319179

Step 5/6 : COPY target/jars $TOMCAT_DIR/webapps/share/WEB-INF/lib

---> 7cf792efec42

Step 6/6 : RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install               $TOMCAT_DIR/amps_share $TOMCAT_DIR/webapps/share -directory -nobackup -force

---> Running in 7a3bbefcaf59

Removing intermediate container 7a3bbefcaf59

---> e760d22a715a

Successfully built e760d22a715a

Successfully tagged my-acs-share:6.0

We call the custom image my-acs-share and give it a version tag 6.0.

Verify that you have the new image locally:

 

$ docker image ls

REPOSITORY                                       TAG IMAGE ID CREATED           SIZE

my-acs-share                                     6.0 e760d22a715a 34 seconds ago      709MB

my-acs-repo                                      6.0 c133631019ac 9 hours ago         1.74GB

alfresco/alfresco-content-repository-community   6.0.4-ea df0b08d0d3a3 10 days ago         1.72GB

alfresco/alfresco-share                          6.0.a 9aaa0425fc95 10 days ago         709MB

alfresco/alfresco-search-services                1.1.0 56575d75dd82 2 months ago        884MB

We can see our image called my-acs-share and we also have the Docker Hub image that it is based on.

Running a container based on the custom Share image

Now we can start a container that is based on our new my-acs-share image. It will depend on the Repository, Search, and Database containers, so make sure they are running. The alf-net network must also still be available.

 

To start the custom Share container:

 

$ docker run --network alf-net --name alf-share -p 8081:8080 -e REPO_HOST=alf-repo -e REPO_PORT=8080 -d my-acs-share:6.0

245ee746cb2d5c28183ab67d97e176ffbe57775cfd13a9237791e53254d19429

 

In the logs we should see the new AMP and JAR extension applied:

 

$ docker container logs 245ee746cb2d5c28183ab67d97e176ffbe57775cfd13a9237791e53254d19429

2018-04-06 14:35:54,268  INFO [config.packaging.ModulePackageManager] [localhost-startStop-1] Found 3 module package(s)

2018-04-06 14:35:54,270  INFO [config.packaging.ModulePackageManager] [localhost-startStop-1] Alfresco / Google Docs Share Module, 3.0.4.2, The Share side artifacts of the Alfresco / Google Docs Integration.

uploader-plus-surf, 1.6.1801311724, uploader-plus AMP for Alfresco Share

Custom share extension JAR, 1.0-SNAPSHOT, ${project.description}

...

 

In the log above we can verify that the two extensions (i.e. Custom share extension JAR and uploader-plus-surf) we added have been installed successfully.

 

Check that you can access the Repository with Alfresco Share at http://localhost:8081/share.

 

Login with admin/admin and upload a document to a folder. Execute the Change Type action and you should see the new content type we added:

 

 

After changing the type you should see a new ACME Doc Information property section:

 

 

You can set the ACME Doc ID by clicking the Edit Properties action:

 

Let’s also test the custom uploader functionality to make sure the extension has been applied properly. The custom upload functionality will not be enabled unless you first make some configurations. Start by configuring a so called “Upload folder” under Admin Tools | Uploader Plus:



 

In this case I have selected a custom folder called Test that is a subfolder of Guest Home. I have then said that only ACME Document type is allowed this folder. It’s then just a matter of uploading something to this folder and the custom Upload Plus dialog will appear:



 

So that seems to work nicely, pretty cool!

Building and Running an Alfresco Repo Image with a data Volume

When we run a container based on the Repository image the Alfresco Data (i.e. alf_data) is stored inside the container. The way this works is that an image is made up of a number of read-only layers. When you start a container based on the Repository image an extra read-write layer will be created on top of it. Then when a file is updated, for example in the tomcat/alf_data directory inside the container, it will automatically be copied into the read-write layer (copy-on-write). A container is Ephemeral (lasts a very short time) and when you remove it the Alfresco data will also be gone as the read-write layer is not persisted outside the container.

 

This presents some problems for us as Alfresco Developers as we would be likely to create new images quite frequently as we keep updating different types of extensions. Every time we build a new custom Repository image with new versions of our extensions, and then start a container based on it, we will see that the Alfresco Data we had when testing the previous image is gone. This scenario may be sufficient for some developer scenarios. However, when you start this new container with a fresh content repository the database and search services will still have metadata and an index that matches when the previous content was added. To solve this you need to remove and restart the database and search services containers too.

 

We can get around this problem by connecting a Docker Volume to the Repository Container. The volume would then persists the Alfresco Data (alf_data) outside of the container life cycle.

Types of Docker Volumes

There are many different types of Docker Volumes with different characteristics. We need to choose one that fits our needs:

 

  • Host: A host volume lives on the Docker host's filesystem and can be accessed from within the container. To create a host volume do:
    • docker run -v /path/on/host:/path/in/container ...
  • Anonymous: An anonymous volume is useful for when you would rather have Docker handle where the files are stored. It can be difficult, however, to refer to the same volume over time when it is an anonymous volumes. To create an anonymous volume:
    • docker run -v /path/in/container …
    • Or in a Dockerfile: VOLUME /path/in/container
  • Named: A named volume is similar to an anonymous volume. Docker manages where on disk the volume is created, but you give it a name. To create a named volume use the following commands:
    • docker volume create somevolumename
    • docker run -v somevolumename:/path/in/container ...

 

The type of volume we will use is the Named. We will not use anonymous because it is difficult to find the volume associated with the data we are storing as the volume ID would look something like 08a2eb76f59faebe30ea972a683914f6011f4fe7fd0468152bfd4ff918f6709b. And an anonymous volume created from a Dockerfile would also not be useful as a new anonymous volume would be created every time we create a new container instance. A hosted volume would be very coupled to the operating system we use.

Creating a Named Repo Data Volume  

A named data volume would live its own life completely outside of container instances lifecycles. We can create it as follows for the Repository Data (i.e. alf_data):

 

$ docker volume create alf-repo-data
alf-repo-data


List the available volumes:

 

$ docker volume ls
DRIVER              VOLUME NAME
local               08a2eb76f59faebe30ea972a683914f6011f4fe7fd0468152bfd4ff918f6709b
local               8f5df54fcf77f5f5f8c740218c8a755aa3b18f7fa880631bc1f59d49e7ecbd72
local               alf-repo-data
local               c4b516ba67c1f9bfef106093db054d9388bdf0316f00e8ee2d7e69fcb9e01ee0
local               cecaf0c49f5e2c9fce247ef9ba9b48704707e6674e40f44545dcdc8a0a1e5809
local               de9fde85ca1ae2d60b79dff7386b11e7c6a289eff24bda3aa0ce6e3a01fc05f0
local               e39dacf1af8f1cc0451b2345ac43b5ea471e52f90d99ce92399eb17125d4df37


It’s very easy to spot the named volumes in the listing.

You might see a few volumes here as the PostgreSQL container uses anonymous volumes. We can remove unused volumes as follows:

 

$ docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
e39dacf1af8f1cc0451b2345ac43b5ea471e52f90d99ce92399eb17125d4df37
cecaf0c49f5e2c9fce247ef9ba9b48704707e6674e40f44545dcdc8a0a1e5809
8f5df54fcf77f5f5f8c740218c8a755aa3b18f7fa880631bc1f59d49e7ecbd72
de9fde85ca1ae2d60b79dff7386b11e7c6a289eff24bda3aa0ce6e3a01fc05f0
c4b516ba67c1f9bfef106093db054d9388bdf0316f00e8ee2d7e69fcb9e01ee0
alf-repo-data

Total reclaimed space: 112.7MB

Running the Alfresco Repository Container with a Volume

We can now restart the custom Repository container and have it use the named alf-repo-data volume. Before we continue stop and remove all the running containers:

 

$ docker container stop alf-postgres alf-search alf-repo alf-share

$ docker container rm alf-postgres alf-search alf-repo alf-share

 

Now let’s kick off the PostgreSQL and Alfresco Search Services containers so we have  them running when we start the Repository (we assume the Docker network alf-net still exists):

 

$ docker run --network alf-net --name alf-postgres -p 5432:5432 -e POSTGRES_USER=alfresco -e POSTGRES_PASSWORD=alfresco -e POSTGRES_DB=alfresco -d postgres:10.1  

95ba7abc8e62ca912cd8afa87bc4d6e3ac5756a0f3daf854587127fd7e5f31ce

$ docker run --network alf-net --name alf-search -p 8983:8983 -e SOLR_ALFRESCO_HOST=alf-repo -e SOLR_ALFRESCO_PORT=8080 -e SOLR_SOLR_HOST=alf-search -e SOLR_SOLR_PORT=8983 -e SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive -d alfresco/alfresco-search-services:1.1.1 

a9f19ec0e3cc5134db42791fd1247fd85532cf3737f55d9f5aff1bd7f361048c

And now start the repository container based on the my-acs-repo image:

$ docker run -v alf-repo-data:/usr/local/tomcat/alf_data--network alf-net --name alf-repo -p 8080:8080 -e JAVA_OPTS='-Ddb.driver=org.postgresql.Driver -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.url=jdbc:postgresql://alf-postgres:5432/alfresco -Dsolr.host=alf-search -Dsolr.port=8983 -Dsolr.secureComms=none -Dsolr.base.url=/solr -Dindex.subsystem.name=solr6' -d my-acs-repo:6.0

2c601b2e8ec9bf06df877e21e9d60d9e3f9bf67b77c802ae574394ed0571c285

Note here how we attach the container to the alf-repo-data volume and map it to the container directory /usr/local/tomcat/alf-data. As soon as the container is started up all the content under /usr/local/tomcat/alf-data will be copied to the volume.

Review the logs and make sure the Repository container starts successfully:

 

$ docker container logs 2c601b2e8ec9bf06df877e21e9d60d9e3f9bf67b77c802ae574394ed0571c285

11-Apr-2018 12:07:13.058 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]

11-Apr-2018 12:07:13.093 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]

11-Apr-2018 12:07:13.104 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 64455 ms

Inspecting the Repository Data Volume

To see which volume is used by the alf-repo container we can list the volumes (mounts) associated with a container:

 

$ docker container inspect -f "{{ .Mounts }}" alf-repo

[

{

volume alf-repo-data /var/lib/docker/volumes/alf-repo-data/_data /usr/local/tomcat/alf_data

local

z

true

}

]

 

As expected the alf-repo container is associated with the alf-repo-data volume.

 

If we were on a Linux box, such as Ubuntu, we could just list the contents of the /var/lib/docker/volumes/alf-repo-data/_data directory. But on a Mac or Windows machine that does not work as Docker runs inside a Virtual Machine (VM).

 

To see persistent volumes created by Docker for Mac (or Docker for Windows) you need to login to that hidden VM first.

 

To do this, we need to use a serial terminal on a Mac. There's a terminal application called "screen" that we can use:

  1. Open a new terminal window
  2. Use the screen tool to get into the Docker driver by executing command: screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
  3. You should see a blank screen, just press Enter, and after a while, you should see a command line prompt
  4. Now you're inside Docker's VM and you can cd into the volumes dir by typing: cd /var/lib/docker/volumes/alf-repo-data/_data

Add some content and then re-build the image

Let’s now try and see if we can re-build the custom Alfresco Repository image and still retain the content we have created so far.

Start a Share container and Add some content

Before we rebuild the Repo image we first need to add some content that we can verify with. Start the Alfresco Share container so we can add content:

 

$ docker run --network alf-net --name alf-share -p 8081:8080 -e REPO_HOST=alf-repo -e REPO_PORT=8080 -d alfresco/alfresco-share:6.0.a

160fe60f064515648acbd71fb82b69ec24de33841124943c17b0708ae049acf8

Login to Share and add a folder and file under Guest Home (use admin/admin when login):

Update and Build the Repo Extension

We will now make a small change to the custom-repo-extension/src/main/java/com/acme/alfresco/action/CustomRepoAction.java file to simulate that we have developed a new version of our Repo extension:

 

public class CustomRepoAction extends ActionExecuterAbstractBase {
private static final Logger LOG = LoggerFactory.getLogger(CustomRepoAction.class);

@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
// No parameters are passed to action
}

@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
System.out.println("Now, do something ... UPDATED");
}
}

 

In this case I just updated the println statement.

 

Now build the project to create a new extension version:

 

custom-repo-extension mbergljung$ mvn clean install

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building Custom repository extension JAR 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

....

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/custom-repo-extension/pom.xml to /Users/mbergljung/.m2/repository/org/alfresco/training/custom-repo-extension/1.0-SNAPSHOT/custom-repo-extension-1.0-SNAPSHOT.pom

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 3.463 s

[INFO] Finished at: 2018-04-12T08:29:30+01:00

[INFO] Final Memory: 42M/324M

[INFO] ------------------------------------------------------------------------

Rebuild the Repo image and restart Repo container

With the new extension version ready we can rebuild the Repo Image:

 

docker-alfresco-custom mbergljung$ docker build .  --tag my-acs-repo:6.1

Sending build context to Docker daemon  44.03kB

Step 1/6 : FROM alfresco/alfresco-content-repository-community:6.0.4-ea

---> df0b08d0d3a3

Step 2/6 : ARG TOMCAT_DIR=/usr/local/tomcat

---> Using cache

---> 1b0322f285fb

Step 3/6 : RUN mkdir -p $TOMCAT_DIR/amps

---> Using cache

---> 393c1f52691f

Step 4/6 : COPY target/amps $TOMCAT_DIR/amps

---> Using cache

---> 56260db9a225

Step 5/6 : COPY target/jars $TOMCAT_DIR/webapps/alfresco/WEB-INF/lib

---> Using cache

---> 09f8f701f2a2

Step 6/6 : RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install               $TOMCAT_DIR/amps $TOMCAT_DIR/webapps/alfresco -directory -nobackup -force

---> Using cache

---> fd4bb88fe25d

Successfully built fd4bb88fe25d

Successfully tagged my-acs-repo:6.1

We give the new image the name my-acs-repo, which is the same name as we used before. But we use version 6.1 to denote a newer build with newer versions of the extensions (we could remove version 6.0 of the image and use the same version number if we wanted to).

Now list the images to verify that we got version 6.1:

 

docker-alfresco-custom mbergljung$ docker image ls

REPOSITORY                                       TAG IMAGE ID CREATED           SIZE

my-acs-repo                                      6.1 fd4bb88fe25d 26 hours ago        1.74GB

my-acs-repo                                      6.0 8816690d43e7 2 days ago          1.72GB

my-acs-share                                     6.0 e760d22a715a 6 days ago          709MB

...

With the new 6.1 image available we can stop, remove, and restart the Repo container:

$ docker container stop alf-repo

alf-repo

$ docker container rm alf-repo

alf-repo

 

Make sure the named volume is still there:

$ docker volume ls

DRIVER              VOLUME NAME

local               08a2eb76f59faebe30ea972a683914f6011f4fe7fd0468152bfd4ff918f6709b

local               alf-repo-data

...

Start the repository container based on version 6.1 of the my-acs-repo image:

$ docker run -v alf-repo-data:/usr/local/tomcat/alf_data--network alf-net --name alf-repo -p 8080:8080 -e JAVA_OPTS='-Ddb.driver=org.postgresql.Driver -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.url=jdbc:postgresql://alf-postgres:5432/alfresco -Dsolr.host=alf-search -Dsolr.port=8983 -Dsolr.secureComms=none -Dsolr.base.url=/solr -Dindex.subsystem.name=solr6' -d my-acs-repo:6.1

1c5b74efa499f3624ece7b995bddc81e53548b3b4047bf238156c2b693cce471

 

Review the logs and make sure it is up and running.

Make sure content is intact

And now to the fun part. Login to Share, if needed, and make sure the folder and file previously uploaded is still there. They are kept in the external named volume, which should be independent of container life cycle.

Building and Running an Alfresco Repo Image with MySQL

Event though this article focuses a lot on the development environment you might still want to run it with a different database than the out-of-the-box PostgreSQL alternative. Maybe you like MySQL more, or have more experience with it.

 

In this section we will have a look at how to run a MySQL container instead of the PostgreSQL container. We will also have to figure out how to install the MySQL Connector JDBC driver into the Repository container.

Running a MySQL container with the Alfresco Database

The Alfresco Repo is going to connect to a MySQL database called ‘alfresco’ where the Repository can store the metadata for the content files. We can easily fire up a MySQL database with images available at https://hub.docker.com/_/mysql/.

 

We can look at the Docker Hub page for MySQL to see what environment variables we need to use to configure the database image. Kick off a new MySQL container as follows and give the new container the name alf-mysql (we assume that the alf-net network still exists):

 

$ docker run --network alf-net --name alf-mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=alfresco -e MYSQL_USER=alfresco -e MYSQL_PASSWORD=alfresco -d mysql:5.7.17 --character-set-server=utf8 --collation-server=utf8_general_ci --max_connections=1024

7921db488804459ebfa84dd6f5ff89d33bd4412f0fa690d4dda38f88394f6b50

 

The --networkoption must be specified directly after run. It cannot, for example, be at the end of the command.

 

Here we start a MySQL container with user/pwd alfresco/alfresco and configure it to create the default database with the name alfresco, which is what the repository needs. The database server is available externally on port 3306. We also connect the container to the alf-net network we created earlier on. The command returns the new container’s ID.

 

Test that it all worked by logging into the container and accessing the database (note that we use the short ID for the container):

 

$ docker container ls

CONTAINER ID        IMAGE COMMAND                  CREATED STATUS PORTS                    NAMES

7921db488804        mysql:5.7.17 "docker-entrypoint.s…"   19 seconds ago Up 20 seconds 0.0.0.0:3306->3306/tcp   alf-mysql

 

$ docker container exec -it 7921db488804/bin/bash

root@7921db488804:/# mysql -u alfresco -p

Enter password:

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 3

Server version: 5.7.17 MySQL Community Server (GPL)

 

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

 

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql> show tables;

Empty set (0.00 sec)

 

mysql> exit;

Bye

root@7921db488804:/# exit

exit

Building and Running an Alfresco Repo Container connecting to MySQL

The Alfresco database is now ready in the MySQL container. We need to build a Repository image containing the mysql-connector-java-5.1.42.jar JDBC driver.

Create and run a POM file that brings in the MySQL connector

First we will create a Maven POM that defines a dependency to the MySQL Connector and then copies it into the target/libs directory when we run the build. This POM is part of the acs-community-packaging-custom project that you downloaded earlier on. If you look into the docker-alfresco-custom-mysql sub-project you will find the POM file, which looks like this:

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.alfresco.training</groupId>
<artifactId>docker-alfresco-custom-mysql</artifactId>
<version>1.0-SNAPSHOT</version>
<name>LIB assembly under /target for use by Dockerfile</name>
<packaging>pom</packaging>

<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-libs</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

 

This POM file defines a dependency to the correct version (i.e. the supported one) of the MySQL JDBC connector and then we use the maven-dependency-plugin to copy the jar into the target/libs directory, where it will be ready to be picked up by the Dockerfile.

 

Now run the build:

 

docker-alfresco-custom-mysql mbergljung$ mvn clean install

[INFO] Scanning for projects...

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] Building LIB assembly under /target for use by Dockerfile 1.0-SNAPSHOT

[INFO] ------------------------------------------------------------------------

[INFO]

[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ docker-alfresco-custom-mysql ---

[INFO] Deleting /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom-mysql/target

[INFO]

[INFO] --- maven-dependency-plugin:3.0.2:copy (copy-libs) @ docker-alfresco-custom-mysql ---

[INFO] Configured Artifact: mysql:mysql-connector-java:5.1.42:jar

[INFO] Copying mysql-connector-java-5.1.42.jar to /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom-mysql/target/libs/mysql-connector-java-5.1.42.jar

[INFO]

[INFO] --- maven-install-plugin:2.4:install (default-install) @ docker-alfresco-custom-mysql ---

[INFO] Installing /Users/mbergljung/DeployProjects/acs-community-packaging-custom/docker-alfresco-custom-mysql/pom.xml to /Users/mbergljung/.m2/repository/org/alfresco/training/docker-alfresco-custom-mysql/1.0-SNAPSHOT/docker-alfresco-custom-mysql-1.0-SNAPSHOT.pom

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 0.916 s

[INFO] Finished at: 2018-04-10T15:14:22+01:00

[INFO] Final Memory: 12M/309M

[INFO] ------------------------------------------------------------------------

Looking in the target/libs directory we should now see the following:

docker-alfresco-custom-mysql mbergljung$ tree

.

├── Dockerfile

├── pom.xml

└── target

   └── libs

       └── mysql-connector-java-5.1.42.jar

Create and build a Dockerfile that injects the MySQL Connector

We are now ready to create the Dockerfile that injects the MySQL JDBC driver into the Repository image. The Dockerfile looks as follows and is also located in the docker-alfresco-custom-mysql directory:

 

FROM alfresco/alfresco-content-repository-community:6.0.5-ea

ARG TOMCAT_LIB_DIR=/usr/local/tomcat/lib

COPY target/libs $TOMCAT_LIB_DIR

 

The file is very simple, it just takes the standard Repository image as a starting point and then copies the JDBC driver into it. Building the image looks like this:

 

docker-alfresco-custom-mysql mbergljung$ docker build . --tag my-acs-repo-mysql:6.0

Sending build context to Docker daemon  1.004MB

Step 1/3 : FROM alfresco/alfresco-content-repository-community:6.0.5-ea

---> df0b08d0d3a3

Step 2/3 : ARG TOMCAT_LIB_DIR=/usr/local/tomcat/lib

---> Using cache

---> e14ed38cfbe5

Step 3/3 : COPY target/libs $TOMCAT_LIB_DIR

---> Using cache

---> 8816690d43e7

Successfully built 8816690d43e7

Successfully tagged my-acs-repo-mysql:6.0

We give the new image the name my-acs-repo-mysql and version 6.0. List the images so we see that it worked:

$ docker image ls

REPOSITORY                                       TAG IMAGE ID CREATED            SIZE

my-acs-repo-mysql                                6.0 8816690d43e7 About a minute ago   1.72GB

my-acs-repo                                      6.0 8816690d43e7 About a minute ago   1.72GB

...

Run the Alfresco Repository Container with MySQL

We are now ready to kick off the custom Repository container with the MySQL JDBC driver and connect to the MySQL container. But let’s first kick off the Alfresco Search Services container so we have that running when the repo starts up:

 

$ docker run --network alf-net --name alf-search -p 8983:8983 -e SOLR_ALFRESCO_HOST=alf-repo -e SOLR_ALFRESCO_PORT=8080 -e SOLR_SOLR_HOST=alf-search -e SOLR_SOLR_PORT=8983 -e SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive -d alfresco/alfresco-search-services:1.1.1 

0b4ca7a949adb2d8b2f07cb1d5ec95a51b350c54c762a577b3f275742d1b95d1

And now the repository container based on the my-acs-repo-mysql image:

$ docker run --network alf-net --name alf-repo -p 8080:8080 -e JAVA_OPTS='-Ddb.driver=org.gjt.mm.mysql.Driver -Ddb.username=alfresco -Ddb.password=alfresco -Ddb.url="jdbc:mysql://alf-mysql:3306/alfresco?useUnicode=yes&characterEncoding=UTF-8" -Dsolr.host=alf-search -Dsolr.port=8983 -Dsolr.secureComms=none -Dsolr.base.url=/solr -Dindex.subsystem.name=solr6' -d my-acs-repo-mysql:6.0

cdad9c60dd0e46bad24c7e5ff96a2c76b964616905e5effa2664a6b51e8c1af3

Review the logs and make sure it connects to MySQL successfully:

$ docker container logs cdad9c60dd0e46bad24c7e5ff96a2c76b964616905e5effa2664a6b51e8c1af3

10-Apr-2018 15:30:06.292 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.28

.

org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Ddb.driver=org.gjt.mm.mysql.Driver

10-Apr-2018 15:30:06.298 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Ddb.username=alfresco

10-Apr-2018 15:30:06.298 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Ddb.password=alfresco

10-Apr-2018 15:30:06.298 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Ddb.url=jdbc:mysql://alf-mysql:3306/alfresco?useUnicode=yes&characterEncoding=UTF-8

...

2018-04-10 15:30:28,393  INFO [alfresco.repo.admin] [localhost-startStop-1] Using database URL 'jdbc:mysql://alf-mysql:3306/alfresco?useUnicode=yes&characterEncoding=UTF-8' with user 'alfresco'.

2018-04-10 15:30:28,394  INFO [alfresco.repo.admin] [localhost-startStop-1] Connected to database MySQL version 5.7.17

...

2018-04-10 15:30:42,972  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Connecting to database: jdbc:mysql://alf-mysql:3306/alfresco?useUnicode=yes&characterEncoding=UTF-8, UserName=alfresco@172.21.0.4, MySQL Connector Java

2018-04-10 15:30:42,972  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Schema managed by database dialect org.alfresco.repo.domain.dialect.MySQLInnoDBDialect.

2018-04-10 15:30:43,118  WARN [domain.schema.SchemaBootstrap] [localhost-startStop-1] Schema validation found 46 potential problems, results written to: /usr/local/tomcat/temp/Alfresco/Alfresco-MySQLInnoDBDialect-Validation-Pre-Upgrade-alf_-1005770665855180801.txt

2018-04-10 15:30:43,133  WARN [domain.schema.SchemaBootstrap] [localhost-startStop-1] Schema validation found 25 potential problems, results written to: /usr/local/tomcat/temp/Alfresco/Alfresco-MySQLInnoDBDialect-Validation-Pre-Upgrade-act_-2723159380226551365.txt

2018-04-10 15:30:43,214  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Normalized schema dumped to file /usr/local/tomcat/temp/Alfresco/Alfresco-schema-MySQLInnoDBDialect-pre-upgrade-alf_-7824608645271764904.xml.

2018-04-10 15:30:43,214  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Normalized schema dumped to file /usr/local/tomcat/temp/Alfresco/Alfresco-schema-MySQLInnoDBDialect-pre-upgrade-act_-1758568877658060149.xml.

2018-04-10 15:30:43,278  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-4701688511608734693.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-RepoTables.sql).

2018-04-10 15:30:43,728  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-1660864257659333372.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-LockTables.sql).

2018-04-10 15:30:43,765  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-8147065905659118747.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-ContentTables.sql).

2018-04-10 15:30:43,843  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-2319822585342629214.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-PropertyValueTables.sql).

2018-04-10 15:30:43,982  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-7958840531865558083.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-ContentUrlEncryptionTables.sql).

2018-04-10 15:30:44,014  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-1493698802374057751.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-AuditTables.sql).

2018-04-10 15:30:44,071  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-3935710904755261199.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-ActivityTables.sql).

2018-04-10 15:30:44,121  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-2654492923882306612.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-UsageTables.sql).

2018-04-10 15:30:44,147  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-481654729795371565.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-SubscriptionTables.sql).

2018-04-10 15:30:44,162  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-7428379169648063519.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-TenantTables.sql).

2018-04-10 15:30:44,184  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Executing database script /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-4157934858382764547.sql (Copied from classpath:alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/AlfrescoCreate-AuthorizationTables.sql).

2018-04-10 15:30:44,215  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Create scripts executed in 1209 ms

2018-04-10 15:30:46,029  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] All executed statements:  /usr/local/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-All_Statements-638494183242731673.sql.

2018-04-10 15:30:46,317  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Compared database schema with reference schema (all OK): class path resource [alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/Schema-Reference-ALF.xml]

2018-04-10 15:30:46,507  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Compared database schema with reference schema (all OK): class path resource [alfresco/dbscripts/create/org.alfresco.repo.domain.dialect.MySQLInnoDBDialect/Schema-Reference-ACT.xml]

2018-04-10 15:30:46,870  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Normalized schema dumped to file /usr/local/tomcat/temp/Alfresco/Alfresco-schema-MySQLInnoDBDialect-post-upgrade-alf_-1249302916559560216.xml.

2018-04-10 15:30:46,870  INFO [domain.schema.SchemaBootstrap] [localhost-startStop-1] Normalized schema dumped to file /usr/local/tomcat/temp/Alfresco/Alfresco-schema-MySQLInnoDBDialect-post-upgrade-act_-1757141603492957245.xml.

[localhost-startStop-1] Alfresco Content Services started (Community Early Access). Current version: 6.0.4 (re493fa84-b38) schema 10,201. Originally installed version: 6.0.4 (re493fa84-b38) schema 10,201.

...

Check access via WebDAV

Verify that the Repository container is up and running successfully with the MySQL database. Connect to WebDAV via http://localhost:8080/alfresco/webdav.

The endless debate that comes up when we speak of mobile apps is whether the technology choice is native, choose a hybrid path or stick with browser-based applications.

 

At Alfresco we often have this debate ourselves, of course as a consumer the apps we enjoy most are likely to be native because of the richer user experience, slick navigation and native is essentially a perfect match for that device you spent you hard earned money on.

 

When we then start to think about enterprises and the public sector and what their strategy might be for  providing mobility solutions. Mobile apps by these organizations could be for the employees, customers or citizens and the use cases so varied that many other factors come into play.

 

How quickly do we need to produce an app? How much will it cost? Do we have the right skills? How do we retain control of content through device/app management? Does it need to work whilst users are offline? Will users want to edit content in other apps? Are there apps we need it to integrate with? … and many more…

 

The answers to these questions can help determine your mobility technology choices … we’d love to hear about what mobile technology choices you have made or would like to make through this short survey: https://www.surveymonkey.co.uk/r/Z65N6BT 

 

The survey has just four questions and should take no longer than 3 minutes to complete, thank you in advance as your feedback is valuable and will help shape future product direction.

The end of July comes with great news, folks! We have officially released Alfresco Governance Services 3.0. Governance Services? Yes, this release is all about changes! Records Management has upgraded its name along with a few other things like dependencies and the way of deploying the final product. 

 

Among the changes, by far the most important changes are compatibility with ACS 6.0(RM-6410,  RM-6135) including the removal of SDK and H2(RM-6295), upgrading to Spring 5(RM-6314) and starting using a containerized deployment environment with Docker (RM-6138).

 

Why Docker and a containerized environment?

 

A containerized deployment brings the advantage of deploying the product faster on any environment. As part of our release, we are publishing the community images to Docker Hub and Quay.io, and the enterprise ones only to Quay.io.

 

The images can be downloaded from these locations and used in a blink of an eye no matter on what environment. Based on your needs, you can choose to download the AGS repository image by itself, or also download the AGS Share image if you want to use our UI.

 

What's new in 3.0?


Alfresco Governance Services as you see has rebranded and continues with a series of changes. As mentioned in the last release, the most awaited change was the compatibility with ACS 6.0 which came with loads of upgrades when it comes to dependencies. The compatibility changes consisted in updating the schedulers(RM-6313) and the Jackson library(RM-6315), removing Hibernate(RM-6316) and upgrading the Spring  version(RM-6314).

 

Another new thing that you will enjoy is the continuously updated Docker images we're creating from our builds. For every successful build, new AGS repository and AGS Share docker images are created with the latest tag, then they are pushed to Quay.io and also on Docker Hub for the community ones. Also at every new release, the AGS images will be published with the tag containing the release version.

To get our community images check AGS-repository and AGS-share for the latest versions.

 

What's coming up next?


We've been working closely with some of you to address your needs and concerns, and our near future plans reflect that. We're working on integrating AGS Enterprise with Amazon Glacier, to open up access to long term cost effective storage for records and other content. This is the next step in our drive to improve and develop Alfresco's Information Lifecycle Management functionality.

Alongside that new module, we'll improve our build infrastructure in order to be able to release faster, and have a series of planned incremental improvements to our core RM features, based on feedback from the field. Keep an eye on JIRA for details of those.

 

We hope that this release was as you expected it to be and we hope to keep you excited about what’s coming up next too. If you have anything that you would like to know about the current release or if there’s anything you would like to see in the near future please let us know.

 

You can use any channel to contact us like using the comments below or writing a message to any of the team members.

 

 

Links

 

In this blog post I'm going to share how to deploy the brand new Alfresco Content Services Community Edition 201806 GA Release. The new deployment mechanism, announced as major change in the ACS 6.x version, discontinued the traditional wizard and introduced a new Dockerized deployment for the benefit of the Developers and DevOps. The manual  installation using the ZIP file containing the artifacts is still available and can be downloaded here.

 

Disclaimer: The intent of this blog post is to share a simple tutorial for the newbies on Alfresco Content Services, where to learn how to rapidly start to launch and using it. A lot of official and unofficial documentation is available (for free) in this community portal (and outside of it). Please refer to the 'Other resources' paragraph, for further details.

 

Deploying ACS using Docker compose

 

All the task con be easily completed thanks to the acs-community-deployment project, publicly available on Alfresco's GitHub account.

Please be sure you are pointing on the TAG 1.0.0 of the GitHub project, using the Alfresco Content Services Community Edition 201806 GA version. 

To deploy Alfresco Content Services Community Edition 201806 GA using Docker compose, the only prerequisites are about having Docker and Docker Compose available, with enough resources into you environment. Once done, you can follow complete the task following the list below.

 

  1. Clone the acs-community-deployment project (related to TAG 1.0.0) or download the source code from this link. As alternative, you can download the single file docker-compose.yml (but check you are using the one tagged with 1.0.0).
  2. Navigate to the folder where the docker-compose.yml file is located.
  3. Run docker-compose up.
  4. Open the following URLs in your browser to check that everything starts up:

 

You can now start using Alfresco Content Services opening a browser to the URL http://<machine_ip>:8080/share.

 

Note:

  • Make sure ports 5432, 8080, 8082, and 8083 are open. These are defined in the docker-compose.yml file.
  • If Docker is running on your local machine, the IP address will be just localhost.
  • If you're using the Docker Toolbox, run the following command to find the IP address:
docker-machine ip
  • If you run docker-compose up after deleting a previous Docker Compose cluster, then replace step 3 with the following command:
docker-compose down && docker-compose build --no-cache && docker-compose up

 

Other resources

 

 

Support and questions and answers


Something is not working properly?
Do you need support or have questions?

 

If this is the case raise a question here or join the community on Discord (channel: alfresco) or IRC.

 

See you there!

This article is about modules for the ACS repository and does not cover Share. Share modules from previous Alfresco versions can be deployed to ACS 6 without modifications.

 

This article describes how to migrate Alfresco SDK 3 based projects alfresco-platform-jar-archetype to Alfresco SDK 3 projects including the new dependencies from ACS 6. However, as a third party developer, it might be a lot easier for you to wait for the next version of the official Alfresco SDK.

 

Step 1: Upgrade Alfresco and Share versions

 

Find following properties in your original pom.xml file...

 

<alfresco.platform.version>5.2.f</alfresco.platform.version>
<alfresco.share.version>5.2.e</alfresco.share.version>

 

... and replace the values with the following numbers...

 

<alfresco.platform.version>6.0.7-ga</alfresco.platform.version>
<alfresco.share.version>6.0.b</alfresco.share.version>

 

Step 2: Change Alfresco distribution dependency name

 

Identify Alfresco distribution dependency in your original pom.xml file...

 

<dependency>
    <groupId>${alfresco.groupId}</groupId>
    <artifactId>alfresco-platform-distribution</artifactId>
    <version>${alfresco.platform.version}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

 

...and replace the name by using the following entry...

 

<dependency>
    <groupId>${alfresco.groupId}</groupId>
    <artifactId>alfresco-content-services-community-distribution</artifactId>
    <version>${alfresco.platform.version}</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

 

From this point you can compile and package your addon for ACS 6. 

 

Step 3: Refactor your code where required

 

Updates that might affect your custom code are (among others):

 

  • Spring
  • Quartz
  • POI
  • Jackson
  • multiple commons-* libraries

 

Removed libraries:

 

  • Hibernate

 

ACS 6 Migration Guide wiki page collects useful information about updating Java code to work with the ACS6 repository.

 

Conclusion

 

These simple instructions can be applied to upgrade your repository addons to ACS 6, but Alfresco will release a detailed guide for migration procedures in the future. 

The new Alfresco Content Services 6.0 is released, and I am happy to share the highlights of this version with you. The major focus of the new Alfresco Content Services 6.0 release was on significant architecture improvements and the new containerized deployment option based on Docker and Kubernetes.

Containerized deployment

With Alfresco Content Services 6.0, we provide more flexible deployment options including Docker & Kubernetes for fast and standardized deployments across all environments.

For those that prefer the more traditional way of installing Alfresco Content Services or its Community version, we - of course - continue to deliver the WAR files for a manual deployment. But for now, let’s focus on the new containerized deployment with Docker and Kubernetes.

 

Why have we invested in containerized deployments?

A number of customers and also users in the open source community requested containerized deployment options in the past. The advantages are obvious, it allows development and operations teams to move faster and deploy software in a more efficient way. Containers provide a consistent environment and support DevOps to accelerate development and deployment from the test environment through a staging system to production.  

 

Do you want to give it a try?

You can test the new improvements around Docker and Kubernetes either with the Community version or start a 30 day free trial of the enterprise version (https://www.alfresco.com/platform/content-services-ecm/trial/download ).

 

Which Alfresco images exist?

The screenshot below shows the currently available Alfresco images that provide:

  • Core parts of Alfresco Content Services like “alfresco-share”, “alfresco-search-services” or the “alfresco-content-repository”
  • Some supporting functionality, e.g. for image or document transformation

 

 

How to start with Docker?

With the new release of Alfresco Content Services 6.0, it is now possible to deploy the product from a number of Docker images as described above. But it would be a time-consuming and also complex task to deploy individual Docker containers based on these images. Furthermore, you’d have to do the configuration to make them work together.

Therefore, the recommended way is to use a docker-compose file to get to a “one-click to deploy” experience. A docker-compose file describes the containers of the environment and starts those containers.

This allows you to quickly deploy and run Alfresco Content Services with just a few commands:

 

$ git clone https://github.com/alfresco/acs-deployment.git

$ cd acs-deployment

$ git checkout 1.0.2

$ cd docker-compose

$ docker-compose up

 

A docker-compose file for testing and development purposes is also available at https://www.alfresco.com/platform/content-services-ecm/trial/download 

 

How to start with Kubernetes?

For production environments, we recommend to orchestrate our containers in a kubernetes cluster. It automates tasks like deployment, but also takes care of scaling and managing the containers in the cluster.

Alfresco uses the HELM package manager to provide production-grade reference deployments that can be adopted to your needs. We publish these Charts through our https://kubernetes-charts.alfresco.com/stable HELM Chart repository.

 

In many cases, the HELM charts can act as a reference for customized deployments; by basing deployments on the official HELM charts, customers can benefit from the extensive functional and security testing performed by Alfresco (HELM chart releases).

 

Where to get further information?

Here, you’ll find extensive documentation:

 

Code Organization

The top-level entry-point for building ACS Enterprise has been moved from Subversion to the Alfresco Content Services Packaging project in GitHub (https://github.com/Alfresco/acs-packaging).  Enterprise customers will be able to build the artifacts from scratch provided they have access to the enterprise-releases Nexus repository.

The intention of this restructuring was the following:

  • The code base was split into smaller projects that produce intermediate artifacts with their own versioning
  • The naming of the artifacts changed. The top-level artifacts include the following indicators in their names:
    • "community" to clarify that they are open source
    • "content-services" if they are Enterprise artifacts
    • “-ea” if they are early access versions

 

REST APIs

This release includes an updated version of the REST API Explorer to navigate the new REST APIs. Those developers that are new to Alfresco should have a closer look at the options the updated REST API provides.

Further information and a full documentation for each endpoint is available at our online REST API Explorer: https://api-explorer.alfresco.com/api-explorer

Use the userid admin and password admin if you're are using the online REST API explorer. To explore the operations on a specific entity just click on it (“favorites in this case):

 

If you are using the docker-compose file for development, the api-explorer application will soon be integrated into that.

 

Anonymous Usage Metrics via Heartbeat

Alfresco Content Services sends anonymous usage metrics to Alfresco through the Heartbeat service. We already used this anonymous information in the past to help understand the usage of our products and to better meet the needs of your organization.

We have been improving the Alfresco Heartbeat to report more detailed information so that we can evolve the product in ways that provide the most value to our customers. As part of this process, we are including the new heartbeat also in the Alfresco Community Edition so that we can better understand how our open source community interacts with the product. This will allow us to better include the needs of both - our customers and our open source community - in our roadmap discussions and decision making process.

Further information around our updated Alfresco Heartbeat is available in our online documentation at https://docs.alfresco.com/6.0/concepts/heartbeatintro.html.

 

Library Upgrades

With Alfresco Content Services 6.0, we introduced a few library upgrades to ensure ongoing security and to have the ability to leverage more capabilities in future releases. A number of underlying third-party libraries have been updated in both the Repository and Share.

We’ve received your feedback since we took the AddOns site offline on May 25th and I can appreciate people’s disappointment in seeing this resource being seemingly taken away, especially for those Community members who’d worked hard on creating AddOns.

 

I wanted to pause and answer to some of the questions that have come up in the community since:

 

Why did we take the site offline?

During an internal audit of all of our sites and systems ahead of GDPR we found out that there were some serious problems with the AddOns site security. The AddOns site stored personally identifiable information and with GDPR compliance looming, we took the difficult decision to take the site offline.

 

What we’re doing now

In the next 5-10 days, we’re going to create a version of the AddOns directory inside of the existing Alfresco Community website and import the previous add-ons to that space. Kristen Gastaldo is working on that, so expect to see some content in the next few days.

 

What we’re doing in the future

We’re currently gaining momentum internally on building what is next for an Alfresco AddOns / Extensions directory and we’d like to hear from you on how we can make it bigger and better than the AddOns site that went before.

*Update: All Addons can be found here - Alfresco Addons 

 

Unfortunately we’ve had to temporarily remove access to addons.alfresco.com - we understand that you may be disappointed, we’re working on bringing it back in a read-only mode whilst we work out what the next steps for the Alfresco AddOns Community.

 

We’d love to hear more from you on your thoughts on how we can move AddOns forward as we begin planning the next evolution of the Alfresco Community we kindly invite you to contact us with a message. We will do our best to face and solve the issue as soon as possible. We sincerely hope that this won't cause problems to anyone. If it will happen, we apologise in advance.

 

Update of 7th of June - You can find the draft of the static list at Alfresco Addons *Incomplete list* 

 

About Alfresco AddOns

 

If you have ever customised or extended Alfresco Content Services (and/or Alfresco Share), you might have found a website called addons.alfresco.com. Alfresco Add-on website is a large collection of customisations and extensions for the Alfresco platform, contributed by the company's global developer community. The Alfresco Add-on website was designed to be a one-stop shop for Alfresco users looking to extend the functionality of Alfresco with pre-built modules.

 

The Alfresco Add-on website has been active since 2012 and since the beginning it grew rapidly, hosting several hundreds of different projects: Open Source and Proprietary, developed by Alfresco official partners or Community enthusiasts, supported or "given as is" in terms of production readiness. From this point of view, the initiative has been a success and a positive achievement of the entire Alfresco ecosystem (Alfresco as a Company, partners, customers, users, enthusiasts, etc.).

 

Most of the Alfresco enthusiasts agree that a sort of "Alfresco Marketplace" would be something useful for everyone, even if some concerns were around since a long time about the (proven) level of maturity of the (oldest) releases of the projects with the newest versions of Alfresco Content Services (and Alfresco Share). In addition to that, an improved experience in searching and installing the add-ons were something suggested, but never discussed and defined with enough details.

 

Today the GDPR is forcing us to the decision to put the Alfresco Add-on website in stand-by mode, until its future version will be defined and re-launched again. Looking forward to start the discussion around the next version of the Alfresco Marketplace, Add-on mechanism or whatever it will be.

Filter Blog

By date: By tag: