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.
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.
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.
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).
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.
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 is one of the most popular container platforms. Docker provides functionality for deploying and running applications in containers based on images.
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.
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.
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.
Before we can deploy and run the Alfresco Content Services it is necessary to install the technologies that it uses.
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:
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:
There are also other supporting features available, such as Docker images for image and document transformation:
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:
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.
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.
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.
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 'jdbcostgresql://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: jdbcostgresql://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.
We can now access the Web UI at http://localhost:8080/share. The login credentials are: admin/admin.
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
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/:
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.
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.
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>.
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
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
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.
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.
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
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.
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.
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=jdbcostgresql://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
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.
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.
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.
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.
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.
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.
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.
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>
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.
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.
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.
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.
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.
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=jdbcostgresql://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
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.
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.
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.
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.
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.
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.
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!
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.
There are many different types of Docker Volumes with different characteristics. We need to choose one that fits our needs:
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.
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
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=jdbcostgresql://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
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:
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.
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):
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] ------------------------------------------------------------------------
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=jdbcostgresql://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.
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.
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.
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
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.
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
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
...
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.
...
Verify that the Repository container is up and running successfully with the MySQL database. Connect to WebDAV via http://localhost:8080/alfresco/webdav.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.