diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index fac5ce7..0000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -.git -*.md diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 219a6c1..332ec40 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,20 +5,7 @@ include: - project: 'ldc-web/shared-ci' ref: 'main' file: 'security/security.yml' - - project: 'ldc-web/shared-ci' - ref: 'main' - file: 'build/build.yml' - - project: 'ldc-web/shared-ci' - ref: 'main' - file: 'test/test.yml' - - project: 'ldc-web/shared-ci' - ref: 'main' - file: 'deploy/deploy.yml' - stages: - lint - security - - build - - test - - deploy diff --git a/deployment/.dockerignore b/deployment/.dockerignore new file mode 100644 index 0000000..94359d9 --- /dev/null +++ b/deployment/.dockerignore @@ -0,0 +1,6 @@ +**/.git/ +**/.gitlab-ci.yml +**/*.md +**/node_modules/ +**/auth.json +**/.vscode/ \ No newline at end of file diff --git a/deployment/.gitlab-ci.yml b/deployment/.gitlab-ci.yml new file mode 100644 index 0000000..8a7d172 --- /dev/null +++ b/deployment/.gitlab-ci.yml @@ -0,0 +1,163 @@ +repo-build: + stage: build + image: $CI_REGISTRY/ldc-web/projets/ldc-web-images-docker/ldcweb-qa-8.2:latest + before_script: + - git clone https://gitlab-ci-token:${GGW_TOKEN}@lab.s-web.fr/ldc-web/projets/gen-game-web.git ggw --branch $APP_GGW_TAG --single-branch + - cd ggw + script: + - git clone https://gitlab-ci-token:${GGW_THEME_TOKEN}@lab.s-web.fr/ldc-web/projets/gen-game-web-themes/${APP_THEME_PATH}.git resources/theme/mounted --branch main --single-branch + cache: + paths: + - ggw + artifacts: + expose_as: 'ggw' + paths: + - ggw/ + allow_failure: false + rules: + - if: $CI_COMMIT_BRANCH == "trunk" || $CI_COMMIT_BRANCH == "master" + +composer-build: + stage: build + image: $CI_REGISTRY/ldc-web/projets/ldc-web-images-docker/ldcweb-qa-8.2:latest + before_script: + - cd ggw + - composer config gitlab-token.lab.s-web.fr $CI_DEPLOY_USER $CI_DEPLOY_PASSWORD + cache: + paths: + - ggw + script: + - composer install --no-dev --optimize-autoloader --classmap-authoritative --no-scripts + artifacts: + expose_as: 'vendor' + paths: + - ggw/ + allow_failure: false + dependencies: + - repo-build + needs: + - job: repo-build + optional: true + rules: + - if: $CI_COMMIT_BRANCH == "trunk" || $CI_COMMIT_BRANCH == "master" + +npm-build: + stage: build + image: $CI_REGISTRY/ldc-web/projets/ldc-web-images-docker/ldcweb-qa-8.2:latest + before_script: + - cd ggw + - npm config set @ldc-web:registry https://${CI_SERVER_HOST}/api/v4/packages/npm/ + - npm config set -- '//${CI_SERVER_HOST}/api/v4/packages/npm/:_authToken' "${CI_DEPLOY_PASSWORD}" + - npm install + cache: + paths: + - ggw + script: + - npm run prod + artifacts: + expose_as: 'front-build' + paths: + - ggw/ + allow_failure: false + dependencies: + - composer-build + needs: + - job: composer-build + optional: true + rules: + - if: $CI_COMMIT_BRANCH == "trunk" || $CI_COMMIT_BRANCH == "master" + +.docker-build: + stage: build + image: + name: gcr.io/kaniko-project/executor:v1.9.1-debug + entrypoint: [""] + script: + - /kaniko/executor + --context "${CI_PROJECT_DIR}" + --dockerfile "${CI_PROJECT_DIR}/Dockerfile" + --destination "${IMAGE_TAG}" + allow_failure: false + dependencies: + - npm-build + - composer-build + needs: + - job: npm-build + optional: true + - job: composer-build + optional: true + +docker-build:staging: + extends: .docker-build + variables: + IMAGE_TAG: "${CI_REGISTRY_IMAGE}:s-${CI_PIPELINE_IID}" + rules: + - if: $CI_COMMIT_BRANCH == "trunk" + + +docker-build:production: + extends: .docker-build + variables: + IMAGE_TAG: "${CI_REGISTRY_IMAGE}:p-${CI_PIPELINE_IID}" + rules: + - if: $CI_COMMIT_BRANCH == "master" + +.kubernetes: + stage: deploy + image: + name: alpine/k8s:1.26.0 + entrypoint: [''] + variables: + KUBE_CONTEXT: ldc-web/cluster-k8s:k8s-ldc-web + KUBE_NAMESPACE: default + before_script: + - kubectl config use-context ${KUBE_CONTEXT} + script: + - envsubst < manifest.yaml | kubectl apply --namespace ${KUBE_NAMESPACE} -f - + +.kubernetes_stop: + extends: .kubernetes + script: + - envsubst < manifest.yaml | kubectl delete --namespace ${KUBE_NAMESPACE} -f - + when: manual + environment: + action: stop + +kubernetes:staging: + extends: .kubernetes + variables: + KUBE_NAMESPACE: staging + IMAGE_TAG: "${CI_REGISTRY_IMAGE}:s-${CI_PIPELINE_IID}" + rules: + - if: $CI_COMMIT_BRANCH == "trunk" + when: manual + environment: + name: staging + url: https://${DOMAIN} + on_stop: kubernetes_stop:staging + +kubernetes_stop:staging: + extends: .kubernetes_stop + variables: + KUBE_NAMESPACE: staging + rules: + - if: $CI_COMMIT_BRANCH == "trunk" + environment: + name: staging + + +kubernetes:prod: + extends: .kubernetes + variables: + KUBE_NAMESPACE: production + IMAGE_TAG: "${CI_REGISTRY_IMAGE}:p-${CI_PIPELINE_IID}" + rules: + - if: $CI_COMMIT_BRANCH == "master" + when: manual + environment: + name: production + url: https://${APP_DOMAIN} + +stages: + - build + - deploy diff --git a/deployment/Dockerfile b/deployment/Dockerfile new file mode 100644 index 0000000..6f34685 --- /dev/null +++ b/deployment/Dockerfile @@ -0,0 +1,5 @@ +FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest +COPY --chown=www-data:www-data ./ggw /app/srcs +USER root +RUN chmod -R 755 /app/srcs/storage +USER www-data \ No newline at end of file diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 0000000..8a25c6b --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,4 @@ +# Gen Game Web Instance Deployment + +## TODO +- Compléter ce fichier \ No newline at end of file diff --git a/deployment/manifest.yaml b/deployment/manifest.yaml new file mode 100644 index 0000000..8434cca --- /dev/null +++ b/deployment/manifest.yaml @@ -0,0 +1,232 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ggw-${CI_PROJECT_NAME}-config-map +data: + APP_NAME: "${APP_APP_NAME}" + APP_ENV: "${APP_APP_ENV}" + APP_KEY: "${APP_APP_KEY}" + APP_DEBUG: "${APP_APP_DEBUG}" + APP_URL: "https://${APP_DOMAIN}" + ASSET_URL: "https://${APP_DOMAIN}" + LOG_CHANNEL: "k8s" + DB_HOST: "mariadb-service.common-services" + DB_DATABASE: "${APP_DB_DATABASE}" + DB_USERNAME: "${APP_DB_USERNAME}" + DB_PASSWORD: "${APP_DB_PASSWORD}" + QUEUE_CONNECTION: "${APP_QUEUE_CONNECTION}" + MAIL_HOST: "${APP_MAIL_HOST}" + MAIL_PORT: "${APP_MAIL_PORT}" + MAIL_USERNAME: "${APP_MAIL_USERNAME}" + MAIL_PASSWORD: "${APP_MAIL_PASSWORD}" + MAIL_ENCRYPTION: "${APP_MAIL_ENCRYPTION}" + MAIL_FROM_ADDRESS: "${APP_MAIL_FROM_ADDRESS}" + MAIL_FROM_NAME: "${APP_APP_NAME}" + SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}" + CRM_ENDPOINT: "${APP_CRM_ENDPOINT}" + CRM_TOKEN: "${APP_CRM_TOKEN}" + CRM_PASSWORD: "${APP_CRM_PASSWORD}" + MESBR_ENDPOINT: "${APP_MESBR_ENDPOINT}" + CODE_PAGINATE: "${APP_CODE_PAGINATE}" + CODE_CHAR_LIST: "${APP_CODE_CHAR_LIST}" + CODE_CHAR_LENGTH: "${APP_CODE_CHAR_LENGTH}" + +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ggw-${CI_PROJECT_NAME}-pvc-storage +spec: + storageClassName: "csi-cinder-classic" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: $APP_PVC_SIZE + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ggw-${CI_PROJECT_NAME}-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: ggw-${CI_PROJECT_NAME}-app + template: + metadata: + labels: + app: ggw-${CI_PROJECT_NAME}-app + spec: + containers: + - name: ggw-${CI_PROJECT_NAME}-container + image: $IMAGE_TAG + envFrom: + - configMapRef: + name: ggw-${CI_PROJECT_NAME}-config-map + volumeMounts: + - name: storage + mountPath: /app/srcs/storage + imagePullSecrets: + - name: docker-registry-credentials + securityContext: + runAsUser: 33 + runAsGroup: 33 + fsGroup: 33 + fsGroupChangePolicy: "OnRootMismatch" + volumes: + - name: storage + persistentVolumeClaim: + claimName: ggw-${CI_PROJECT_NAME}-pvc-storage + + +--- +apiVersion: v1 +kind: Service +metadata: + name: ggw-${CI_PROJECT_NAME}-service +spec: + selector: + app: ggw-${CI_PROJECT_NAME}-app + ports: + - port: 80 + targetPort: 443 + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: ggw-${CI_PROJECT_NAME}-ingress-route +spec: + entryPoints: + - web + - websecure + routes: + - match: Host(`${APP_DOMAIN}`) + kind: Rule + services: + - name: ggw-${CI_PROJECT_NAME}-service + port: 80 + tls: + secretName: $APP_DOMAIN + +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: $APP_DOMAIN +spec: + dnsNames: + - $APP_DOMAIN + secretName: $APP_DOMAIN + issuerRef: + name: $APP_CERT_ISSUER + kind: ClusterIssuer + +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: ggw-${CI_PROJECT_NAME}-cronjob +spec: + schedule: "* * * * *" + jobTemplate: + spec: + template: + spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - ggw-${CI_PROJECT_NAME}-app + topologyKey: "kubernetes.io/hostname" + namespaces: [$KUBE_NAMESPACE] + containers: + - name: ggw-${CI_PROJECT_NAME}-scheduled + image: $IMAGE_TAG + imagePullPolicy: IfNotPresent + command: + - "php" + args: + - "artisan" + - "schedule:run" + envFrom: + - configMapRef: + name: ggw-${CI_PROJECT_NAME}-config-map + volumeMounts: + - name: storage + mountPath: /app/srcs/storage + imagePullSecrets: + - name: docker-registry-credentials + volumes: + - name: storage + persistentVolumeClaim: + claimName: ggw-${CI_PROJECT_NAME}-pvc-storage + securityContext: + runAsUser: 33 + runAsGroup: 33 + fsGroup: 33 + fsGroupChangePolicy: "OnRootMismatch" + restartPolicy: OnFailure + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ggw-${CI_PROJECT_NAME}-deployment-queue +spec: + replicas: 1 + selector: + matchLabels: + app: ggw-${CI_PROJECT_NAME}-app-queue + template: + metadata: + labels: + app: ggw-${CI_PROJECT_NAME}-app-queue + spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - ggw-${CI_PROJECT_NAME}-app + topologyKey: "kubernetes.io/hostname" + namespaces: [$KUBE_NAMESPACE] + containers: + - name: ggw-${CI_PROJECT_NAME}-container-queue + image: "registry.s-web.fr/ldc-web/projets/op-insta:latest" + command: + - php + args: + - artisan + - queue:work + - --max-jobs=200 + - --sleep=3 + - --tries=3 + imagePullPolicy: IfNotPresent + envFrom: + - configMapRef: + name: ggw-${CI_PROJECT_NAME}-config-map + volumeMounts: + - name: storage + mountPath: /app/srcs/storage + imagePullSecrets: + - name: docker-registry-credentials + volumes: + - name: storage + persistentVolumeClaim: + claimName: ggw-${CI_PROJECT_NAME}-pvc-storage + securityContext: + runAsUser: 33 + runAsGroup: 33 + fsGroup: 33 + fsGroupChangePolicy: "OnRootMismatch" \ No newline at end of file