Skip to content

Commit

Permalink
build(dockerfile): update dockerfile to handle deploying to production (
Browse files Browse the repository at this point in the history
#693)

* build(dockerfile): update dockerfile to handle deploying to production

Amend dockerfile to be multistage and allow generating a different image for staging and production.
Production needs to be different as it needs to not have http auth, not have the staging banner, and
it needs to be built from a git repo to eanble the 'last updated' functionality for components.

* build(deployment): add config to deploy prod to Cloud Platform

* build(deployment): correct production deploy action, allow for manual running

* build(deployment): reenable workflow push and pr triggers

Manual trigger only works if the workflow file is merged on main :( so re-enabling the other
triggers fro testing on the branch

* build(deployment): fix prod deploy workflow yaml

* build(deployment): enable auth on new prod site until domain is sorted

* build(deployment): add live domain to kubernetes hosting config

* build(deployment): combin cloudplatform deploy with tests and publish in one workflow

* build(deployment): remove auth from production deploy config
  • Loading branch information
chrispymm authored Sep 11, 2024
1 parent ad73113 commit 1ad47e3
Show file tree
Hide file tree
Showing 8 changed files with 1,257 additions and 856 deletions.
119 changes: 119 additions & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Deploy main to production
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]

env:
GITHUB_DEPLOY_KEY: ${{ secrets.GH_DEPLOY_KEY }}
ECR_NAME: ${{ secrets.ECR_NAME }}
KUBE_CLUSTER: ${{ secrets.KUBE_CLUSTER }}
KUBE_NAMESPACE: ${{ secrets.KUBE_NAMESPACE }}

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm ci
- run: npm run build:package
- uses: actions/upload-artifact@v4
with:
name: mojds-package
path: package
- run: npm run build:dist
- run: npm run build:docs
- uses: actions/upload-artifact@v4
with:
name: mojds-dist
path: dist

test:
runs-on: ubuntu-latest
needs: build

strategy:
matrix:
node-version: [12.x, 14.x, 16.x, 18.x, 20.x]

steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: mojds-package
path: package
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Test Sass can be compiled
run: npm run test:sass

publish:
runs-on: ubuntu-latest
needs: [build, test]
if: github.event_name == 'push'

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: lts/*
- uses: actions/download-artifact@v4
with:
name: mojds-package
path: package
- uses: actions/download-artifact@v4
with:
name: mojds-dist
path: dist
- run: npm ci
- name: Publish to NPM
run: npm run ci:release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}

push-to-production:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.ECR_ROLE_TO_ASSUME }}
aws-region: ${{ vars.ECR_REGION }}
- uses: aws-actions/amazon-ecr-login@v2
id: login-ecr
- run: |
docker build --build-arg GITHUB_DEPLOY_KEY="${GITHUB_DEPLOY_KEY}" --target=production -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
cat kubernetes-deploy-production.tpl | envsubst > kubernetes-deploy-production.yaml
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: ${{ vars.ECR_REPOSITORY }}
IMAGE_TAG: ${{ github.sha }}
BRANCH: "production"
- run: |
echo "${KUBE_CERT}" > ca.crt
kubectl config set-cluster ${KUBE_CLUSTER} --certificate-authority=./ca.crt --server=https://${KUBE_CLUSTER}
kubectl config set-credentials deploy-user --token=${KUBE_TOKEN}
kubectl config set-context ${KUBE_CLUSTER} --cluster=${KUBE_CLUSTER} --user=deploy-user --namespace=${KUBE_NAMESPACE}
kubectl config use-context ${KUBE_CLUSTER}
kubectl -n ${KUBE_NAMESPACE} apply -f kubernetes-deploy-production.yaml
env:
KUBE_CERT: ${{ secrets.KUBE_CERT }}
KUBE_TOKEN: ${{ secrets.KUBE_TOKEN }}
KUBE_CLUSTER: ${{ secrets.KUBE_CLUSTER }}
2 changes: 1 addition & 1 deletion .github/workflows/tag-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- uses: aws-actions/amazon-ecr-login@v2
id: login-ecr
- run: |
docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
docker build --target=staging -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
cat kubernetes-deploy-staging.tpl | envsubst > kubernetes-deploy-staging.yaml
env:
Expand Down
31 changes: 26 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
FROM node:lts-slim AS build
FROM node:lts AS base

RUN apt-get update && apt-get -y install autoconf gcc make

WORKDIR /app

FROM base AS staging-build
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci
Expand All @@ -15,13 +17,32 @@ COPY gulp gulp
COPY gulpfile.js gulpfile.js
COPY README.md README.md
COPY webpack.config.js webpack.config.js

RUN STAGING=1 npm run build:docs

FROM nginxinc/nginx-unprivileged:alpine AS nginx
FROM base AS production-build
RUN apt-get -y install git
ARG GITHUB_DEPLOY_KEY
RUN mkdir /root/.ssh/
RUN echo "${GITHUB_DEPLOY_KEY}" > /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa
RUN touch /root/.ssh/known_hosts
RUN ssh-keyscan github.com >> /root/.ssh/known_hosts

EXPOSE 3000
RUN git clone [email protected]:ministryofjustice/moj-frontend.git .

run npm install
RUN npm run build:docs

RUN rm /root/.ssh/id_rsa

FROM nginxinc/nginx-unprivileged:alpine AS staging
EXPOSE 3000
COPY docker/htpasswd /etc/nginx/.htpasswd
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY docker/nginx-staging.conf /etc/nginx/conf.d/default.conf
COPY --from=staging-build /app/public /usr/share/nginx/html

COPY --from=build /app/public /usr/share/nginx/html
FROM nginxinc/nginx-unprivileged:alpine AS production
EXPOSE 3000
COPY docker/nginx-production.conf /etc/nginx/conf.d/default.conf
COPY --from=production-build /app/public /usr/share/nginx/html
16 changes: 16 additions & 0 deletions docker/nginx-production.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
server {
listen 3000;
server_name localhost;

absolute_redirect off;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
File renamed without changes.
70 changes: 70 additions & 0 deletions kubernetes-deploy-production.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: moj-frontend-${BRANCH}
spec:
replicas: 1
selector:
matchLabels:
app: moj-frontend-${BRANCH}
template:
metadata:
labels:
app: moj-frontend-${BRANCH}
spec:
containers:
- name: moj-frontend
image: ${REGISTRY}/${REPOSITORY}:${IMAGE_TAG}
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: moj-frontend-service-${BRANCH}
labels:
app: moj-frontend-service-${BRANCH}
spec:
ports:
- port: 3000
name: http
targetPort: 3000
selector:
app: moj-frontend-${BRANCH}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: moj-frontend-ingress-${BRANCH}
annotations:
external-dns.alpha.kubernetes.io/set-identifier: moj-frontend-ingress-${BRANCH}-${KUBE_NAMESPACE}-green
external-dns.alpha.kubernetes.io/aws-weight: "100"
spec:
ingressClassName: default
tls:
- hosts:
- ${KUBE_NAMESPACE}-${BRANCH}.apps.live.cloud-platform.service.justice.gov.uk
- hosts:
- design-patterns.service.justice.gov.uk
secretName: moj-frontend-prod-secret
rules:
- host: ${KUBE_NAMESPACE}-${BRANCH}.apps.live.cloud-platform.service.justice.gov.uk
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: moj-frontend-service-${BRANCH}
port:
number: 3000
- host: design-patterns.service.justice.gov.uk
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: moj-frontend-service-${BRANCH}
port:
number: 3000
Loading

0 comments on commit 1ad47e3

Please sign in to comment.