Introduction - IN PROGRESS
We are currently utilising Redwood as the tooling to build out a Startup software offer. We have chosen Microsoft Azure as our cloud provider.
Redwood offers multiple cloud options, however, Azure hasn’t made the list of supported solutions yet.
This guide will take you through how we have achieved a functional environment within Microsoft Azure.
Services
Within our current environment, we are utilising the following Azure Services:
- Azure App Service (Application Service)
- Azure Static Web App (Static Web App Service)
- Azure Database for PostgreSQL flexible server (PostgreSQL Service)
We are also using the following services for CI/CD
- Github
- Github Actions
- Github Container Registry (ghcr.io)
Application Service Configuration - API Side
1. Docker
As Redwood doesn’t support Azure Functions at the time of development, we needed to containerise our API side of the application.
The docker file performs the following actions
- Uses Node 16 Alpine.
- Sets the DATABASE_URL and SESSION_SECRET environmental variables.
- Creates an app directory (/app).
- Copies API, .nvmrc, graphql.config.js, package.json, redwood.toml & yarn.lock into app directory.
- Runs yarn install.
- Adds React, React-DOM to work around some issues seen within the build process.
- Runs the API build.
- Runs any outstanding migrations on the PostgreSQL.
- Removes the non-required app/api/src folder.
- Exposes 8911 and runs the API.
Dockerfile:
FROM node:16-alpine
ENV DATABASE_URL=
ENV SESSION_SECRET=
WORKDIR /app
COPY api api
COPY .nvmrc .
COPY graphql.config.js .
COPY package.json .
COPY redwood.toml .
COPY yarn.lock .
# RUN yarn install --frozen-lockfile
RUN yarn install
RUN yarn add react react-dom --ignore-workspace-root-check
RUN yarn rw build api
RUN yarn rw data-migrate up
RUN rm -rf ./api/src
WORKDIR /app/api
# WEBSITES_PORT=8911 in Azure Web Apps
EXPOSE 8911
ENTRYPOINT [ "yarn", "rw", "serve", "api", "--port", "8911", "--rootPath", "/api" ]
2. Github Actions
The purpose of the Github Action is to create an updated version of the docker image, it then pushes the image to the repositories Github Container Registry.
The below code performs the following operations:
name: Build & Push Docker Image
on:
push:
branches:
- master
env:
REGISTRY: ghcr.io
IMAGE_NAME: your_image_name
DATABASE_URL: ${{ secrets.DATABASE_URL }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Login to the container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract tags & labels for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: . # Searches the root of the repo for the dockerfile
push: true
tags: ghcr.io/{GITHUB_ORGANISATION_NAME}/{IMAGE_NAME}:latest
labels: ${{ steps.meta.outputs.labels }}
3. Github Container Registry
Github container registry will store the image privately (if your main code repo is private).
There is no need to change anything in GHCR.
4. Azure App Service
Within your Azure App Service configuration