diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 0000000..1a45345 --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,3 @@ +.env.production +mysql-secret.env +.dockerconfigjson diff --git a/build/build.sh b/build/build.sh index 9cae866..fdccc14 100755 --- a/build/build.sh +++ b/build/build.sh @@ -1,8 +1,45 @@ +set -e + +run_command() { + echo "Running: $*" >&2 + $* +} + REGISTRY_URL="registry.chaoticlogic.us" IMAGE_NAME="daniel-website" IMAGE_TAG="latest" +KUBE_NAMESPACE="portfolio" +KUBE_POD_LABELS="app=portfolio,tier=website" + +STARTING_PWD=$(pwd) PROJECT_PATH=$(realpath "$(dirname "$0")/..") -docker build -t "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" "$PROJECT_PATH" -docker push "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" +run_command cd "$PROJECT_PATH/build" + +REQUIRED_IGNORED_FILES=(".env.production" "mysql-secret.env" ".dockerconfigjson") + +run_command docker build -t "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" "$PROJECT_PATH" +run_command docker push "$REGISTRY_URL/$IMAGE_NAME:$IMAGE_TAG" + +for i in "${!REQUIRED_IGNORED_FILES[@]}" +do + FILE=${REQUIRED_IGNORED_FILES[$i]} + + if [ ! -e "$FILE" ] + then + echo "Missing file $PROJECT_PATH/$FILE required to deploy. Skipping deploy" + exit 0 + fi +done + +run_command kubectl apply -k "$PROJECT_PATH/build/" + +echo "Waiting for deployment" +run_command sleep 30 + +WEBSITE_POD=$(run_command kubectl get pod -l "$KUBE_POD_LABELS" -n "$KUBE_NAMESPACE" -o jsonpath="{.items[0].metadata.name}") + +run_command kubectl delete -n "$KUBE_NAMESPACE" pod "$WEBSITE_POD" + +run_command cd "$STARTING_PWD" diff --git a/build/k3s.yaml b/build/k3s.yaml new file mode 100644 index 0000000..727bab5 --- /dev/null +++ b/build/k3s.yaml @@ -0,0 +1,230 @@ +# vim: syntax=yaml:ts=2:et + +apiVersion: v1 +kind: Namespace +metadata: + name: portfolio + +--- +apiVersion: v1 +kind: Service +metadata: + name: website + namespace: portfolio + labels: + app: portfolio +spec: + ports: + - port: 80 + selector: + app: portfolio + tier: website + +--- +apiVersion: v1 +kind: Service +metadata: + name: mysql + namespace: portfolio + labels: + app: portfolio +spec: + ports: + - port: 3306 + selector: + app: portfolio + tier: mysql + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mysql-pvc + namespace: portfolio + labels: + app: portfolio +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: website + namespace: portfolio + labels: + app: portfolio +spec: + selector: + matchLabels: + app: portfolio + tier: website + strategy: + type: Recreate + template: + metadata: + namespace: portfolio + labels: + app: portfolio + tier: website + spec: + containers: + - image: registry.chaoticlogic.us/daniel-website:latest + imagePullPolicy: Always + name: website + ports: + - containerPort: 80 + name: http + volumeMounts: + - name: env + mountPath: /app/.env + subPath: .env.production + volumes: + - name: env + configMap: + name: env-cm + imagePullSecrets: + - name: chaoticlogic-registry-login + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mysql + namespace: portfolio + labels: + app: portfolio +spec: + selector: + matchLabels: + app: portfolio + tier: mysql + strategy: + type: Recreate + template: + metadata: + namespace: portfolio + labels: + app: portfolio + tier: mysql + spec: + containers: + - image: mysql:5 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-pass + key: password + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pvc + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ingress-https + namespace: portfolio +spec: + entryPoints: + - https + routes: + - match: Host(`danieldecloet.nl`) + kind: Rule + middlewares: + - name: www-redirect + services: + - name: website + port: 80 + tls: + certResolver: letsencrypt + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ingress-http + namespace: portfolio +spec: + entryPoints: + - http + routes: + - match: Host(`danieldecloet.nl`) + kind: Rule + middlewares: + - name: https-redirect + - name: www-redirect + services: + - name: website + port: 80 + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ingress-https-www + namespace: portfolio +spec: + entryPoints: + - https + routes: + - match: Host(`www.danieldecloet.nl`) + kind: Rule + services: + - name: website + port: 80 + tls: + certResolver: letsencrypt + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ingress-http-www + namespace: portfolio +spec: + entryPoints: + - http + routes: + - match: Host(`www.danieldecloet.nl`) + kind: Rule + middlewares: + - name: https-redirect + services: + - name: website + port: 80 +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: https-redirect + namespace: portfolio +spec: + redirectScheme: + scheme: https + permanent: true + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: www-redirect + namespace: portfolio +spec: + redirectRegex: + regex: ^(https?://)danieldecloet.nl/(.*)$ + replacement: ${1}www.danieldecloet.nl/${2} + permanent: true diff --git a/build/kustomization.yaml b/build/kustomization.yaml new file mode 100644 index 0000000..1bfbbf6 --- /dev/null +++ b/build/kustomization.yaml @@ -0,0 +1,17 @@ +resources: +- k3s.yaml +configMapGenerator: +- name: env-cm + namespace: portfolio + files: + - .env.production +secretGenerator: +- name: chaoticlogic-registry-login + namespace: portfolio + type: kubernetes.io/dockerconfigjson + files: + - .dockerconfigjson +- name: mysql-pass + namespace: portfolio + envs: + - mysql-secret.env