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
|
- test
|
||||||
- release
|
- release
|
||||||
- deploy
|
- deploy
|
||||||
|
- deploy-production
|
||||||
|
|
||||||
|
#
|
||||||
|
# Validation
|
||||||
|
#
|
||||||
|
|
||||||
check-style:
|
check-style:
|
||||||
image: composer:latest
|
image: composer:latest
|
||||||
|
@ -45,6 +50,10 @@ validate-yarn:
|
||||||
script:
|
script:
|
||||||
- pjv
|
- pjv
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build
|
||||||
|
#
|
||||||
|
|
||||||
.docker_template: &docker_definition
|
.docker_template: &docker_definition
|
||||||
image: docker:18
|
image: docker:18
|
||||||
services:
|
services:
|
||||||
|
@ -78,6 +87,10 @@ build-image:
|
||||||
- docker build --pull --build-arg VERSION="${VERSION}" -t "${TEST_IMAGE}" -f docker/Dockerfile .
|
- docker build --pull --build-arg VERSION="${VERSION}" -t "${TEST_IMAGE}" -f docker/Dockerfile .
|
||||||
- docker push "${TEST_IMAGE}"
|
- docker push "${TEST_IMAGE}"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test
|
||||||
|
#
|
||||||
|
|
||||||
audit-composer:
|
audit-composer:
|
||||||
image: ${TEST_IMAGE}
|
image: ${TEST_IMAGE}
|
||||||
stage: test
|
stage: test
|
||||||
|
@ -125,6 +138,10 @@ test:
|
||||||
after_script:
|
after_script:
|
||||||
- '"${DOCROOT}/bin/migrate" down'
|
- '"${DOCROOT}/bin/migrate" down'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Release
|
||||||
|
#
|
||||||
|
|
||||||
release-image:
|
release-image:
|
||||||
<<: *docker_definition
|
<<: *docker_definition
|
||||||
stage: release
|
stage: release
|
||||||
|
@ -146,11 +163,27 @@ release-image-nginx:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
.deploy_template: &deploy_definition
|
.deploy_template: &deploy_definition
|
||||||
stage: deploy
|
stage: release
|
||||||
image: ${TEST_IMAGE}
|
image: ${TEST_IMAGE}
|
||||||
before_script:
|
before_script:
|
||||||
- apk add -q bash rsync openssh-client
|
- 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:
|
.deploy_template_script:
|
||||||
# Configure SSH
|
# Configure SSH
|
||||||
- &deploy_template_script |-
|
- &deploy_template_script |-
|
||||||
|
@ -158,20 +191,9 @@ release-image-nginx:
|
||||||
rsync -vAax public/assets ${DOCROOT}/public/
|
rsync -vAax public/assets ${DOCROOT}/public/
|
||||||
cd "${DOCROOT}"
|
cd "${DOCROOT}"
|
||||||
|
|
||||||
build-release-file:
|
deploy:
|
||||||
<<: *deploy_definition
|
<<: *deploy_definition
|
||||||
stage: deploy
|
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:
|
environment:
|
||||||
name: staging
|
name: staging
|
||||||
only:
|
only:
|
||||||
|
@ -187,8 +209,84 @@ deploy-staging:
|
||||||
# Deploy to server
|
# Deploy to server
|
||||||
- ./bin/deploy.sh -r "${STAGING_REMOTE}" -p "${STAGING_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}"
|
- ./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-production:
|
||||||
<<: *deploy_definition
|
<<: *deploy_definition
|
||||||
|
stage: deploy-production
|
||||||
environment:
|
environment:
|
||||||
name: production
|
name: production
|
||||||
when: manual
|
when: manual
|
||||||
|
@ -204,3 +302,22 @@ deploy-production:
|
||||||
- *deploy_template_script
|
- *deploy_template_script
|
||||||
# Deploy to server
|
# Deploy to server
|
||||||
- ./bin/deploy.sh -r "${PRODUCTION_REMOTE}" -p "${PRODUCTION_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}"
|
- ./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
|
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
|
RUN mkdir -p /var/www/public/ && touch /var/www/public/index.php
|
||||||
COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf
|
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