Skip to content

Commit

Permalink
Support build and deployment within K8 against custom subdomain (#292)
Browse files Browse the repository at this point in the history
* Add Docker static site containerisation

This change adds Docker containerisation utilising a multi-stage build
Dockerfile. This leads to the static site being generated and served
through nginx.

* Add GHA to build and publish to Quay

This change adds a new GitHub Action that builds the resultant Docker
image and publishes this to the Quay repository.

* Add Helm chart for deployment

This change adds the necessary Helm configuration to deploy the
application within an appropriate Kubernetes cluster.

* Add Drone deployment

This change adds Drone configuration to trigger a new deployment to the
appropriate Kubernetes namespace.
  • Loading branch information
LiamMacP authored Oct 18, 2023
1 parent c15b21d commit 71c41df
Show file tree
Hide file tree
Showing 13 changed files with 304 additions and 1 deletion.
69 changes: 69 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---

kind: pipeline
type: kubernetes
name: helm lint

platform:
os: linux
arch: amd64

trigger:
event:
- pull_request
branch:
- main

steps:
- name: lint-helm-chart
image: pelotech/drone-helm3
settings:
mode: lint
chart: helm
values_files: helm/values.yaml
values:
- app.image.version=$${DRONE_COMMIT_SHA}

---
kind: pipeline
type: kubernetes
name: deployment

platform:
os: linux
arch: amd64

trigger:
event:
- push
branch:
- main

steps:
- name: Wait for image tag
image: alpine/curl:8.2.1
commands:
- |
while ! curl -s -L 'https://quay.io/api/v1/repository/ukhomeofficedigital/engineering-guidance-and-standards/tag?specificTag=${DRONE_COMMIT_SHA}' | grep -q '${DRONE_COMMIT_SHA}' ; do
echo "Tag not present, waiting 10 seconds"
sleep 10
done
- name: Deployment
image: pelotech/drone-helm3
settings:
chart: helm
mode: upgrade
namespace: sas-prod
release: engineering-guidance-and-standards
kube_certificate:
from_secret: kube_cert_acp_prod
kube_api_server: https://kube-api-prod.prod.acp.homeoffice.gov.uk
kube_token:
from_secret: kube_token_acp_prod
values_files: helm/values.yaml
wait_for_upgrade: true
timeout: 10m
history_max: 3
values:
- app.image.version=$${DRONE_COMMIT_SHA}
10 changes: 9 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
commit-message:
prefix: "docker"
labels:
- "dependencies"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "daily"
commit-message:
prefix: "github-actions"
labels:
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/build-and-publish-docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: build-and-publish-docker

on:
pull_request:
types: [ closed ]

jobs:
build:
uses: UKHomeOffice/sas-github-workflows/.github/workflows/publish-docker.yml@v2
if: |
github.event.pull_request.merged == true &&
github.base_ref == 'main'
with:
image: 'quay.io/ukhomeofficedigital/engineering-guidance-and-standards'
tag: ${{ github.sha }}
secrets: inherit
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:18.18.0-alpine AS build

COPY . .

RUN apk update && apk upgrade && \
apk add --no-cache git

RUN npm ci --omit=dev
RUN npm run build

FROM nginx:1.25.2-alpine

COPY --from=build /_site /usr/share/nginx/html
COPY --from=build /nginx/nginx.conf /etc/nginx/nginx.conf

USER 1000

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
5 changes: 5 additions & 0 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v2
name: engineering-guidance-and-standards
description: A Helm chart for Engineering Guidance and Standards
type: application
version: 1.0.0
6 changes: 6 additions & 0 deletions helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{{/*
Name of the chart.
*/}}
{{- define "app.name" -}}
{{- .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
28 changes: 28 additions & 0 deletions helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "app.name" . }}
spec:
selector:
matchLabels:
app: {{ include "app.name" . }}
replicas: 1
template:
metadata:
labels:
app: {{ include "app.name" . }}
spec:
containers:
- name: {{ .Chart.Name }}
image: {{ .Values.app.image.repository }}:{{ .Values.app.image.version }}
imagePullPolicy: Always
resources:
requests:
memory: "20Mi"
cpu: "100m"
limits:
memory: "400Mi"
cpu: "500m"
ports:
- containerPort: {{ .Values.app.port }}
29 changes: 29 additions & 0 deletions helm/templates/ingress-external.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{- if .Values.ingress.external.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "app.name" . }}-external
labels:
cert-manager.io/solver: route53
annotations:
cert-manager.io/enabled: "true"
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: "nginx-external"
tls:
- hosts:
- {{ .Values.ingress.external.host }}
secretName: {{ include "app.name" . }}-external
rules:
- host: {{ .Values.ingress.external.host }}
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: {{ include "app.name" . }}
port:
number: {{ .Values.service.port }}
{{- end }}
29 changes: 29 additions & 0 deletions helm/templates/ingress-internal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{{- if .Values.ingress.internal.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "app.name" . }}-internal
labels:
cert-manager.io/solver: route53
annotations:
cert-manager.io/enabled: "true"
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: "nginx-internal"
tls:
- hosts:
- {{ .Values.ingress.internal.host }}
secretName: {{ include "app.name" . }}-internal
rules:
- host: {{ .Values.ingress.internal.host }}
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: {{ include "app.name" . }}
port:
number: {{ .Values.service.port }}
{{- end}}
19 changes: 19 additions & 0 deletions helm/templates/networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ include "app.name" . }}-service-policy
spec:
podSelector:
matchLabels:
app: {{ include "app.name" . }}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-internal
- namespaceSelector:
matchLabels:
name: ingress-external
13 changes: 13 additions & 0 deletions helm/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "app.name" . }}
spec:
selector:
app: {{ include "app.name" . }}
type: ClusterIP
ports:
- name: https
port: 443
targetPort: {{ .Values.app.port }}
16 changes: 16 additions & 0 deletions helm/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
app:
image:
repository: quay.io/ukhomeofficedigital/engineering-guidance-and-standards
version:
port: 80

service:
port: 443

ingress:
internal:
enabled: true
host: engineering.internal.sas.homeoffice.gov.uk
external:
enabled: false
host: engineering.homeoffice.gov.uk
47 changes: 47 additions & 0 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /tmp/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;

keepalive_timeout 10;
send_timeout 10;
server_tokens off;
client_body_timeout 10;
client_header_timeout 10;
client_max_body_size 100K;

server {
listen 80;
root /usr/share/nginx/html;

location / {
try_files $uri $uri/ $uri.html =404;
}

error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}

client_body_temp_path /tmp/client_temp;
proxy_temp_path /tmp/proxy_temp_path;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;

}

0 comments on commit 71c41df

Please sign in to comment.