This guide is geared towards developers who are looking to use Microsoft Azure as a hosting environment for their Next.js website/application. Essentially, there are 2 ways you can host Next.js on Azure:
When building a preview environment, we recommend using Server-Side Rendering (SSR).
Behind the scenes, your Next.js project syncs content from your Agility CMS locally. For static sites (SSG) any changes made in Agility would require a site rebuild to re-generate the files. By running your project in SSR using
npm run start in your Next.js project, it does not require a site rebuild and any changes made will be synced immediately and available for preview. This makes the editing experience more streamlined, simple, and responsive.
When building your production environment, we recommend using Static Site Generation (SSG). You can also use Server-Side Rendering for production, but it's recommended to put your website/application behind a Content Delivery Network (CDN) to help with performance and caching.
There are many benefits that come with Static Site Generation:
- Security - Statically generating your site removes multiple moving parts and systems from the hosting infrastructure resulting in fewer servers and systems to harden against attack.
- Scalability - When sites can be served entirely from a CDN there is no complex logic or workflow to determine what assets can be cached and when.
- Performance - With all the pages are already available on a CDN close to the user and ready to serve, very high performance is possible without introducing expensive or complex infrastructure.
- Maintainability - When hosting complexity is reduced, so are maintenance tasks. A pre-generated site, being served directly from a simple host or directly from a CDN does not need a team of experts to "keep the lights on".
Server-Side Rendering (SSR)
To host your Next.js application/website in Azure using Server-Side Rendering, you need to use Docker to dockerize your project.
How Azure works with Docker and Why
Docker is a containerization technology that allows you to package your application and all development dependencies into a container.
A few of the many benefits are:
- Docker enables more efficient use of system resources
- Docker enables faster software delivery cycles
- Docker enables application portability
- Great for microservice architectures
- Package your application and environments to run anywhere
Azure App Services is a PaaS for hosting your websites. Until recently you were not able to host Docker images natively but with the introduction of Azure Web Apps for containers, we can now get the benefits of Docker and Azure.
How to Dockerize your Project
Before your start, make sure you have Docker installed locally on your machine.
At the root of your project, create a file named
FROM node:14 # Create app directory WORKDIR /app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json ./ RUN npm install # Bundle app source COPY . . RUN npm run build EXPOSE 3000 CMD ["npm","run","start"]
How to create your Azure Environment using Docker & Azure Containers
- Create an Azure Container Registry
az acr create --resource-group myResourceGroup --name <azureContainerRegistry> --sku Basic
- Authenticate Azure Container Registry
If you are a user:
az acr login --name <azureContainerRegistryFQDN>
If you need to authenticate using an Azure Service Principal
docker login --name <azureContainerRegistryFQDN>/<nameOfImage> -u <s_AppId> -p <s_Password>
- Build docker image
docker image build -t <azureContainerRegistryFQDN>/<nameOfImage>:latest .
- Push Docker Image
docker push <azureContainerRegistryFQDN>/<nameOfImage>:latest
Preview and Production Environments
Preview and production environments are hosted in the same Azure App Service/Docker Image. To toggle between Preview and Live content:
When setting up your DevOps it's important to keep in mind when pushing changes to your docker image that it takes time to pull, build and start up the site. This only applies to changes to your docker image NOT to your Agility CMS content. The content will be synced automatically when saving or publishing items.
We recommend using a deployment slot to first pull in your updated image and once up and running. You can validate your changes and then perform a swap.
With the use of Azure Dev Ops (azure-pipelines.yml) and Docker (Dockerfile), you can use Docker to build an image, and then push it to the Azure Container registry of your choice. An Azure App Service that you set up would simply use the Registry to enable Continuous Deployment.
# Docker # Build a Docker image # https://docs.microsoft.com/azure/devops/pipelines/languages/docker trigger: - master resources: - repo: self variables: tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build image jobs: - job: Build displayName: Build & Deploy all Environments (sample) pool: vmImage: 'ubuntu-latest' steps: - task: Docker@2 displayName: 'Build and Push Preview Env' inputs: containerRegistry: '$(containerRegistry)' repository: '$(containerRepository)' command: 'buildAndPush' Dockerfile: '**/Dockerfile' tags: 'latest'
Streaming Logs from Azure App Service Container
You can stream logs from the Azure App Service that is running your container using the Azure CLI.
- Login to Azure CLI using your personal Azure Account:
Or, use a Service Principal to log in:
az login --service-principal --username <APP_ID> --password <PASSWORD> --tenant <TENANT_ID>
- Select your Azure Subscription
az account set --subscription <SUBSCRIPTIONNAME>
- Stream Web Logs:
az webapp log tail --resource-group <RESOURCEGROUP> --name <APPSERVICENAME>
Securing Environment Variables
Authenticating with Agility CMS API services requires you to set API Keys. These are typically managed using environment variables. In order to keep sensitive information such as this hidden from prying eyes, ensure you have a .gitignore file that will ignore any .env local files from being checked into source control. Then, in your Azure App Service, define those variables as Application settings so that your server environment can access them.
Static Site Generation (SSG)
To host Next.js projects in Azure using Static Site Generation (SSG), you can deploy directly to Azure Static Web Apps (Recommended) or host the files in blob storage.
Further steps coming soon.