Deploying Magnolia using Azure App Service
Azure App Service provides a web hosting service that enables quick deployments of Magnolia projects. It integrates well with Maven and can be used directly from your IDE. Once configured, it just takes a few commands to deploy your Magnolia application to a hosted service, where the application can be accessed from the public internet. This makes it easy for users outside your organization to test new features in your Magnolia project.
This blog explains how to enable quick deployments of a single Magnolia instance to a hosted Azure environment using standard development tools. Full documentation for production-ready configurations and deployments is outside the scope of this blog.
Prerequisites
Tools
Besides the standards required for Magnolia development like Maven and Java, you will need to install the following tools for Azure:
You can either work on the command line or install a toolkit for your development environment:
In this example, we will use the command line and Maven tools, but feel free to use one of the above alternatives.
General Azure and Maven setup
We assume that you already have an Azure account and were able to create an initial configuration on your development machine to use the Azure command-line tools. You should also be aware of how Maven is used to create Java-based web applications, such as a Magnolia instance. We provide additional resources at the end of this article for more information.
Please be aware that you have to use unique parameters for your Magnolia instance, for example for its name, because Azure does not allow you to use the same parameters for multiple Azure clients at the same time, like “MagnoliaAzureDemo”.
Create a service principal
Service principals are dedicated Azure accounts for automated tools providing an account without administrator privileges. Using a service principal is more secure than using a regular user account.
To enable Maven to deploy the Magnolia project on Azure, create a service principal with password-based authentication:
# az ad sp create-for-rbac --name MagnoliaAzureDemo
It’s important to keep the output of the result you retrieve from this command, especially the password which cannot be retrieved later.
{
"appId": "ed4b6deb-e623-4d75-949b-1674dbfa7e82",
"displayName": "MagnoliaAzureDemo",
"name": "http://MagnoliaAzureDemo",
"password": "pBpBiZYy.P7PB0GmpN2T1vq-Z4huA~Tuct",
"tenant": "f7b40566-d9fd-49e6-a4ad-2c4fbc01129d"
}
In production, you should make use of Azure’s key vault or use Maven to encrypt the key value.
We recommended storing any configuration in Maven settings. Therefore, adjust your existing settings.xml file by adding a server configuration:
settings.xml
...
<server>
<id>azure-auth</id>
<configuration>
<client>ed4b6deb-e623-4d75-949b-1674dbfa7e82</client>
<tenant>f7b40566-d9fd-49e6-a4ad-2c4fbc01129d</tenant>
<key>pBpBiZYy.P7PB0GmpN2T1vq-Z4huA~Tuct</key>
<environment>AZURE</environment>
</configuration>
</server>
...
You can specify the Azure region using one of the following values for the environment parameter: AZURE, AZURE_CHINA, AZURE_GERMANY, or AZURE_US_GOVERNMENT.
Prepare the Magnolia demo
In this article, we will use a simple Magnolia public instance based on the “magnolia-community-demo-webapp”. Alternatively, you can skip this section and leverage one of your existing projects.
If you are new to Magnolia, we recommend you read how to create a custom webapp with Maven first. You can also have a look at an example project.
Configure the Magnolia webapp
The Magnolia instance context should be available as a subdomain matching the name of your deployment on the azurewebsites.net domain, like:
https://<name>.azurewebsites.net/
For the root configuration, create a folder named “ROOT” under <project>-webapp/src/main/webapp/WEB-INF/config and add a magnolia.properties file.
magnolia-blog-azure-demo-webapp/
├── overlays/
└── src/
└── main/
└── webapp/
├── docroot/
└── WEB-INF
├── bootstrap/
└── config
├── default/
└── ROOT
└── magnolia.properties
Add the following content to magnolia.properties to bootstrap a public Magnolia instance at the ROOT level.
magnolia.bootstrap.authorInstance=false
# the directories in which the bootstrap files are searched
magnolia.bootstrap.dir=WEB-INF/bootstrap/public WEB-INF/bootstrap/common
Integrate Azure into your build configuration
Add a profile to the pom.xml in the <project-name>-webapp:
pom.xml
<profiles>
...
<profile>
<id>ROOT</id>
<build>
<finalName>ROOT</finalName>
</build>
</profile>
</profiles>
In the same file, add the Azure Maven build plug-in:
<build>
<plugins>
...
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>1.12.0</version>
<configuration>
<schemaVersion>V2</schemaVersion>
<subscriptionId>94dbb43c-40b5-4de6-ba4f-7b00075XXX456</subscriptionId>
<resourceGroup>MagnoliaAzureDemoResourceGroup</resourceGroup>
<appName>mgnlazuredemo</appName>
<pricingTier>B3</pricingTier>
<region>westeurope</region>
<runtime>
<os>Linux</os>
<webContainer>Tomcat 9.0</webContainer>
<javaVersion>Java 11</javaVersion>
</runtime>
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.war</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
</plugins>
</build>
In a production deployment, you would use properties and variable names in your Maven configuration. Feel free to adjust the pricing tier, region, and other values according to your needs. See Maven Plugin for Azure App Service for additional information.
Deploying your CMS to Azure Cloud
Our free blueprints guide you through deploying your CMS to Azure Cloud, using Magnolia CMS as an example
Test your deployment
Open a terminal and navigate to <project-name>-webapp of your Magnolia project.
Create a Resource Group
If you have not already done so, create a Resource Group for the demo using your preferred name and location parameters:
# az group create --name MagnoliaAzureDemoResourceGroup --location westeurope
This should produce a response in JSON similar to the below:
{
"id": "/subscriptions/94dbb43c-41b6-5de5-ba9d-7b11175de438/resourceGroups/MagnoliaAzureDemoResourceGroup",
"location": "westeurope",
"managedBy": null,
"name": "MagnoliaAzureDemoResourceGroup",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
Build and deploy Magnolia
Build Magnolia with the ROOT profile. The final artifact will be called ROOT.war and the magnolia.properties file in the ROOT folder will be used at startup.
# mvn clean package -P ROOT
Deploy the build to Azure:
# mvn azure-webapp:deploy
The last command can take some time while Azure App Service takes care of your Magnolia instance:
[INFO] Trying to deploy artifact to mgnlazuredemo...
[INFO] Deploying the war file ROOT.war...
[INFO] Successfully deployed the artifact to https://mgnlazuredemo.azurewebsites.net
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Once you see the “BUILD SUCCESS” message you can access your Magnolia instance via its public URL https://<name>.azurewebsites.net/ and start the installation:
When the installation is complete, start Magnolia:
You have successfully deployed a Magnolia instance and should now see your public website:
Now try to restart the instance from the terminal and see what happens:
# az webapp restart -n mgnlazuredemo -g MagnoliaAzureDemoResourceGroup
Once the service is ready, you’ll notice that you see “Start installation” again, because the Azure container has not stored the default location of its file-based H2 database.
Stop and delete the Magnolia demo instance:
# az webapp stop --name mgnlazuredemo --resource-group MagnoliaAzureDemoResourceGroup
# az webapp delete --name mgnlazuredemo --resource-group MagnoliaAzureDemoResourceGroup
Adjust Magnolia instance properties
Open the magnolia.properties file you created above and add the following lines:
magnolia.content.bootstrap.dir=/var/lib/mgnl-public/content-importer
magnolia.upload.tmpdir=/var/tmp/mgnl-public-uploaded
magnolia.exchange.history=/var/tmp/mgnl-public-history
magnolia.home=/home/site/magnolia
magnolia.resources.dir=/home/site/magnolia/resources
magnolia.cache.startdir=/home/site/magnolia/cache
magnolia.repositories.home=/home/site/magnolia/repositories
magnolia.logs.dir=/home/site/magnolia/log
magnolia.author.key.location=/home/site/magnolia/magnolia-activation-keypair.properties
For a public instance, set magnolia.update.auto=true, to trigger module installations automatically rather than giving your visitors the option to update Magnolia.
# Set it to true if bootstrapping/update should be performed automatically
magnolia.update.auto=true
Deploy the new build
Repeat the previous steps:
# mvn clean package -P ROOT
# mvn azure-webapp:deploy
Once the instance has been deployed successfully, navigate to your application URL and clear your browser cache if necessary.
Troubleshooting
If Magnolia fails to start, check its log file by connecting to the container via SSH:
# az webapp ssh -n mgnlazuredemo -g MagnoliaAzureDemoResourceGroup
# tail -f /home/site/magnolia/log/magnolia-debug.log
Clean up Azure resources
Attention: Remove any unused resources and orphaned artifacts to prevent being charged for them by Microsoft.
Use the Azure portal or clean up on the command line:
# az webapp stop --name mgnlazuredemo --resource-group MagnoliaAzureDemoResourceGroup
# az webapp delete --name mgnlazuredemo --resource-group MagnoliaAzureDemoResourceGroup
# az group delete --name MagnoliaAzureDemoResourceGroup
Simplifying Magnolia deployments with Azure App Service
Azure App Service is a convenient way to deploy Maven-based Magnolia projects to the cloud. It builds on an existing tool stack and requires only some initial configuration. Furthermore, it provides integrations for the most popular Java IDEs out-of-the-box.
Azure App Service’s stability and reliability have improved significantly in recent years. However, its “self-patching” approach might pose challenges in production environments. A productive installation might also require higher standards of performance, data storage, and scalability.
In any case, it is a solution that relieves developers from providing and configuring their own infrastructure whether you use it for testing or more.