CI: Add k8s deployment
This commit is contained in:
parent
4995aa2a0b
commit
9e507eda66
143
.gitlab-ci.yml
143
.gitlab-ci.yml
|
@ -20,6 +20,11 @@ stages:
|
|||
- test
|
||||
- release
|
||||
- deploy
|
||||
- deploy-production
|
||||
|
||||
#
|
||||
# Validation
|
||||
#
|
||||
|
||||
check-style:
|
||||
image: composer:latest
|
||||
|
@ -45,6 +50,10 @@ validate-yarn:
|
|||
script:
|
||||
- pjv
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
.docker_template: &docker_definition
|
||||
image: docker:18
|
||||
services:
|
||||
|
@ -78,6 +87,10 @@ build-image:
|
|||
- docker build --pull --build-arg VERSION="${VERSION}" -t "${TEST_IMAGE}" -f docker/Dockerfile .
|
||||
- docker push "${TEST_IMAGE}"
|
||||
|
||||
#
|
||||
# Test
|
||||
#
|
||||
|
||||
audit-composer:
|
||||
image: ${TEST_IMAGE}
|
||||
stage: test
|
||||
|
@ -125,6 +138,10 @@ test:
|
|||
after_script:
|
||||
- '"${DOCROOT}/bin/migrate" down'
|
||||
|
||||
#
|
||||
# Release
|
||||
#
|
||||
|
||||
release-image:
|
||||
<<: *docker_definition
|
||||
stage: release
|
||||
|
@ -146,11 +163,27 @@ release-image-nginx:
|
|||
- master
|
||||
|
||||
.deploy_template: &deploy_definition
|
||||
stage: deploy
|
||||
stage: release
|
||||
image: ${TEST_IMAGE}
|
||||
before_script:
|
||||
- apk add -q bash rsync openssh-client
|
||||
|
||||
build-release-file:
|
||||
<<: *deploy_definition
|
||||
stage: release
|
||||
artifacts:
|
||||
name: release_${CI_COMMIT_REF_SLUG}_${CI_JOB_ID}_${CI_COMMIT_SHA}
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- ./release/
|
||||
script:
|
||||
- rsync -vAax "${DOCROOT}" "${DOCROOT}/.babelrc" "${DOCROOT}/.browserslistrc" release/
|
||||
- rsync -vAax public/assets release/public/
|
||||
|
||||
#
|
||||
# Deploy staging
|
||||
#
|
||||
|
||||
.deploy_template_script:
|
||||
# Configure SSH
|
||||
- &deploy_template_script |-
|
||||
|
@ -158,20 +191,9 @@ release-image-nginx:
|
|||
rsync -vAax public/assets ${DOCROOT}/public/
|
||||
cd "${DOCROOT}"
|
||||
|
||||
build-release-file:
|
||||
deploy:
|
||||
<<: *deploy_definition
|
||||
stage: deploy
|
||||
artifacts:
|
||||
name: "release_${CI_COMMIT_REF_SLUG}_${CI_JOB_ID}_${CI_COMMIT_SHA}"
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- ./release/
|
||||
script:
|
||||
- rsync -vAax "${DOCROOT}" "${DOCROOT}/.babelrc" "${DOCROOT}/.browserslistrc" release/
|
||||
- rsync -vAax public/assets release/public/
|
||||
|
||||
deploy-staging:
|
||||
<<: *deploy_definition
|
||||
environment:
|
||||
name: staging
|
||||
only:
|
||||
|
@ -187,8 +209,84 @@ deploy-staging:
|
|||
# Deploy to server
|
||||
- ./bin/deploy.sh -r "${STAGING_REMOTE}" -p "${STAGING_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}"
|
||||
|
||||
.kubectl_deployment: &kubectl_deployment
|
||||
stage: deploy
|
||||
image:
|
||||
name: bitnami/kubectl:latest
|
||||
entrypoint: ['']
|
||||
before_script:
|
||||
- &kubectl_deployment_script if [[ -z "${KUBE_INGRESS_BASE_DOMAIN}" ]]; then echo "Skipping deployment"; exit; fi
|
||||
|
||||
.deploy_k8s: &deploy_k8s
|
||||
<<: *kubectl_deployment
|
||||
artifacts:
|
||||
name: deployment.yaml
|
||||
expire_in: 1 day
|
||||
when: always
|
||||
paths:
|
||||
- deployment.yaml
|
||||
script:
|
||||
# CI_ENVIRONMENT_URL is the URL configured in the GitLab environment
|
||||
- export CI_ENVIRONMENT_URL="${CI_ENVIRONMENT_URL:-https://${CI_PROJECT_PATH_SLUG}.${KUBE_INGRESS_BASE_DOMAIN}/}"
|
||||
- export CI_IMAGE=$RELEASE_IMAGE
|
||||
- export CI_IMAGE_NGINX=$RELEASE_IMAGE_NGINX
|
||||
- export CI_INGRESS_DOMAIN=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?\K([^/]+)' | head -n1)
|
||||
- export CI_INGRESS_PATH=$(echo "$CI_ENVIRONMENT_URL" | grep -oP '(?:https?://)?(?:[^/])+\K(.*)')
|
||||
- export CI_KUBE_NAMESPACE=$KUBE_NAMESPACE
|
||||
# Any available storage class like longhorn
|
||||
- export CI_PVC_SC=${CI_PVC_SC:-"${CI_PVC_SC_LOCAL:-local-path}"}
|
||||
- export CI_REPLICAS=${CI_REPLICAS_REVIEW:-${CI_REPLICAS:-2}}
|
||||
- export CI_APP_NAME=${CI_APP_NAME:-Engelsystem}
|
||||
|
||||
- cp deployment.tpl.yaml deployment.yaml
|
||||
- for env in ${!CI_*}; do sed -i "s#<${env}>#$(echo "${!env}"|head -n1)#g" deployment.yaml; done
|
||||
|
||||
- echo "Deploying to ${CI_ENVIRONMENT_URL}"
|
||||
- kubectl apply -f deployment.yaml
|
||||
- >-
|
||||
kubectl -n $CI_KUBE_NAMESPACE wait --for=condition=Ready pods --timeout=${CI_WAIT_TIMEOUT:-5}m
|
||||
-l app=$CI_PROJECT_PATH_SLUG -l tier=database
|
||||
- >-
|
||||
kubectl -n $CI_KUBE_NAMESPACE wait --for=condition=Ready pods --timeout=${CI_WAIT_TIMEOUT:-5}m
|
||||
-l app=$CI_PROJECT_PATH_SLUG -l tier=application -l commit=$CI_COMMIT_SHORT_SHA
|
||||
|
||||
.deploy_k8s_stop: &deploy_k8s_stop
|
||||
<<: *kubectl_deployment
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
dependencies: []
|
||||
when: manual
|
||||
script:
|
||||
- kubectl delete all,ingress,pvc -l app=$CI_PROJECT_PATH_SLUG -l environment=$CI_ENVIRONMENT_SLUG
|
||||
|
||||
deploy-k8s-review:
|
||||
<<: *deploy_k8s
|
||||
environment:
|
||||
name: review/${CI_COMMIT_REF_NAME}
|
||||
on_stop: stop-k8s-review
|
||||
auto_stop_in: 1 week
|
||||
url: https://${CI_PROJECT_PATH_SLUG}-review.${KUBE_INGRESS_BASE_DOMAIN}/${CI_COMMIT_REF_SLUG}
|
||||
variables:
|
||||
CI_REPLICAS_REVIEW: 1
|
||||
CI_APP_NAME: review/${CI_COMMIT_REF_NAME}
|
||||
before_script:
|
||||
- *kubectl_deployment_script
|
||||
- RELEASE_IMAGE=$TEST_IMAGE
|
||||
- RELEASE_IMAGE_NGINX=$TEST_IMAGE_NGINX
|
||||
|
||||
stop-k8s-review:
|
||||
<<: *deploy_k8s_stop
|
||||
environment:
|
||||
name: review/${CI_COMMIT_REF_NAME}
|
||||
action: stop
|
||||
|
||||
#
|
||||
# Deploy production
|
||||
#
|
||||
|
||||
deploy-production:
|
||||
<<: *deploy_definition
|
||||
stage: deploy-production
|
||||
environment:
|
||||
name: production
|
||||
when: manual
|
||||
|
@ -204,3 +302,22 @@ deploy-production:
|
|||
- *deploy_template_script
|
||||
# Deploy to server
|
||||
- ./bin/deploy.sh -r "${PRODUCTION_REMOTE}" -p "${PRODUCTION_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}"
|
||||
|
||||
deploy-k8s-production:
|
||||
<<: *deploy_k8s
|
||||
stage: deploy-production
|
||||
environment:
|
||||
name: production
|
||||
on_stop: stop-k8s-production
|
||||
when: manual
|
||||
only:
|
||||
- master
|
||||
|
||||
stop-k8s-production:
|
||||
<<: *deploy_k8s_stop
|
||||
stage: deploy-production
|
||||
only:
|
||||
- master
|
||||
environment:
|
||||
name: production
|
||||
action: stop
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: engelsystem-db
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClassName: <CI_PVC_SC>
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: database
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
tier: database
|
||||
spec:
|
||||
containers:
|
||||
- image: mariadb:10.2
|
||||
name: database
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: MYSQL_DATABASE
|
||||
value: engelsystem
|
||||
- name: MYSQL_USER
|
||||
value: engelsystem
|
||||
- name: MYSQL_PASSWORD
|
||||
value: engelsystem
|
||||
- name: MYSQL_RANDOM_ROOT_PASSWORD
|
||||
value: '1'
|
||||
- name: MYSQL_INITDB_SKIP_TZINFO
|
||||
value: 'yes'
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/mysql
|
||||
name: data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: engelsystem-db
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: database
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
commit: <CI_COMMIT_SHORT_SHA>
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 3306
|
||||
targetPort: 3306
|
||||
name: database
|
||||
selector:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
tier: database
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: engelsystem
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
commit: <CI_COMMIT_SHORT_SHA>
|
||||
spec:
|
||||
replicas: <CI_REPLICAS>
|
||||
selector:
|
||||
matchLabels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
tier: application
|
||||
commit: <CI_COMMIT_SHORT_SHA>
|
||||
annotations:
|
||||
app.gitlab.com/app: <CI_PROJECT_PATH_SLUG>
|
||||
app.gitlab.com/env: <CI_ENVIRONMENT_SLUG>
|
||||
commit: <CI_COMMIT_SHORT_SHA>
|
||||
spec:
|
||||
initContainers:
|
||||
- image: <CI_IMAGE>
|
||||
name: engelsystem-migrate
|
||||
imagePullPolicy: Always
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- while ! bin/migrate up; do sleep 1; done
|
||||
env:
|
||||
- name: MYSQL_HOST
|
||||
value: database
|
||||
- name: MYSQL_DATABASE
|
||||
value: engelsystem
|
||||
- name: MYSQL_USER
|
||||
value: engelsystem
|
||||
- name: MYSQL_PASSWORD
|
||||
value: engelsystem
|
||||
containers:
|
||||
- image: <CI_IMAGE>
|
||||
name: engelsystem-fpm
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: MYSQL_HOST
|
||||
value: database
|
||||
- name: MYSQL_DATABASE
|
||||
value: engelsystem
|
||||
- name: MYSQL_USER
|
||||
value: engelsystem
|
||||
- name: MYSQL_PASSWORD
|
||||
value: engelsystem
|
||||
- name: APP_URL
|
||||
value: <CI_ENVIRONMENT_URL>
|
||||
- name: APP_NAME
|
||||
value: '<CI_APP_NAME>'
|
||||
- image: <CI_IMAGE_NGINX>
|
||||
name: engelsystem-nginx
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: PHP_FPM_HOST
|
||||
value: localhost
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: engelsystem
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
commit: <CI_COMMIT_SHORT_SHA>
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
name: engelsystem
|
||||
selector:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
tier: application
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: engelsystem-ingress
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: 'true'
|
||||
kubernetes.io/ingress.class: 'nginx'
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /$1
|
||||
labels:
|
||||
app: <CI_PROJECT_PATH_SLUG>
|
||||
environment: <CI_ENVIRONMENT_SLUG>
|
||||
commit: <CI_COMMIT_SHORT_SHA>
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- <CI_INGRESS_DOMAIN>
|
||||
secretName: <CI_INGRESS_DOMAIN>
|
||||
rules:
|
||||
- host: <CI_INGRESS_DOMAIN>
|
||||
http:
|
||||
paths:
|
||||
- path: '<CI_INGRESS_PATH>/?(.*)'
|
||||
backend:
|
||||
serviceName: engelsystem
|
||||
servicePort: 80
|
|
@ -1,4 +1,6 @@
|
|||
FROM nginx:alpine as es_nginx
|
||||
COPY docker/nginx/entrypoint.sh /
|
||||
ENTRYPOINT /entrypoint.sh
|
||||
RUN mkdir -p /var/www/public/ && touch /var/www/public/index.php
|
||||
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env sh
|
||||
set -e
|
||||
|
||||
sed -i "s/es_php_fpm:/${PHP_FPM_HOST:-es_php_fpm}:/g" /etc/nginx/nginx.conf
|
||||
|
||||
# If first arg starts with a `-` or is empty
|
||||
if [[ "${1#-}" != "${1}" ]] || [[ -z "${1}" ]]; then
|
||||
set -- nginx -g 'daemon off;' "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
Loading…
Reference in New Issue