diff --git a/.dockerignore b/.dockerignore index 12389ce613..87ac5d9034 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,6 +11,7 @@ /.travis.yml /AUTHORS /CONTRIBUTORS +/doc /Dockerfile /LICENSE /bin diff --git a/doc/infra/minikube.md b/doc/infra/minikube.md new file mode 100644 index 0000000000..5e4b745f88 --- /dev/null +++ b/doc/infra/minikube.md @@ -0,0 +1,52 @@ +# Deploy stack to minikube + +## Setup + +status : Alpha + + + +```bash +minikube start +minikube addons enable ingress +``` + +Get the minikube IP: + +```bash +minikube ip +``` + + +Refer to [sample.yaml](../infra/helm/sample.yaml) to get all domains. +Add these domains to your `/etc/hosts`: + +``` +# Alchemy Minikube +192.168.49.2 phraseanet-bo.alchemy.kube +# ... add other domains +``` + +For a quicker setup we will use the nginx configuration explained in [dev-with-nginx](./dev-with-nginx.md) + +## Build local image in minikube + +If you need to test your fresh image directly into minikube cluster, you need to build them +with the Mminikube Docker daemon: + +```bash +eval $(minikube docker-env) +docker-compose build +``` + +Alternatively you can run a registry in minikube and push your images: +https://minikube.sigs.k8s.io/docs/handbook/pushing/#4-pushing-to-an-in-cluster-using-registry-add + +If your minikube server name is not "minikube" define it in MINIKUBE_NAME + + +```bash +infra/dev/deploy-minikube.sh install +infra/dev/deploy-minikube.sh update +infra/dev/deploy-minikube.sh uninstall +``` \ No newline at end of file diff --git a/infra/dev/deploy-minikube.sh b/infra/dev/deploy-minikube.sh new file mode 100755 index 0000000000..c158a7eba5 --- /dev/null +++ b/infra/dev/deploy-minikube.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -ex + + +BASEDIR="$(dirname $0)" +DIR="${BASEDIR}" + +#MINIKUBE_NAME:${MINIKUBE_NAME:-"minikube"} + +NS=${NS:-"phraseanet"} +RELEASE_NAME="phraseanet" +CHART_DIR="infra/helm/all" +VALUE_SRC="infra/helm/myvalues.yaml" + +#kubectl config use-context $MINIKUBE_NAME + +case $1 in + uninstall) + helm uninstall ${RELEASE_NAME} || true; + ;; + validate) + helm install --dry-run --debug ${RELEASE_NAME} "${CHART_DIR}" \ + -f "${VALUE_SRC}" \ + --namespace $NS + ;; + update) + echo "Updating..." + helm upgrade ${RELEASE_NAME} "${CHART_DIR}" \ + -f "${VALUE_SRC}" \ + --namespace $NS + ;; + + *) + if [ ! -d "${CHART_DIR}/charts" ]; then + (cd "${CHART_DIR}" && helm dependency update) + fi + kubectl create ns $NS || true + helm uninstall ${RELEASE_NAME} --namespace $NS || true; + # kubectl -n $NS delete pvc elasticsearch-master-elasticsearch-master-0 || true + while [ $(kubectl -n $NS get pvc | wc -l) -gt 0 ] || [ $(kubectl -n $NS get pods | wc -l) -gt 0 ] + do + echo "Waiting for resources to be deleted..." + sleep 5 + done + echo "Installing release ${RELEASE_NAME} in namespace $NS..." + helm install ${RELEASE_NAME} "${CHART_DIR}" \ + -f "${VALUE_SRC}" \ + --namespace $NS + ;; +esac diff --git a/infra/helm/.helmignore b/infra/helm/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/infra/helm/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/infra/helm/README.md b/infra/helm/README.md new file mode 100644 index 0000000000..3f4cd74151 --- /dev/null +++ b/infra/helm/README.md @@ -0,0 +1,9 @@ +# Helm Chart + +## Deploy chart + +First you should write your own configuration file named `myvalues.yaml` (see [sample.yaml](./sample.yaml)) + +```bash +helm install -f myvalues.yaml phraseanet ./all +``` diff --git a/infra/helm/all/Chart.yaml b/infra/helm/all/Chart.yaml new file mode 100644 index 0000000000..73faa82209 --- /dev/null +++ b/infra/helm/all/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: phraseanet +description: Helm chart for Phraseanet + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: 4.0.0 diff --git a/infra/helm/all/templates/NOTES.txt b/infra/helm/all/templates/NOTES.txt new file mode 100644 index 0000000000..92d2d93cf1 --- /dev/null +++ b/infra/helm/all/templates/NOTES.txt @@ -0,0 +1 @@ +Phraseanet application. diff --git a/infra/helm/all/templates/database-service.yml b/infra/helm/all/templates/database-service.yml new file mode 100644 index 0000000000..792ce0d9a1 --- /dev/null +++ b/infra/helm/all/templates/database-service.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: db +spec: + ports: + - port: 3306 + targetPort: 3306 + selector: + app: phraseanet + tier: db + diff --git a/infra/helm/all/templates/database.yml b/infra/helm/all/templates/database.yml new file mode 100644 index 0000000000..5d8f389591 --- /dev/null +++ b/infra/helm/all/templates/database.yml @@ -0,0 +1,38 @@ + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-db +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: phraseanet + tier: db + template: + metadata: + labels: + app: phraseanet + tier: db + spec: + volumes: + - name: database + persistentVolumeClaim: + claimName: {{ .Values.mysql.pvc_name }} + containers: + - name: db + image: {{ .Values.image.registry }}/phraseanet-db:{{ .Values.image.tag.phraseanet }} + imagePullPolicy: Always + terminationMessagePolicy: FallbackToLogsOnError + resources: +{{ toYaml .Values.mysql.resources | indent 12 }} + env: + - name: MYSQL_ROOT_PASSWORD + value: {{ .Values.mysql.root_password }} + - name : MYSQL_MAX_ALLOWED_PACKET + value : {{ .Values.mysql.max_allowed_packet }} + volumeMounts: + - name: "database" + mountPath: "/var/lib/mysql" diff --git a/infra/helm/all/templates/elasticsearch-service.yml b/infra/helm/all/templates/elasticsearch-service.yml new file mode 100644 index 0000000000..2fa9304f79 --- /dev/null +++ b/infra/helm/all/templates/elasticsearch-service.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: elasticsearch +spec: + ports: + - name: + port: 9200 + targetPort: 9200 + selector: + app: phraseanet + tier: elasticsearch diff --git a/infra/helm/all/templates/elasticsearch.yml b/infra/helm/all/templates/elasticsearch.yml new file mode 100644 index 0000000000..b21a83c761 --- /dev/null +++ b/infra/helm/all/templates/elasticsearch.yml @@ -0,0 +1,33 @@ + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-elasticsearch +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: phraseanet + tier: elasticsearch + template: + metadata: + labels: + app: phraseanet + tier: elasticsearch + spec: + volumes: + - name: elastic-data + persistentVolumeClaim: + claimName: {{ .Values.elasticsearch.pvc_name }} + containers: + - name: elasticsearch + image: {{ .Values.image.registry }}/phraseanet-elasticsearch:{{ .Values.image.tag.phraseanet }} + imagePullPolicy: Always + terminationMessagePolicy: FallbackToLogsOnError + resources: +{{ toYaml .Values.elasticsearch.resources | indent 12 }} + volumeMounts: + - name: elastic-data + mountPath: "/usr/share/elasticsearch/data" diff --git a/infra/helm/all/templates/gateway-ingress.yml b/infra/helm/all/templates/gateway-ingress.yml new file mode 100644 index 0000000000..44404f052f --- /dev/null +++ b/infra/helm/all/templates/gateway-ingress.yml @@ -0,0 +1,25 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + labels: + app: phraseanet-gateway + name: phraseanet-gateway +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + rules: + - host: {{ .Values.ingress.host }} + http: + paths: + - backend: + serviceName: phraseanet-gateway + servicePort: 80 + path: / + {{- if .Values.ingress.tls }} + tls: +{{ toYaml .Values.ingress.tls | indent 4 }} + {{- end -}} +{{- end }} diff --git a/infra/helm/all/templates/gateway-service.yml b/infra/helm/all/templates/gateway-service.yml new file mode 100644 index 0000000000..d8db2edbb5 --- /dev/null +++ b/infra/helm/all/templates/gateway-service.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: phraseanet-gateway +spec: + ports: + - port: 80 + targetPort: 80 + selector: + app: phraseanet + tier: gateway + diff --git a/infra/helm/all/templates/gateway.yml b/infra/helm/all/templates/gateway.yml new file mode 100644 index 0000000000..96b762f9a0 --- /dev/null +++ b/infra/helm/all/templates/gateway.yml @@ -0,0 +1,57 @@ + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-gateway +spec: + replicas: 1 + selector: + matchLabels: + app: phraseanet + tier: gateway + template: + metadata: + labels: + app: phraseanet + tier: gateway + spec: + volumes: + - name: phraseanet-datas + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.data }} + - name: phraseanet-thumbnails + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.thumbnails }} + - name: phraseanet-custom + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.custom }} + - name: phraseanet-wwwplugins + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.wwwplugins }} + + containers: + - name: gateway + image: {{ .Values.image.registry }}/phraseanet-nginx:{{ .Values.image.tag.phraseanet }} + imagePullPolicy: Always + terminationMessagePolicy: FallbackToLogsOnError + resources: +{{ toYaml .Values.app.gateway.resources | indent 12 }} + volumeMounts: + - name: "phraseanet-datas" + mountPath: "/var/alchemy/Phraseanet/datas" + - name: "phraseanet-thumbnails" + mountPath: "/var/alchemy/Phraseanet/www/thumbnails" + - name: "phraseanet-custom" + mountPath: "/var/alchemy/Phraseanet/www/custom" + - name: phraseanet-wwwplugins + mountPath: "/var/alchemy/Phraseanet/www/plugins" + env: + - name: "MAX_BODY_SIZE" + value: {{ .Values.http.max_body_size }} + - name: "GATEWAY_SEND_TIMEOUT" + value : "600" + - name: GATEWAY_PROXY_TIMEOUT + value: "1200" + - name: GATEWAY_FASTCGI_TIMEOUT + value: "1200" + \ No newline at end of file diff --git a/infra/helm/all/templates/phraseanet-service.yml b/infra/helm/all/templates/phraseanet-service.yml new file mode 100644 index 0000000000..134349da6a --- /dev/null +++ b/infra/helm/all/templates/phraseanet-service.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: phraseanet +spec: + ports: + - port: 9000 + targetPort: 9000 + selector: + app: phraseanet + tier: fpm + diff --git a/infra/helm/all/templates/phraseanet.yml b/infra/helm/all/templates/phraseanet.yml new file mode 100644 index 0000000000..bbaebc20fb --- /dev/null +++ b/infra/helm/all/templates/phraseanet.yml @@ -0,0 +1,166 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-fpm +spec: + replicas: 1 + selector: + matchLabels: + app: phraseanet + tier: fpm + template: + metadata: + labels: + app: phraseanet + tier: fpm + spec: + volumes: + - name: phraseanet-config + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.config }} + - name: phraseanet-datas + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.data }} + - name: phraseanet-thumbnails + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.thumbnails }} + - name: phraseanet-custom + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.custom }} + - name: phraseanet-wwwplugins + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.wwwplugins }} + - name: phraseanet-tmp + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.tmp }} + - name: phraseanet-logs + emptyDir: + - name: phraseanet-cache + emptyDir: + + containers: + - name: phraseanet-fpm + image: {{ .Values.image.registry }}/phraseanet-fpm:{{ .Values.image.tag.phraseanet }} + imagePullPolicy: Always + terminationMessagePolicy: FallbackToLogsOnError + resources: +{{ toYaml .Values.app.web.resources | indent 12 }} + volumeMounts: + - name: phraseanet-config + mountPath: "/var/alchemy/Phraseanet/config" + - name: phraseanet-datas + mountPath: "/var/alchemy/Phraseanet/datas" + - name: phraseanet-tmp + mountPath: "/var/alchemy/Phraseanet/tmp" + - name: phraseanet-logs + mountPath: "/var/alchemy/Phraseanet/logs" + - name: phraseanet-thumbnails + mountPath: "/var/alchemy/Phraseanet/www/thumbnails" + - name: phraseanet-custom + mountPath: "/var/alchemy/Phraseanet/www/custom" + - name: phraseanet-wwwplugins + mountPath: "/var/alchemy/Phraseanet/www/plugins" + - name: phraseanet-cache + mountPath: "/var/alchemy/Phraseanet/cache" + + env: + - name: MAX_BODY_SIZE + value: {{ .Values.http.max_body_size | quote }} + - name: MAX_INPUT_VARS + value: {{ .Values.http.max_input_vars | quote }} + - name: MAX_EXECUTION_TIME + value: "600" + - name: MAX_INPUT_TIME + value: "60" + - name: GATEWAY_PROXY_TIMEOUT + value: "1200" + - name: GATEWAY_FASTCGI_TIMEOUT + value: "1200" + - name: REQUEST_TERMINATE_TIMEOUT + value: "1200s" + - name: OPCACHE_ENABLED + value: {{ .Values.php.opcache_enabled | quote }} + - name: PHP_LOG_LEVEL + value: {{ .Values.php.log_level | quote }} + - name: PHRASEANET_ADMIN_ACCOUNT_EMAIL + value: {{ .Values.app.phraseanet_admin_account_email | quote }} + - name: PHRASEANET_ADMIN_ACCOUNT_PASSWORD + value: {{ .Values.app.phraseanet_admin_account_password | quote }} + - name: PHRASEANET_DB_HOST + value: {{ .Values.app.phraseanet_db_host | quote }} + - name: PHRASEANET_DB_USER + value: {{ .Values.app.phraseanet_db_user | quote }} + - name: PHRASEANET_DB_PASSWORD + value: {{ .Values.app.phraseanet_db_password | quote }} + - name: INSTALL_DB_TEMPLATE + value: {{ .Values.app.install_db_template | quote }} + - name: INSTALL_APPBOX + value: {{ .Values.app.install_appbox | quote }} + - name: INSTALL_DATABOX + value: {{ .Values.app.install_databox | quote }} + - name: PHRASEANET_SERVER_NAME + value: {{ .Values.app.phraseanet_server_name | quote }} + - name: PHRASEANET_DOWNLOAD_DIR + value: "/var/alchemy/Phraseanet/datas/download" + - name: PHRASEANET_LAZARET_DIR + value: "/var/alchemy/Phraseanet/datas/lazaret" + - name: PHRASEANET_CAPTION_DIR + value: "/var/alchemy/Phraseanet/tmp/caption" + - name: PHRASEANET_FFMPEG_TIMEOUT + value: {{ .Values.app.phraseanet_ffmpeg_timeout | quote }} + - name: PHRASEANET_FFPROBE_TIMEOUT + value: {{ .Values.app.phraseanet_ffprobe_timeout | quote }} + - name: PHRASEANET_GS_TIMEOUT + value: {{ .Values.app.phraseanet_gs_timeout | quote }} + - name: PHRASEANET_MP4BOX_TIMEOUT + value: {{ .Values.app.phraseanet_mp4box_timeout | quote }} + - name: PHRASEANET_SWFTOOLS_TIMEOUT + value: {{ .Values.app.phraseanet_swftools_timeout | quote }} + - name: PHRASEANET_UNOCON_TIMEOUT + value: {{ .Values.app.phraseanet_unocon_timeout | quote }} + - name: PHRASEANET_EXIFTOOL_TIMEOUT + value: {{ .Values.app.phraseanet_exiftool_timeout | quote }} + - name: PHRASEANET_SMTP_ENABLED + value: {{ .Values.app.phraseanet_smtp_enabled | quote }} + - name: PHRASEANET_SMTP_AUTH_ENABLED + value: {{ .Values.app.phraseanet_smtp_auth_enabled | quote }} + - name: PHRASEANET_SMTP_SECURE_MODE + value: {{ .Values.app.phraseanet_smtp_secure_mode | quote }} + - name: PHRASEANET_SMTP_HOST + value: {{ .Values.app.phraseanet_smtp_host | quote }} + - name: PHRASEANET_SMTP_PORT + value: {{ .Values.app.phraseanet_smtp_port | quote }} + - name: PHRASEANET_SMTP_USER + value: {{ .Values.app.phraseanet_smtp_user | quote }} + - name: PHRASEANET_SMTP_PASSWORD + value: {{ .Values.app.phraseanet_smtp_password | quote }} + - name: PHRASEANET_EMITTER_EMAIL + value: {{ .Values.app.phraseanet_emitter_email | quote }} + - name: PHRASEANET_MAIL_OBJECT_PREFIX + value: {{ .Values.app.phraseanet_mail_object_prefix | quote }} + - name: PHRASEANET_RABBITMQ_USER + value: {{ .Values.rabbitmq.default_user | quote }} + - name: PHRASEANET_RABBITMQ_PASSWORD + value: {{ .Values.rabbitmq.default_pass | quote }} + - name: SESSION_CACHE_LIMITER + value: {{ .Values.php.session_cache_limiter | quote }} + - name: PHRASEANET_TRUSTED_PROXIES + value: {{ .Values.app.phraseanet_trusted_proxies | quote }} + - name: XDEBUG + value: "0" + - name: LC_MESSAGES + value: "C.UTF-8" + - name: LC_COLLATE + value: "C.UTF-8" + - name: LC_IDENTIFICATION + value: "C.UTF-8" + - name: LANG + value: "C.UTF-8" + - name: LC_MEASUREMENT + value: "C.UTF-8" + - name: LC_CTYPE + value: "C.UTF-8" + - name: LC_TIME + value: "C.UTF-8" + - name: LC_NAME + value: "C.UTF-8" diff --git a/infra/helm/all/templates/rabbitmq-service.yml b/infra/helm/all/templates/rabbitmq-service.yml new file mode 100644 index 0000000000..7e01fe5ec5 --- /dev/null +++ b/infra/helm/all/templates/rabbitmq-service.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: rabbitmq +spec: + ports: + - port: 5672 + targetPort: 5672 + selector: + app: phraseanet + tier: rabbitmq + diff --git a/infra/helm/all/templates/rabbitmq.yml b/infra/helm/all/templates/rabbitmq.yml new file mode 100644 index 0000000000..2878d69193 --- /dev/null +++ b/infra/helm/all/templates/rabbitmq.yml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-rabbitmq +spec: + replicas: 1 + selector: + matchLabels: + app: phraseanet + tier: rabbitmq + template: + metadata: + labels: + app: phraseanet + tier: rabbitmq + spec: + containers: + - name: rabbitmq + image: rabbitmq:3-management + terminationMessagePolicy: FallbackToLogsOnError + resources: +{{ toYaml .Values.rabbitmq.resources | indent 12 }} + env: + - name: RABBITMQ_DEFAULT_USER + value: {{ .Values.rabbitmq.default_user }} + - name: RABBITMQ_DEFAULT_PASS + value: {{ .Values.rabbitmq.default_pass }} diff --git a/infra/helm/all/templates/redis-service.yml b/infra/helm/all/templates/redis-service.yml new file mode 100644 index 0000000000..400bad250a --- /dev/null +++ b/infra/helm/all/templates/redis-service.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: redis +spec: + ports: + - port: 6379 + targetPort: 6379 + selector: + app: phraseanet + tier: redis + diff --git a/infra/helm/all/templates/redis.yml b/infra/helm/all/templates/redis.yml new file mode 100644 index 0000000000..5fa6ea73c1 --- /dev/null +++ b/infra/helm/all/templates/redis.yml @@ -0,0 +1,21 @@ + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-redis +spec: + replicas: 1 + selector: + matchLabels: + app: phraseanet + tier: redis + template: + metadata: + labels: + app: phraseanet + tier: redis + spec: + containers: + - name: redis + image: redis:5.0.5 + terminationMessagePolicy: FallbackToLogsOnError diff --git a/infra/helm/all/templates/worker.yml b/infra/helm/all/templates/worker.yml new file mode 100644 index 0000000000..c8dd892d4d --- /dev/null +++ b/infra/helm/all/templates/worker.yml @@ -0,0 +1,103 @@ +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phraseanet-worker +spec: + replicas: 1 + selector: + matchLabels: + app: phraseanet + tier: worker + template: + metadata: + labels: + app: phraseanet + tier: worker + spec: + volumes: + - name: phraseanet-config + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.config }} + - name: phraseanet-datas + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.data }} + - name: phraseanet-thumbnails + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.thumbnails }} + - name: phraseanet-custom + persistentVolumeClaim: + claimName: {{ .Values.app.pvc_name.custom }} + - name: phraseanet-tmp + emptyDir: + - name: phraseanet-logs + emptyDir: + - name: phraseanet-cache + emptyDir: + + containers: + - name: phraseanet-worker + image: {{ .Values.image.registry }}/phraseanet-worker:{{ .Values.image.tag.phraseanet }} + imagePullPolicy: Always + terminationMessagePolicy: FallbackToLogsOnError + resources: +{{ toYaml .Values.app.worker.resources | indent 12 }} + volumeMounts: + - name: phraseanet-config + mountPath: "/var/alchemy/Phraseanet/config" + - name: phraseanet-datas + mountPath: "/var/alchemy/Phraseanet/datas" + - name: phraseanet-tmp + mountPath: "/var/alchemy/Phraseanet/tmp" + - name: phraseanet-logs + mountPath: "/var/alchemy/Phraseanet/logs" + - name: phraseanet-thumbnails + mountPath: "/var/alchemy/Phraseanet/www/thumbnails" + - name: phraseanet-custom + mountPath: "/var/alchemy/Phraseanet/www/custom" + - name: phraseanet-cache + mountPath: "/var/alchemy/Phraseanet/cache" + env: + - name: MAX_BODY_SIZE + value: {{ .Values.http.max_body_size | quote }} + - name: MAX_INPUT_VARS + value: {{ .Values.http.max_input_vars | quote }} + - name: OPCACHE_ENABLED + value: {{ .Values.php.opcache_enabled | quote }} + - name: PHP_LOG_LEVEL + value: {{ .Values.php.log_level | quote }} + - name: SESSION_CACHE_LIMITER + value: {{ .Values.php.session_cache_limiter | quote }} + - name: XDEBUG + value: "0" + - name: LC_MESSAGES + value: "C.UTF-8" + - name: LC_COLLATE + value: "C.UTF-8" + - name: LC_IDENTIFICATION + value: "C.UTF-8" + - name: LANG + value: "C.UTF-8" + - name: LC_MEASUREMENT + value: "C.UTF-8" + - name: LC_CTYPE + value: "C.UTF-8" + - name: LC_TIME + value: "C.UTF-8" + - name: LC_NAME + value: "C.UTF-8" + initContainers: + - name: create-tmp-locks + image: {{ .Values.image.registry }}/phraseanet-worker:{{ .Values.image.tag.phraseanet }} + volumeMounts: + - name: phraseanet-tmp + mountPath: "/var/alchemy/Phraseanet/tmp" + command: ['mkdir', '-p', '/var/alchemy/Phraseanet/tmp/locks'] + - name: chown-phraseanet-tmp + image: {{ .Values.image.registry }}/phraseanet-worker:{{ .Values.image.tag.phraseanet }} + volumeMounts: + - name: phraseanet-tmp + mountPath: "/var/alchemy/Phraseanet/tmp" + command: ['chown', '-R', 'app:app', '/var/alchemy/Phraseanet/tmp'] + diff --git a/infra/helm/all/values.yaml b/infra/helm/all/values.yaml new file mode 100644 index 0000000000..c99dccba35 --- /dev/null +++ b/infra/helm/all/values.yaml @@ -0,0 +1,96 @@ + +image: + registry: + tag: + phraseanet: master + database : master + elasticsearch : master + +mysql: + root_password: + max_allowed_packet: 16M + pvc_name: phraseanet-database + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + +elasticsearch: + pvc_name: phraseanet-elasticsearch + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + +rabbitmq: + default_user: rabbit + default_pass: + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + +http: + max_body_size: 2G + max_input_vars: 12000 + +php: + opcache_enabled: 1 + log_level: warning + session_cache_limiter: off + +ingress: + enabled: false + +app: + hostname: localhost + phraseanet_admin_account_email: support@alchemy.fr + phraseaenet_admin_account_password: phraseanet + phraseanet_db_host: db + phraseanet_db_user: root + phraseanet_db_password: root + install_db_template: DublinCore + install_appbox: ab_master + install_databox: db_databox1 + phraseanet_server_name: localhost + phraseanet_trusted_proxies: + gateway: + resources: + requests: + cpu: "50m" + memory: "32Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + web: + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + worker: + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + pvc_name: + data: phraseanet-datas + thumbnails: phraseanet-thumbnails + custom: phraseanet-custom + config: phraseanet-config + wwwplugins: phraseanet-wwwplugins + tmp: phraseanet-tmp diff --git a/infra/helm/myvalues.yaml b/infra/helm/myvalues.yaml new file mode 100644 index 0000000000..4a715a2160 --- /dev/null +++ b/infra/helm/myvalues.yaml @@ -0,0 +1,96 @@ + +image: + registry: alchemyfr + tag: + phraseanet: master + database : master + elasticsearch : master + +mysql: + root_password: + max_allowed_packet: 16M + pvc_name: phraseanet-database + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + +elasticsearch: + pvc_name: phraseanet-elasticsearch + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + +rabbitmq: + default_user: rabbit + default_pass: + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + +http: + max_body_size: 2G + max_input_vars: 12000 + +php: + opcache_enabled: 1 + log_level: warning + session_cache_limiter: off + +ingress: + enabled: false + +app: + hostname: localhost + phraseanet_admin_account_email: support@alchemy.fr + phraseaenet_admin_account_password: phraseanet + phraseanet_db_host: db + phraseanet_db_user: root + phraseanet_db_password: root + install_db_template: DublinCore + install_appbox: ab_master + install_databox: db_databox1 + phraseanet_server_name: localhost + phraseanet_trusted_proxies: + gateway: + resources: + requests: + cpu: "50m" + memory: "32Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + web: + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + worker: + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + pvc_name: + data: phraseanet-datas + thumbnails: phraseanet-thumbnails + custom: phraseanet-custom + config: phraseanet-config + wwwplugins: phraseanet-wwwplugins + tmp: phraseanet-tmp diff --git a/infra/ssl/create-root-ca.sh b/infra/ssl/create-root-ca.sh new file mode 100755 index 0000000000..bc2592a61e --- /dev/null +++ b/infra/ssl/create-root-ca.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +mkdir -p ~/ssl/ +openssl genrsa -des3 -out ~/ssl/AlchemyRootCA.key 2048 +openssl req -x509 -new -nodes -key ~/ssl/AlchemyRootCA.key -sha256 -days 1825 \ + -subj "/C=FR/ST=France/O=Alchemy, Inc./CN=Alchemy" \ + -out ~/ssl/AlchemyRootCA.pem + +echo "Done." diff --git a/infra/ssl/create-self-signed-certificate.sh b/infra/ssl/create-self-signed-certificate.sh new file mode 100755 index 0000000000..83171cc93d --- /dev/null +++ b/infra/ssl/create-self-signed-certificate.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +DOMAIN=${1:-"alchemy.local"} + +PROJECT_DIR="$( cd "$(dirname "$0")" && pwd )" +SSL_DIR="/etc/nginx/ssl/${DOMAIN}" + +sudo mkdir -p $SSL_DIR + +sudo openssl req -new -sha256 -nodes -out $SSL_DIR/${DOMAIN}.csr -newkey rsa:2048 -keyout $SSL_DIR/${DOMAIN}.key \ + -config $PROJECT_DIR/server.csr.${DOMAIN}.cnf + +sudo openssl x509 -req -in $SSL_DIR/${DOMAIN}.csr -CA ~/ssl/AlchemyRootCA.pem -CAkey ~/ssl/AlchemyRootCA.key -CAcreateserial \ + -out $SSL_DIR/${DOMAIN}.crt -days 1825 -sha256 -extfile $PROJECT_DIR/v3.${DOMAIN}.ext + +sudo rm $SSL_DIR/${DOMAIN}.csr + +echo "Done." diff --git a/infra/ssl/server.csr.alchemy.kube.cnf b/infra/ssl/server.csr.alchemy.kube.cnf new file mode 100644 index 0000000000..387e508d85 --- /dev/null +++ b/infra/ssl/server.csr.alchemy.kube.cnf @@ -0,0 +1,14 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn + +[dn] +C=FR +ST=France +L=Paris +O=Alchemy +OU=Alchemy +emailAddress=contact@alchemy.fr +CN = *.alchemy.kube diff --git a/infra/ssl/server.csr.alchemy.local.cnf b/infra/ssl/server.csr.alchemy.local.cnf new file mode 100644 index 0000000000..e3ea24850b --- /dev/null +++ b/infra/ssl/server.csr.alchemy.local.cnf @@ -0,0 +1,14 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn + +[dn] +C=FR +ST=France +L=Paris +O=Alchemy +OU=Alchemy +emailAddress=contact@alchemy.fr +CN = *.alchemy.local diff --git a/infra/ssl/v3.alchemy.kube.ext b/infra/ssl/v3.alchemy.kube.ext new file mode 100644 index 0000000000..28c4b28e5e --- /dev/null +++ b/infra/ssl/v3.alchemy.kube.ext @@ -0,0 +1,7 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = *.alchemy.kube diff --git a/infra/ssl/v3.alchemy.local.ext b/infra/ssl/v3.alchemy.local.ext new file mode 100644 index 0000000000..387301b0c1 --- /dev/null +++ b/infra/ssl/v3.alchemy.local.ext @@ -0,0 +1,7 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = *.alchemy.local