diff --git a/.github/workflows/chart-preview.yml b/.github/workflows/chart-preview.yml new file mode 100644 index 0000000..b6de0c3 --- /dev/null +++ b/.github/workflows/chart-preview.yml @@ -0,0 +1,129 @@ +name: Helm Preview Build + +on: + workflow_dispatch: + inputs: + plane-ce: + description: "Plane CE" + required: false + default: false + type: boolean + plane-enterprise: + description: "Plane Enterprise" + required: false + default: false + type: boolean + +env: + PREVIEW_BUILD_FOLDER: helm-preview + AWS_ACCESS_KEY_ID: ${{ secrets.HELM_PREVIEW_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.HELM_PREVIEW_AWS_SECRET_ACCESS_KEY }} + AWS_REGION: ${{ vars.HELM_PREVIEW_AWS_REGION }} + AWS_BUCKET: ${{ vars.HELM_PREVIEW_BUCKET }} + HELM_SUB_FOLDER: ${{ github.run_id }} + CHART_PREFIX: ${{ github.run_id }} + BUILD_PLANE_CE: ${{ github.event.inputs.plane-ce }} + BUILD_PLANE_EE: ${{ github.event.inputs.plane-enterprise }} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Source + uses: actions/checkout@v4 + with: + path: code + + - name: Configure Git + working-directory: code + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + mkdir -p helm-preview + + - name: Set up Helm + uses: azure/setup-helm@v4 + + - name: Prepare GPG key #this step is for using exported keys and make your github runner + working-directory: code + run: | + gpg_dir=.cr-gpg + mkdir "$gpg_dir" + keyring="$gpg_dir/secring.gpg" #referring keyring to private key of gpg + base64 -d <<< "$GPG_KEYRING_BASE64" > "$keyring" #storing base64 GPG key into keyring + passphrase_file="$gpg_dir/passphrase" + echo "$GPG_PASSPHRASE" > "$passphrase_file" #storing passphrase data into a file + echo "CR_PASSPHRASE_FILE=$passphrase_file" >> "$GITHUB_ENV" #saving passphrase into github-environment + echo "CR_KEYRING=$keyring" >> "$GITHUB_ENV" #saving private key into github-environemnt + env: + GPG_KEYRING_BASE64: "${{ secrets.GPG_KEYRING_BASE64 }}" #Referring secrets of github above + GPG_PASSPHRASE: "${{ secrets.GPG_PASSPHRASE }}" + + - id: build-plane-ce + if: ${{ env.BUILD_PLANE_CE == 'true' }} + name: Build Plane-CE + working-directory: code + env: + EXPORT_DIR: ${{env.PREVIEW_BUILD_FOLDER}} + CHART_REPO: plane-ce + run: | + flatBranchName=$(echo "${{ github.ref_name}}" | sed 's/\//\-/g') + sed -i "s/name: ${{env.CHART_REPO}}/name: ${{ env.CHART_PREFIX }}-${{env.CHART_REPO}}/" charts/${{env.CHART_REPO}}/Chart.yaml + sed -i "s/description: .*/description: ${flatBranchName}/g" charts/${{env.CHART_REPO}}/Chart.yaml + sed -i "s/version: \(.*\)/version: \1-${flatBranchName}/" charts/${{env.CHART_REPO}}/Chart.yaml + + helm package --sign --key "Plane" --keyring $CR_KEYRING --passphrase-file "$CR_PASSPHRASE_FILE" charts/$CHART_REPO -u -d ${{ env.EXPORT_DIR }}/${{env.CHART_REPO}}/charts + cp charts/${{env.CHART_REPO}}/README.md ${{ env.EXPORT_DIR }}/${{env.CHART_REPO}}/${{env.CHART_REPO}}.md + helm repo index ${{ env.EXPORT_DIR }}/${{env.CHART_REPO}} + + - id: build-plane-enterprise + if: ${{ env.BUILD_PLANE_EE == 'true' }} + name: Build Plane-Enterprise + working-directory: code + env: + EXPORT_DIR: ${{env.PREVIEW_BUILD_FOLDER}} + CHART_REPO: plane-enterprise + run: | + flatBranchName=$(echo "${{ github.ref_name}}" | sed 's/\//\-/g') + sed -i "s/name: ${{env.CHART_REPO}}/name: ${{ env.CHART_PREFIX }}-${{env.CHART_REPO}}/" charts/${{env.CHART_REPO}}/Chart.yaml + sed -i "s/description: .*/description: ${flatBranchName}/g" charts/${{env.CHART_REPO}}/Chart.yaml + sed -i "s/version: \(.*\)/version: \1-${flatBranchName}/" charts/${{env.CHART_REPO}}/Chart.yaml + + helm package --sign --key "Plane" --keyring $CR_KEYRING --passphrase-file "$CR_PASSPHRASE_FILE" charts/$CHART_REPO -u -d ${{ env.EXPORT_DIR }}/${{env.CHART_REPO}}/charts + cp charts/${{env.CHART_REPO}}/README.md ${{ env.EXPORT_DIR }}/${{env.CHART_REPO}}/${{env.CHART_REPO}}.md + helm repo index ${{ env.EXPORT_DIR }}/${{env.CHART_REPO}} + + + - name: Publish + if: ${{ env.BUILD_PLANE_CE == 'true' || env.BUILD_PLANE_EE == 'true' }} + working-directory: code + run: | + + # helm repo index ${{env.PREVIEW_BUILD_FOLDER}} + touch ${{env.PREVIEW_BUILD_FOLDER}}/index.html + # echo "

Helm Preview Build for Branch:${{github.ref_name}}

" > ${{env.PREVIEW_BUILD_FOLDER}}/index.html + HTML_CONTENT=" +

Helm Preview Build for Branch:${{github.ref_name}}

+ " + echo $HTML_CONTENT >> ${{env.PREVIEW_BUILD_FOLDER}}/index.html + + pip install awscli + aws s3 cp ${{env.PREVIEW_BUILD_FOLDER}} s3://${{env.AWS_BUCKET}}/${{ env.HELM_SUB_FOLDER }} --recursive + + echo "************************************************" + echo "http://${{env.AWS_BUCKET}}.s3-website.${{env.AWS_REGION}}.amazonaws.com/${{env.HELM_SUB_FOLDER}}" + echo "************************************************" + diff --git a/.github/workflows/chart-releaser.yml b/.github/workflows/chart-releaser.yml new file mode 100644 index 0000000..185154c --- /dev/null +++ b/.github/workflows/chart-releaser.yml @@ -0,0 +1,67 @@ +name: Chart Release + +on: + workflow_dispatch: + push: + branches: + - master + +env: + CR_CONFIGFILE: "${{ github.workspace }}/cr.yaml" + CR_TOOL_PATH: "${{ github.workspace }}/.cr-tool" + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + TARGET_BRANCH: "${{ github.ref_name }}" + +jobs: + setup: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Install Helm + uses: azure/setup-helm@v4 + + - name: Prepare GPG key #this step is for using exported keys and make your github runner + run: | + gpg_dir=.cr-gpg + mkdir "$gpg_dir" + keyring="$gpg_dir/secring.gpg" #referring keyring to private key of gpg + base64 -d <<< "$GPG_KEYRING_BASE64" > "$keyring" #storing base64 GPG key into keyring + passphrase_file="$gpg_dir/passphrase" + echo "$GPG_PASSPHRASE" > "$passphrase_file" #storing passphrase data into a file + echo "CR_PASSPHRASE_FILE=$passphrase_file" >> "$GITHUB_ENV" #saving passphrase into github-environment + echo "CR_KEYRING=$keyring" >> "$GITHUB_ENV" #saving private key into github-environemnt + env: + GPG_KEYRING_BASE64: "${{ secrets.GPG_KEYRING_BASE64 }}" #Referring secrets of github above + GPG_PASSPHRASE: "${{ secrets.GPG_PASSPHRASE }}" + + - name: Rename Chart + if: github.ref_name != 'master' + run: | + flatBranchName=$(echo "${{ env.TARGET_BRANCH }}" | sed 's/\//\-/g') + sed -i "s/name: \(.*\)/name: \1-${flatBranchName}/" charts/plane-ce/Chart.yaml + sed -i "s/name: \(.*\)/name: \1-${flatBranchName}/" charts/plane-enterprise/Chart.yaml + + - name: Release Charts + uses: helm/chart-releaser-action@v1.6.0 + with: + charts_dir: charts + config: cr.yaml + packages_with_index: false + skip_existing: true + env: + CR_TOKEN: ${{ env.CR_TOKEN }} + CR_KEY: "Plane" + CR_KEYRING: ${{ env.CR_KEYRING }} + CR_PASSPHRASE_FILE: ${{ env.CR_PASSPHRASE_FILE }} + CR_SIGN: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a4745c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +dist/ +test-helm.yaml +.DS_Store +*/local-values.yaml +test.yaml +test-*.yaml diff --git a/artifacthub-repo.yml b/artifacthub-repo.yml new file mode 100644 index 0000000..db1fca9 --- /dev/null +++ b/artifacthub-repo.yml @@ -0,0 +1,16 @@ +# Artifact Hub repository metadata file +# +# Some settings like the verified publisher flag or the ignored packages won't +# be applied until the next time the repository is processed. Please keep in +# mind that the repository won't be processed if it has not changed since the +# last time it was processed. Depending on the repository kind, this is checked +# in a different way. For Helm http based repositories, we consider it has +# changed if the `index.yaml` file changes. For git based repositories, it does +# when the hash of the last commit in the branch you set up changes. This does +# NOT apply to ownership claim operations, which are processed immediately. +# +repositoryID: 1f012931-5011-4f86-bd8e-c0ef4f819ace + +ignore: + - name: plane-ce + version: develop diff --git a/charts/plane-ce/.helmignore b/charts/plane-ce/.helmignore new file mode 100644 index 0000000..2d4a744 --- /dev/null +++ b/charts/plane-ce/.helmignore @@ -0,0 +1,24 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +test-*.yaml \ No newline at end of file diff --git a/charts/plane-ce/Chart.lock b/charts/plane-ce/Chart.lock new file mode 100644 index 0000000..e69de29 diff --git a/charts/plane-ce/Chart.yaml b/charts/plane-ce/Chart.yaml new file mode 100644 index 0000000..3ccdcf7 --- /dev/null +++ b/charts/plane-ce/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 + +name: plane-ce +description: Meet Plane. An open-source software development tool to manage issues, sprints, and product roadmaps with peace of mind. + +type: application + +version: 1.0.18 +appVersion: "0.20.0" + +home: https://plane.so +icon: https://plane.so/favicon/favicon-32x32.png +sources: + - https://github.com/makeplane/plane + +annotations: + artifacthub.io/license: AGPL-3.0 diff --git a/charts/plane-ce/README.md b/charts/plane-ce/README.md new file mode 100644 index 0000000..0d369ab --- /dev/null +++ b/charts/plane-ce/README.md @@ -0,0 +1,218 @@ +## Pre-requisite +- A working Kubernetes cluster +- `kubectl` and `helm` on the client system that you will use to install our Helm charts + +## Installing Plane + +1. Open Terminal or any other command-line app that has access to Kubernetes tools on your local system. +2. Add Helm Repo + ```bash + helm repo add makeplane https://helm.plane.so/ + ``` +3. Set-up and customization
+ - Quick set-up
+ This is the fastest way to deploy Plane with default settings. This will create stateful deployments for Postgres, Redis, and Minio with a persistent volume claim using the `longhorn` storage class. This also sets up the ingress routes for you using `nginx` ingress class. + > To customize this, see `Custom ingress routes` below. + + Continue to be on the same Terminal window as you have so far, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install plane-app makeplane/plane-ce \ + --create-namespace \ + --namespace plane-ce \ + --set planeVersion=stable \ + --set ingress.appHost="plane.example.com" \ + --set ingress.minioHost="plane-minio.example.com" \ + --set ingress.ingressClass=nginx \ + --set postgres.storageClass=longhorn \ + --set redis.storageClass=longhorn \ + --set minio.storageClass=longhorn \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + + > This is the minimum required to set up Plane-CE. You can change the default namespace from `plane-ce`, the default appname + from `plane-app`, the default storage class from `[postgres, redis, minio].storageClass`, and the default ingress class from `ingress.ingressClass` to + whatever you would like to.

+ You can also pass other settings referring to `Configuration Settings` section. + + - Advance set-up
+ For more control over your set-up, run the script below to download the `values.yaml` file and and edit using any editor like Vim or Nano. + + ```bash + helm show values makeplane/plane-ce > values.yaml + vi values.yaml + ``` + > See `Available customizations` for more details. + + After saving the `values.yaml` file, continue to be on the same Terminal window as on the previous steps, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install plane-app makeplane/plane-ce \ + --create-namespace \ + --namespace plane-ce \ + -f values.yaml \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + +## Configuration Settings Available + +### Plane Version +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| planeVersion | stable | Yes | | + +### Ingress Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| ingress.appHost | 'plane.example.com' | Yes | | +| ingress.minioHost | 'plane-minio.example.com' | | (Optional) Required to open minio console interface | +| ingress.ingressClass | 'nginx' | Yes | can be any of the supported ingress controller class (eg. nginx, traefik, etc) | +| ingress.clientMaxBodySize | 5m | Yes | This is set at the ingress controller level to support max data from client. | + +### SSL Settings +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| ssl.createIssuer | false | | Set it to true to create Let's Encrypt Service based issuer | +| ssl.issuer | http | | (Yes, if createIssuer = true) Allowed - cloudflare, digitalocean, http | +| ssl.token | | | (Yes, if createIssuer = true) api token of dns provider, not required for http | +| ssl.server | https://acme-v02.api.letsencrypt.org/directory | | (Yes, if createIssuer = true)Lets Encrypt SSL Generation API. Staging: https://acme-staging-v02.api.letsencrypt.org/directory | +| ssl.email | plane-admin@example.com | | (Yes, if createIssuer = true) Required by Let's Encrypt. Change to a valid email id | +| ssl.generateCerts | false | | | + +### Postgress DB Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| postgres.local_setup | true | | Plane uses `postgres` as the primary database to store all the transactional data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `postgres`. Mark it as `false` when using a remotely hosted database | +| postgres.image | postgres:15.5-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `postgres`. (must be set when `postgres.local_setup=true`) | +| postgres.servicePort | 5432 | | This key sets the default port number to be used while setting up stateful deployment of `postgres`. | +| postgres.cliConnectPort | | | | | If you intend to access the hosted stateful deployment of postgres using any of the client tools (e.g Postico), this key helps you expose the port. The mentioned port must not be occupied by any other applicaiton | +| postgres.volumeSize | 5Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | +| env.pgdb_username | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the username for the stateful deployment. | +| env.pgdb_password | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the password for the stateful deployment. | +| env.pgdb_name | plane | | Database name to be used while setting up stateful deployment of `Postgres` | +| env.pgdb_remote_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `postgres.local_setup` to `false` and set this key with remote connection url. | +| postgres.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + + +### Redis Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| redis.local_setup | true | | Plane uses `redis` to cache the session authentication and other static data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `redis`. Mark it as `false` when using a remotely hosted database | +| redis.image | redis:6.2.7-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `redis`. (must be set when `redis.local_setup=true`) | +| redis.servicePort | 6379 | | This key sets the default port number to be used while setting up stateful deployment of `redis`. | +| redis.volumeSize | 1Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | +| env.remote_redis_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `redis.local_setup` to `false` and set this key with remote connection url. | +| redis.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + + +### Doc Store (Minio/S3) Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| minio.local_setup | true | | Plane uses `minio` as the default file storage drive. This storage can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws S3 or similar services). Set this to `true` when you choose to setup stateful deployment of `postgres`. Mark it as `false` when using a remotely hosted database | +| minio.image | minio/minio:latest | | Using this key, user must provide the docker image name to setup the stateful deployment of `minio`. (must be set when `minio.local_setup=true`) | +| minio.volumeSize | 5Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | +| minio.root_user | admin | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the username for the stateful deployment. | +| minio.root_password | password | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the password for the stateful deployment. | +| env.docstore_bucket | uploads | Yes | Storage bucket name is required as part of configuration. This is where files will be uploaded irrespective of if you are using `Minio` or external `S3` (or compatible) storage service | +| env.doc_upload_size_limit | 5242880 | Yes | Document Upload Size Limit (default to 5Mb) | +| env.aws_access_key | | | External `S3` (or compatible) storage service provides `access key` for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| env.aws_secret_access_key | | | External `S3` (or compatible) storage service provides `secret access key` for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| env.aws_region | | | External `S3` (or compatible) storage service providers creates any buckets in user selected region. This is also shared with the user as `region` for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| env.aws_s3_endpoint_url | | | External `S3` (or compatible) storage service providers shares a `endpoint_url` for the integration purpose for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| minio.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + +### Web Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| web.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| web.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| web.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| web.image | makeplane/plane-frontend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + +### Space Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| space.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| space.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| space.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| space.image | makeplane/plane-space | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + +### Admin Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| admin.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| admin.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| admin.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| admin.image | makeplane/plane-admin | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + +### API Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| api.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| api.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| api.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| api.image | makeplane/plane-backend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | +| env.sentry_dsn | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry provided DSN for this integration. | +| env.sentry_environment | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry environment name (as configured in Sentry) for this integration. | + + +### Worker Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| worker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| worker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| worker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| worker.image | makeplane/plane-backend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + +### Beat-Worker deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| beatworker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| beatworker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| beatworker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| beatworker.image | makeplane/plane-backend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + + +### Ingress and SSL Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| ingress.enabled | true | | Ingress setup in kubernetes is a common practice to expose application to the intended audience. Set it to `false` if you are using external ingress providers like `Cloudflare` | +| ingress.appHost | 'plane.example.com' | Yes | The fully-qualified domain name (FQDN) in the format `sudomain.domain.tld` or `domain.tld` that the license is bound to. It is also attached to your `ingress` host to access Plane. | +| ingress.minioHost | 'plane-minio.example.com' | | Based on above configuration, if you want to expose the `minio` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. | +| ingress.ingressClass | 'nginx' | Yes | Kubernetes cluster setup comes with various options of `ingressClass`. Based on your setup, set this value to the right one (eg. nginx, traefik, etc). Leave it to default in case you are using external ingress provider. | +| ingress.clientMaxBodySize | 5m | Yes | Ingress controllers comes with various configuration options. One of which is `max payload size limit`. Setting this value lets you change the default value to user required. | +| ssl.createIssuer | false | | Kubernets cluster setup supports creating `issuer` type resource. After deployment, this is step towards creating secure access to the ingress url. Issuer is required for you generate SSL certifiate. Kubernetes can be configured to use any of the certificate authority to generate SSL (depending on CertManager configuration). Set it to `true` to create the issuer. Applicable only when `ingress.enabled=true` | +| ssl.issuer | http | | CertManager configuration allows user to create issuers using `http` or any of the other DNS Providers like `cloudflare`, `digitalocean`, etc. As of now Plane supports `http`, `cloudflare`, `digitalocean` | +| ssl.token | | | To create issuers using DNS challenge, set the issuer api token of dns provider like cloudflare` or `digitalocean`(not required for http) | +| ssl.server | https://acme-v02.api.letsencrypt.org/directory | | Issuer creation configuration need the certificate generation authority server url. Default URL is the `Let's Encrypt` server | +| ssl.email | plane@example.com | | Certificate generation authority needs a valid email id before generating certificate. Required when `ssl.createIssuer=true` | +| ssl.generateCerts | false | | After creating the issuers, user can still not create the certificate untill sure of configuration. Setting this to `true` will try to generate SSL certificate and associate with ingress. Applicable only when `ingress.enabled=true` and `ssl.createIssuer=true` | + + +### Common Environment Settings +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| env.secret_key | 60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 | Yes | This must a random string which is used for hashing/encrypting the sensitive data within the application. Once set, changing this might impact the already hashed/encrypted data | + + +## Custom Ingress Routes + +If you are planning to use 3rd party ingress providers, here is the available route configuration + +| Host | Path | Service | +|--- |:---: |--- | +| plane.example.com | / | http://plane-web.plane-ce:3000 | +| plane.example.com | /spaces/* | http://plane-space.plane-ce:3000 | +| plane.example.com | /god-mode/* | http://plane-admin.plane-ce:8000 | +| plane.example.com | /api/* | http://plane-api.plane-ce:8000 | +| plane.example.com | /auth/* | http://plane-api.plane-ce:8000 | +| plane.example.com | /uploads/* | http://plane-minio.plane-ce:9000 | +| plane-minio.example.com | / | http://plane-minio.plane-ce:9090 | diff --git a/charts/plane-ce/questions.yml b/charts/plane-ce/questions.yml new file mode 100644 index 0000000..effd805 --- /dev/null +++ b/charts/plane-ce/questions.yml @@ -0,0 +1,364 @@ +questions: + +- variable: dockerRegistry.enabled + label: Docker Registry Enabled + type: boolean + default: false + group: "Docker Registry" + show_subquestion_if: true + subquestions: + - variable: dockerRegistry.loginid + label: "Registry Host" + type: string + - variable: dockerRegistry.loginid + label: "Login ID" + type: string + - variable: dockerRegistry.password + label: "Password/Token" + type: password + +- variable: planeVersion + label: Plane Version (Docker Image Tag) + type: string + default: stable + required: true + group: "Docker Images" + subquestions: + - variable: web.image + label: Frontend Docker Image + type: string + required: true + default: "makeplane/plane-frontend" + - variable: space.image + label: Space Docker Image + type: string + required: true + default: "makeplane/plane-space" + - variable: admin.image + label: Admin Docker Image + type: string + required: true + default: "makeplane/plane-admin" + - variable: api.image + label: Backend Docker Image + type: string + required: true + default: "makeplane/plane-backend" + description: "Used by API, Worker, Beat-Worker" + +- variable: web.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Web Setup" + subquestions: + - variable: web.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: web.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: space.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Spaces Setup" + subquestions: + - variable: space.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: space.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: admin.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Admin Setup" + subquestions: + - variable: admin.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: admin.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: api.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "API Setup" + subquestions: + - variable: api.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: api.cpuLimit + label: "CPU Limit" + type: string + default: 500m + - variable: env.gunicorn_api_workers + label: "Workers" + type: int + default: 1 + - variable: env.cors_allowed_origins + label: "CORS Allowed Origins" + type: string + default: "" + +- variable: worker.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Worker Setup" + subquestions: + - variable: worker.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: worker.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: beatworker.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Beat Worker Setup" + subquestions: + - variable: beatworker.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: beatworker.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: redis.local_setup + label: "Install Redis" + type: boolean + default: true + group: "Redis Setup" + subquestions: + - variable: redis.image + label: "Docker Image" + type: string + default: "redis:6.2.7-alpine" + show_if: "redis.local_setup=true" + - variable: redis.servicePort + label: Port + type: int + default: 6379 + show_if: "redis.local_setup=true" + - variable: redis.storageClass + label: "Storage Class" + type: string + default: "longhorn" + show_if: "redis.local_setup=true" + - variable: redis.volumeSize + label: "Volume Size" + type: string + default: "1Gi" + show_if: "redis.local_setup=true" + - variable: env.remote_redis_url + label: "Remote Redis URL" + type: string + default: "redis://" + show_if: "redis.local_setup=false" + +- variable: postgres.local_setup + label: "Install Postgres" + type: boolean + default: true + group: "Postgres Setup" + # show_subquestion_if: true + subquestions: + - variable: postgres.image + label: "Docker Image" + type: string + default: "postgres:15.2-alpine" + show_if: "postgres.local_setup=true" + - variable: postgres.servicePort + label: Service Port + type: int + default: 5432 + show_if: "postgres.local_setup=true" + - variable: postgres.cliConnectPort + label: CLI Connect Port + type: int + show_if: "postgres.local_setup=true" + - variable: postgres.storageClass + label: "Storage Class" + type: string + default: "longhorn" + show_if: "postgres.local_setup=true" + - variable: postgres.volumeSize + label: "Volume Size" + type: string + default: "5Gi" + show_if: "postgres.local_setup=true" + - variable: env.pgdb_username + label: "Username" + type: string + default: "plane" + show_if: "postgres.local_setup=true" + - variable: env.pgdb_password + label: "Password" + type: password + default: "plane" + show_if: "postgres.local_setup=true" + - variable: env.pgdb_name + label: "DB Name" + type: string + default: "plane" + show_if: "postgres.local_setup=true" + - variable: env.pgdb_remote_url + label: "Remote URL" + type: string + default: "postrgres://" + show_if: "postgres.local_setup=false" + +- variable: minio.local_setup + label: "Install Minio" + type: boolean + default: true + group: "Storage Setup" + subquestions: + - variable: minio.image + label: "Docker Image" + type: string + default: "minio/minio:RELEASE.2023-10-25T06-33-25Z" + show_if: "minio.local_setup=true" + - variable: minio.root_user + label: "Root User" + type: string + default: "admin" + show_if: "minio.local_setup=true" + - variable: minio.root_password + label: "Root Password" + type: password + default: "password" + show_if: "minio.local_setup=true" + - variable: minio.storageClass + label: "Storage Class" + type: string + default: "longhorn" + show_if: "minio.local_setup=true" + - variable: minio.volumeSize + label: "Volume Size" + type: string + default: "5Gi" + show_if: "minio.local_setup=true" + - variable: env.aws_access_key + label: "AWS Access Key" + type: string + default: "" + show_if: "minio.local_setup=false" + - variable: env.aws_secret_access_key + label: "AWS Secret Key" + type: password + default: "" + show_if: "minio.local_setup=false" + - variable: env.aws_region + label: "AWS Region" + type: string + default: "" + show_if: "minio.local_setup=false" + - variable: env.docstore_bucket + label: "Bucket Name" + type: string + default: "uploads" + - variable: env.doc_upload_size_limit + label: "FIle Upload Size Limit" + type: string + default: "5242880" + + +- variable: ingress.enabled + label: "Install Ingress" + type: boolean + default: true + required: true + group: "Ingress" + show_subquestion_if: true + subquestions: + - variable: ingress.appHost + label: "App. Host" + type: string + default: "plane.example.com" + required: true + - variable: ingress.minioHost + label: "Minio Host" + type: string + default: "plane-minio.example.com" + show_if: "minio.local_setup=true" + - variable: ingress.ingressClass + label: "Ingress Classname" + type: string + required: true + default: "nginx" + - variable: ingress.clientMaxBodySize + label: "Max Body Size" + type: string + required: true + default: "10m" + +- variable: ssl.createIssuer + label: "Create Issuer" + type: boolean + default: false + group: "Ingress" + show_if: "ingress.enabled=true" + show_subquestion_if: true + subquestions: + - variable: ssl.issuer + label: "SSL Issuer" + type: enum + options: + - "http" + - "cloudflare" + - "digitalocean" + default: "http" + - variable: ssl.server + label: "Let's Encrypt Server URL" + type: string + default: "https://acme-staging-v02.api.letsencrypt.org/directory" + - variable: ssl.email + label: "Let's Encrypt Reg. Email" + type: string + default: "plane@example.com" + - variable: ssl.token + label: "Provider API Token" + type: password + default: "" + description: "Not required for 'http' issuer" + - variable: ssl.generateCerts + label: "Enable to generate certificates" + type: boolean + default: false + +- variable: env.sentry_dsn + label: "Sentry DSN" + type: string + default: "" + group: "Misc." + subquestions: + - variable: env.sentry_environment + label: "Sentry Environment" + type: string + default: "Development" + - variable: env.secret_key + label: "Random Secret Key" + type: string + required: true + default: "60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5" diff --git a/charts/plane-ce/templates/_helpers.tpl b/charts/plane-ce/templates/_helpers.tpl new file mode 100644 index 0000000..b33a371 --- /dev/null +++ b/charts/plane-ce/templates/_helpers.tpl @@ -0,0 +1,3 @@ +{{- define "imagePullSecret" }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\"}}}" .Values.dockerRegistry.host .Values.dockerRegistry.loginid .Values.dockerRegistry.password | b64enc }} +{{- end }} \ No newline at end of file diff --git a/charts/plane-ce/templates/certs/cert-issuers.yaml b/charts/plane-ce/templates/certs/cert-issuers.yaml new file mode 100644 index 0000000..5b70cf8 --- /dev/null +++ b/charts/plane-ce/templates/certs/cert-issuers.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.ingress.enabled .Values.ssl.createIssuer }} + +apiVersion: v1 +kind: Secret +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-issuer-api-token-secret +type: Opaque +stringData: + api-token: {{ .Values.ssl.token | default "default-api-token" | quote }} + +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-cert-issuer +spec: + acme: + email: {{ .Values.ssl.email }} + server: {{ .Values.ssl.server }} + privateKeySecretRef: + name: {{ .Release.Name }}-cert-issuer-key + solvers: + {{- if eq .Values.ssl.issuer "cloudflare" }} + - dns01: + cloudflare: + apiTokenSecretRef: + name: {{ .Release.Name }}-issuer-api-token-secret + key: api-token + {{- end }} + {{- if eq .Values.ssl.issuer "digitalocean" }} + - dns01: + digitalocean: + tokenSecretRef: + name: {{ .Release.Name }}-issuer-api-token-secret + key: api-token + {{- end }} + {{- if eq .Values.ssl.issuer "http" }} + - http01: + ingress: + ingressClassName: {{ .Values.ingress.ingressClass }} + {{- end }} + +--- +{{- end}} \ No newline at end of file diff --git a/charts/plane-ce/templates/certs/certs.yaml b/charts/plane-ce/templates/certs/certs.yaml new file mode 100644 index 0000000..bf6cfda --- /dev/null +++ b/charts/plane-ce/templates/certs/certs.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ingress.enabled .Values.ssl.createIssuer .Values.ssl.generateCerts }} + +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-ssl-cert +spec: + dnsNames: + - {{ .Values.ingress.appHost | quote }} + {{- if and .Values.minio.local_setup .Values.ingress.minioHost }} + - {{ .Values.ingress.minioHost | quote }} + {{- end }} + issuerRef: + name: {{ .Release.Name }}-cert-issuer + secretName: {{ .Release.Name }}-ssl-cert + +{{- end}} diff --git a/charts/plane-ce/templates/config-secrets/app-env.yaml b/charts/plane-ce/templates/config-secrets/app-env.yaml new file mode 100644 index 0000000..b358e49 --- /dev/null +++ b/charts/plane-ce/templates/config-secrets/app-env.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-app-secrets +data: + SECRET_KEY: {{ .Values.env.secret_key | default "60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5" | b64enc | quote }} + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-app-vars +data: + SENTRY_DSN: {{ .Values.env.sentry_dsn | default "" | quote}} + SENTRY_ENVIRONMENT: {{ .Values.env.sentry_environment | default "" | quote}} + DEBUG: "0" + DOCKERIZED: "1" + GUNICORN_WORKERS: {{ .Values.env.gunicorn_api_workers | default 1 | quote }} + + {{- if and .Values.ingress.enabled .Values.ingress.appHost }} + WEB_URL: "http://{{ .Values.ingress.appHost }}" + {{- else }} + WEB_URL: "" + {{- end }} + + + {{- if eq .Values.env.cors_allowed_origins "*"}} + CORS_ALLOWED_ORIGINS: "*" + {{- else if and .Values.ingress.enabled .Values.ingress.appHost .Values.env.cors_allowed_origins }} + CORS_ALLOWED_ORIGINS: "http://{{ .Values.ingress.appHost }},https://{{ .Values.ingress.appHost }},{{ .Values.env.cors_allowed_origins }}" + {{- else if .Values.env.cors_allowed_origins }} + CORS_ALLOWED_ORIGINS: "{{ .Values.env.cors_allowed_origins }}" + {{- else if and .Values.ingress.enabled .Values.ingress.appHost}} + CORS_ALLOWED_ORIGINS: "http://{{ .Values.ingress.appHost }},https://{{ .Values.ingress.appHost }}" + {{- else }} + CORS_ALLOWED_ORIGINS: "" + {{- end }} + + {{- if .Values.redis.local_setup }} + REDIS_URL: "redis://{{ .Release.Name }}-redis.{{ .Release.Namespace }}.svc.cluster.local:6379/" + {{- else }} + REDIS_URL: {{ .Values.env.remote_redis_url | default "" | quote }} + {{- end }} + + {{ if .Values.postgres.local_setup }} + DATABASE_URL: "postgresql://{{ .Values.env.pgdb_username }}:{{ .Values.env.pgdb_password }}@{{ .Release.Name }}-pgdb.{{ .Release.Namespace }}.svc.cluster.local/{{ .Values.env.pgdb_name }}" + {{ else if .Values.env.pgdb_remote_url }} + DATABASE_URL: {{ .Values.env.pgdb_remote_url}} + {{ else }} + DATABASE_URL: "" + {{ end }} diff --git a/charts/plane-ce/templates/config-secrets/doc-strore.yaml b/charts/plane-ce/templates/config-secrets/doc-strore.yaml new file mode 100644 index 0000000..f40cc76 --- /dev/null +++ b/charts/plane-ce/templates/config-secrets/doc-strore.yaml @@ -0,0 +1,37 @@ + +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-doc-store-secrets +data: + {{ if .Values.minio.local_setup }} + MINIO_ROOT_PASSWORD: {{ .Values.minio.root_password | default "password" | b64enc | quote}} + AWS_SECRET_ACCESS_KEY: {{ .Values.minio.root_password | default "password" | b64enc | quote }} + {{ else }} + AWS_SECRET_ACCESS_KEY: {{ .Values.env.aws_secret_access_key | default "" | b64enc | quote }} + {{ end }} + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-doc-store-vars +data: + FILE_SIZE_LIMIT: {{ .Values.env.doc_upload_size_limit | default 5242880 | quote }} + AWS_S3_BUCKET_NAME: {{ .Values.env.docstore_bucket | default "" | quote }} + {{ if .Values.minio.local_setup }} + MINIO_ROOT_USER: {{ .Values.minio.root_user | default "admin" | quote }} + AWS_ACCESS_KEY_ID: {{ .Values.minio.root_user | default "admin" | quote }} + AWS_S3_ENDPOINT_URL: http://{{ .Release.Name }}-minio:9000 + USE_MINIO: "1" + {{ else }} + USE_MINIO: "0" + AWS_ACCESS_KEY_ID: {{ .Values.env.aws_access_key | default "" | quote }} + AWS_REGION: {{ .Values.env.aws_region | default "" | quote }} + # AWS_S3_ENDPOINT_URL=${AWS_S3_ENDPOINT_URL:-http://plane-minio:9000} + {{ end }} +--- \ No newline at end of file diff --git a/charts/plane-ce/templates/config-secrets/docker-registry.yaml b/charts/plane-ce/templates/config-secrets/docker-registry.yaml new file mode 100644 index 0000000..14e6b3d --- /dev/null +++ b/charts/plane-ce/templates/config-secrets/docker-registry.yaml @@ -0,0 +1,12 @@ +{{- if .Values.dockerRegistry.enabled }} + +apiVersion: v1 +kind: Secret +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-docker-registry-credentials +data: + .dockerconfigjson: {{ include "imagePullSecret" .}} +type: kubernetes.io/dockerconfigjson + +{{- end }} \ No newline at end of file diff --git a/charts/plane-ce/templates/config-secrets/pgdb.yaml b/charts/plane-ce/templates/config-secrets/pgdb.yaml new file mode 100644 index 0000000..e8455bd --- /dev/null +++ b/charts/plane-ce/templates/config-secrets/pgdb.yaml @@ -0,0 +1,21 @@ +{{- if .Values.postgres.local_setup }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-secrets +data: + POSTGRES_PASSWORD: {{ .Values.env.pgdb_password | default "plane" | b64enc | quote }} +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-vars +data: + POSTGRES_DB: {{ .Values.env.pgdb_name | default "plane" | quote }} + POSTGRES_USER: {{ .Values.env.pgdb_username | default "plane" | quote }} +--- +{{- end}} \ No newline at end of file diff --git a/charts/plane-ce/templates/ingress.yaml b/charts/plane-ce/templates/ingress.yaml new file mode 100644 index 0000000..4942e2e --- /dev/null +++ b/charts/plane-ce/templates/ingress.yaml @@ -0,0 +1,83 @@ +{{- if and .Values.ingress.enabled .Values.ingress.appHost }} + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-ingress + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: {{ .Values.ingress.clientMaxBodySize | default "5m" | quote}} +spec: + ingressClassName: {{ .Values.ingress.ingressClass }} + rules: + - host: {{ .Values.ingress.appHost }} + http: + paths: + - backend: + service: + port: + number: 3000 + name: {{ .Release.Name }}-web + path: / + pathType: Prefix + - backend: + service: + port: + number: 8000 + name: {{ .Release.Name }}-api + path: /api + pathType: Prefix + - backend: + service: + port: + number: 8000 + name: {{ .Release.Name }}-api + path: /auth + pathType: Prefix + - backend: + service: + port: + number: 3000 + name: {{ .Release.Name }}-space + path: /spaces + pathType: Prefix + - backend: + service: + port: + number: 3000 + name: {{ .Release.Name }}-admin + path: /god-mode + pathType: Prefix + {{- if and .Values.minio.local_setup .Values.env.docstore_bucket }} + - backend: + service: + port: + number: 9000 + name: {{ .Release.Name }}-minio + path: /{{ .Values.env.docstore_bucket }} + pathType: Prefix + {{- end }} + + {{- if and .Values.minio.local_setup .Values.ingress.minioHost }} + - host: {{ .Values.ingress.minioHost }} + http: + paths: + - backend: + service: + port: + number: 9090 + name: {{ .Release.Name }}-minio + path: / + pathType: Prefix + {{- end }} + {{- if .Values.ssl.generateCerts }} + tls: + - hosts: + - {{ .Values.ingress.appHost | quote }} + {{- if and .Values.minio.local_setup .Values.ingress.minioHost }} + - {{ .Values.ingress.minioHost | quote }} + {{ end }} + secretName: {{ .Release.Name }}-ssl-cert + {{- end }} + +{{- end }} \ No newline at end of file diff --git a/charts/plane-ce/templates/service-account.yaml b/charts/plane-ce/templates/service-account.yaml new file mode 100644 index 0000000..6eed2f5 --- /dev/null +++ b/charts/plane-ce/templates/service-account.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-srv-account +{{- if .Values.dockerRegistry.enabled }} +imagePullSecrets: + - name: {{ .Release.Name }}-docker-registry-credentials +{{- end}} \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/admin.deployment.yaml b/charts/plane-ce/templates/workloads/admin.deployment.yaml new file mode 100644 index 0000000..d17179a --- /dev/null +++ b/charts/plane-ce/templates/workloads/admin.deployment.yaml @@ -0,0 +1,60 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-admin + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin +spec: + clusterIP: None + ports: + - name: admin-3000 + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-admin-wl +spec: + replicas: {{ .Values.admin.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-admin + imagePullPolicy: Always + image: {{ .Values.admin.image | default "makeplane/plane-frontend" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.admin.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.admin.cpuLimit | default "500m" | quote}} + command: + - node + args: + - admin/server.js + - admin + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/api.deployment.yaml b/charts/plane-ce/templates/workloads/api.deployment.yaml new file mode 100644 index 0000000..e1daa14 --- /dev/null +++ b/charts/plane-ce/templates/workloads/api.deployment.yaml @@ -0,0 +1,80 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-api + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api +spec: + clusterIP: None + ports: + - name: api-8000 + port: 8000 + protocol: TCP + targetPort: 8000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-api-wl +spec: + replicas: {{ .Values.api.replicas | default 1}} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-api + imagePullPolicy: Always + image: {{ .Values.api.image | default "makeplane/plane-backend" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.api.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.api.cpuLimit | default "500m" | quote}} + command: + - ./bin/docker-entrypoint-api.sh + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + readinessProbe: + failureThreshold: 30 + httpGet: + path: / + port: 8000 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/beat-worker.deployment.yaml b/charts/plane-ce/templates/workloads/beat-worker.deployment.yaml new file mode 100644 index 0000000..2966acd --- /dev/null +++ b/charts/plane-ce/templates/workloads/beat-worker.deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-beat-worker-wl +spec: + replicas: {{ .Values.beatworker.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-beat-worker + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-beat-worker + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-beat-worker + imagePullPolicy: Always + image: {{ .Values.beatworker.image | default "makeplane/plane-backend" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.beatworker.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.beatworker.cpuLimit | default "500m" | quote}} + command: + - ./bin/docker-entrypoint-beat.sh + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/migrator.job.yaml b/charts/plane-ce/templates/workloads/migrator.job.yaml new file mode 100644 index 0000000..b6a2805 --- /dev/null +++ b/charts/plane-ce/templates/workloads/migrator.job.yaml @@ -0,0 +1,38 @@ + +apiVersion: batch/v1 +kind: Job +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-api-migrate-{{ .Release.Revision }} +spec: + backoffLimit: 3 + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api-migrate + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-api-migrate + image: {{ .Values.api.image | default "makeplane/plane-backend" }}:{{ .Values.planeVersion }} + command: + - ./bin/docker-entrypoint-migrator.sh + imagePullPolicy: Always + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + restartPolicy: OnFailure + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account +--- diff --git a/charts/plane-ce/templates/workloads/minio.stateful.yaml b/charts/plane-ce/templates/workloads/minio.stateful.yaml new file mode 100644 index 0000000..1dd7b14 --- /dev/null +++ b/charts/plane-ce/templates/workloads/minio.stateful.yaml @@ -0,0 +1,122 @@ +{{- if .Values.minio.local_setup }} + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-minio + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio +spec: + clusterIP: None + ports: + - name: minio-api-9000 + port: 9000 + protocol: TCP + targetPort: 9000 + - name: minio-console-9090 + port: 9090 + protocol: TCP + targetPort: 9090 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-minio-wl +spec: + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio + serviceName: {{ .Release.Name }}-minio + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio + spec: + containers: + - image: {{ .Values.minio.image }} + imagePullPolicy: Always + name: {{ .Release.Name }}-minio + stdin: true + tty: true + # command: + args: + - server + - /data + - --console-address + - :9090 + envFrom: + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + volumeMounts: + - mountPath: /data + name: pvc-{{ .Release.Name }}-minio-vol + subPath: '' + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + creationTimestamp: null + namespace: {{ .Release.Namespace }} + name: pvc-{{ .Release.Name }}-minio-vol + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.minio.volumeSize | default "5Gi" | quote }} + storageClassName: {{ .Values.minio.storageClass }} + volumeMode: Filesystem + +--- + +apiVersion: batch/v1 +kind: Job +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-minio-bucket +spec: + backoffLimit: 6 + completionMode: NonIndexed + template: + metadata: + namespace: {{ .Release.Namespace }} + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox + command: ['sh', '-c', "until nslookup {{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc.cluster.local; do echo waiting for {{ .Release.Name }}-minio; sleep 2; done"] + containers: + - command: + - /bin/sh + args: + - '-c' + - >- + /usr/bin/mc config host add plane-app-minio + http://{{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc.cluster.local:9000 "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY"; + /usr/bin/mc mb plane-app-minio/$AWS_S3_BUCKET_NAME; + /usr/bin/mc anonymous set download plane-app-minio/$AWS_S3_BUCKET_NAME; exit 0; + envFrom: + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + image: minio/mc + imagePullPolicy: Always + name: {{ .Release.Name }}-minio-bucket + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + terminationGracePeriodSeconds: 120 +{{- end }} \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/postgres.stateful.yaml b/charts/plane-ce/templates/workloads/postgres.stateful.yaml new file mode 100644 index 0000000..ee30991 --- /dev/null +++ b/charts/plane-ce/templates/workloads/postgres.stateful.yaml @@ -0,0 +1,98 @@ +{{- if .Values.postgres.local_setup }} + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb +spec: + clusterIP: None + ports: + - name: pg-{{ .Values.postgres.servicePort }} + port: {{ .Values.postgres.servicePort }} + protocol: TCP + targetPort: 5432 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb +--- +{{- if and .Values.postgres.cliConnectPort .Values.postgres.cliConnectPort | int }} +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-cli-connect +spec: + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: pg-{{ .Values.postgres.cliConnectPort | default 30000 }} + nodePort: {{ .Values.postgres.cliConnectPort | default 30000 }} + port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb + sessionAffinity: None + type: NodePort +--- +{{- end }} + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-wl +spec: + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb + serviceName: {{ .Release.Name }}-pgdb + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb + spec: + containers: + - image: {{ .Values.postgres.image }} + imagePullPolicy: Always + name: {{ .Release.Name }}-pgdb + stdin: true + tty: true + env: + - name: PGDATA + value: /var/lib/postgresql/data/plane + envFrom: + - configMapRef: + name: {{ .Release.Name }}-pgdb-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-pgdb-secrets + optional: false + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: pvc-{{ .Release.Name }}-pgdb-vol + subPath: '' + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + creationTimestamp: null + namespace: {{ .Release.Namespace }} + name: pvc-{{ .Release.Name }}-pgdb-vol + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.postgres.volumeSize | default "5Gi" | quote }} + storageClassName: {{ .Values.postgres.storageClass }} + volumeMode: Filesystem + +{{- end }} \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/redis.stateful.yaml b/charts/plane-ce/templates/workloads/redis.stateful.yaml new file mode 100644 index 0000000..7eede7d --- /dev/null +++ b/charts/plane-ce/templates/workloads/redis.stateful.yaml @@ -0,0 +1,66 @@ +{{- if .Values.redis.local_setup }} + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-redis + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis +spec: + clusterIP: None + ports: + - name: redis-{{ .Values.redis.servicePort }} + port: {{ .Values.redis.servicePort }} + protocol: TCP + targetPort: 6379 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis +--- + +# REDIS WORKLOAD + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-redis-wl +spec: + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis + serviceName: {{ .Release.Name }}-redis + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis + spec: + containers: + - image: {{ .Values.redis.image }} + imagePullPolicy: Always + name: {{ .Release.Name }}-redis + stdin: true + tty: true + volumeMounts: + - mountPath: /data + name: pvc-{{ .Release.Name }}-redis-vol + subPath: '' + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + creationTimestamp: null + namespace: {{ .Release.Namespace }} + name: pvc-{{ .Release.Name }}-redis-vol + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.redis.volumeSize | default "1Gi" | quote }} + storageClassName: {{ .Values.redis.storageClass }} + volumeMode: Filesystem + +{{- end }} \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/space.deployment.yaml b/charts/plane-ce/templates/workloads/space.deployment.yaml new file mode 100644 index 0000000..a6a51d7 --- /dev/null +++ b/charts/plane-ce/templates/workloads/space.deployment.yaml @@ -0,0 +1,60 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-space + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space +spec: + clusterIP: None + ports: + - name: space-3000 + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-space-wl +spec: + replicas: {{ .Values.space.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-space + imagePullPolicy: Always + image: {{ .Values.space.images | default "makeplane/plane-space" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.web.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.web.cpuLimit | default "500m" | quote}} + command: + - node + args: + - space/server.js + - space + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/web.deployment.yaml b/charts/plane-ce/templates/workloads/web.deployment.yaml new file mode 100644 index 0000000..2f65aaa --- /dev/null +++ b/charts/plane-ce/templates/workloads/web.deployment.yaml @@ -0,0 +1,60 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-web + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web +spec: + clusterIP: None + ports: + - name: web-3000 + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-web-wl +spec: + replicas: {{ .Values.web.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-web + imagePullPolicy: Always + image: {{ .Values.web.image | default "makeplane/plane-frontend" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.web.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.web.cpuLimit | default "500m" | quote}} + command: + - node + args: + - web/server.js + - web + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-ce/templates/workloads/worker.deployment.yaml b/charts/plane-ce/templates/workloads/worker.deployment.yaml new file mode 100644 index 0000000..42ca195 --- /dev/null +++ b/charts/plane-ce/templates/workloads/worker.deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-worker-wl +spec: + replicas: {{ .Values.worker.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-worker + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-worker + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-worker + imagePullPolicy: Always + image: {{ .Values.worker.image | default "makeplane/plane-backend" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.worker.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.worker.cpuLimit | default "500m" | quote}} + command: + - ./bin/docker-entrypoint-worker.sh + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-ce/values.yaml b/charts/plane-ce/values.yaml new file mode 100644 index 0000000..d1ec810 --- /dev/null +++ b/charts/plane-ce/values.yaml @@ -0,0 +1,112 @@ +planeVersion: stable + +dockerRegistry: + enabled: false + host: "index.docker.io/v1/" + loginid: makeplane + password: '' + +ingress: + enabled: true + appHost: 'plane.example.com' + minioHost: 'plane-minio.example.com' + ingressClass: 'nginx' + clientMaxBodySize: 10m + +# SSL Configuration - Valid only if ingress.enabled is true +ssl: + createIssuer: false + issuer: "http" # Allowed : cloudflare, digitalocean, http + token: "" # not required for http + server: https://acme-v02.api.letsencrypt.org/directory + email: plane@example.com + generateCerts: false + +redis: + local_setup: true + image: redis:7.2.4-alpine + servicePort: 6379 + storageClass: longhorn + volumeSize: 1Gi + +postgres: + local_setup: true + image: postgres:15.5-alpine + servicePort: 5432 + cliConnectPort: '' + storageClass: longhorn + volumeSize: 5Gi + +minio: + local_setup: true + image: minio/minio:latest + storageClass: longhorn + volumeSize: 5Gi + root_user: admin + root_password: password + +web: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: makeplane/plane-frontend + + +space: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: makeplane/plane-space + +admin: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: makeplane/plane-admin + +api: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: makeplane/plane-backend + +worker: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: makeplane/plane-backend + +beatworker: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: makeplane/plane-backend + +env: + pgdb_username: plane + pgdb_password: plane + pgdb_name: plane + pgdb_remote_url: "" #INCASE OF REMOTE PG DB URL ONLY + + # NEXT_PUBLIC_DEPLOY_URL: "" + # REDIS + remote_redis_url: "" #INCASE OF REMOTE REDIS ONLY + # POSTGRES DB VALUES + + # DATA STORE + docstore_bucket: "uploads" + doc_upload_size_limit: "5242880" # 5MB + + # REQUIRED IF MINIO LOCAL SETUP IS FALSE + aws_access_key: "" + aws_secret_access_key: "" + aws_region: "" + + secret_key: "60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5" + + sentry_dsn: "" + sentry_environment: "" + + gunicorn_api_workers: 1 + + cors_allowed_origins: "" diff --git a/charts/plane-enterprise/.helmignore b/charts/plane-enterprise/.helmignore new file mode 100644 index 0000000..2d4a744 --- /dev/null +++ b/charts/plane-enterprise/.helmignore @@ -0,0 +1,24 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +test-*.yaml \ No newline at end of file diff --git a/charts/plane-enterprise/Chart.lock b/charts/plane-enterprise/Chart.lock new file mode 100644 index 0000000..e69de29 diff --git a/charts/plane-enterprise/Chart.yaml b/charts/plane-enterprise/Chart.yaml new file mode 100644 index 0000000..7da7550 --- /dev/null +++ b/charts/plane-enterprise/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 + +name: plane-enterprise +description: Meet Plane. An Enterprise software development tool to manage issues, sprints, and product roadmaps with peace of mind. + +type: application + +version: 1.0.5 +appVersion: "1.0.0" + +home: https://plane.so/ +icon: https://plane.so/favicon/favicon-32x32.png diff --git a/charts/plane-enterprise/README.md b/charts/plane-enterprise/README.md new file mode 100644 index 0000000..01bdc99 --- /dev/null +++ b/charts/plane-enterprise/README.md @@ -0,0 +1,231 @@ +## Pre-requisite +- A Plane One license
+ > If you don’t have a license, get it here. +- A working Kubernetes cluster +- `kubectl` and `helm` on the client system that you will use to install our Helm charts + +## Installing Plane One + + 1. Open Terminal or any other command-line app that has access to Kubernetes tools on your local system. + 2. Set the following environment variables.
+ Copy the format of constants below, paste it on Terminal to start setting environment variables, set values for each variable, and hit ENTER or RETURN. + > You will get the values for the variables from [prime.plane.so](https://prime.plane.so) under the Kuberntes tab of your license's details page. When installing Plane One for the first time, remember to specify a domain name. + + ```bash + LICENSE_KEY= + REG_USER_ID= + REG_PASSWORD=<******> + PLANE_VERSION= + DOMAIN_NAME= + ``` + + 3. Add Plane helm chart repo
+ Continue to be on the same Terminal window as with the previous steps, copy the code below, paste it on Terminal, and hit ENTER or RETURN. + + ```bash + helm repo add plane https://helm.plane.so/ + ``` + + 4. Set-up and customization
+ - Quick set-up
+ This is the fastest way to deploy Plane with default settings. This will create stateful deployments for Postgres, Redis, and Minio with a persistent volume claim using the `longhorn` storage class. This also sets up the ingress routes for you using `nginx` ingress class. + > To customize this, see `Custom ingress routes` below. + + Continue to be on the same Terminal window as you have so far, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install one-app plane/plane-enterprise \ + --create-namespace \ + --namespace plane-one \ + --set dockerRegistry.loginid=${REG_USER_ID} \ + --set dockerRegistry.password=${REG_PASSWORD} \ + --set license.licenseKey=${LICENSE_KEY} \ + --set license.licenseDomain=${DOMAIN_NAME} \ + --set license.licenseServer=https://prime.plane.so \ + --set planeVersion=${PLANE_VERSION} \ + --set ingress.ingressClass=nginx \ + --set env.storageClass=longhorn \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + + > This is the minimum required to set up Plane One. You can change the default namespace from `plane-one`, the default appname + from `one-app`, the default storage class from `env.storageClass`, and the default ingress class from `ingress.ingressClass` to + whatever you would like to.

+ You can also pass other settings referring to `Configuration Settings` section. + + - Advance set-up
+ For more control over your set-up, run the script below to download the `values.yaml` file and and edit using any editor like Vim or Nano. + + ```bash + helm show values plane/plane-enterprise > values.yaml + vi values.yaml + ``` + + Make sure you set the minimum required values as below. + - `planeVersion: ` + - `dockerRegistry.loginid: ` + - `dockerRegistry.password: ` + - `license.licenseKey: ` + - `license.licenseDomain: ` + - `license.licenseServer: https://prime.plane.so` + - `ingress.ingressClass: ` + - `env.storageClass: ` + + > See `Available customizations` for more details. + + After saving the `values.yaml` file, continue to be on the same Terminal window as on the previous steps, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install one-app plane/plane-enterprise \ + --create-namespace \ + --namespace plane-one \ + -f values.yaml \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + + +## Available customizations + + ### Docker registry + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | dockerRegistry.enabled | true | Yes | Plane uses a private Docker registry which needs authenticated login. This must be set to `true` to install Plane One. | + | dockerRegistry.registry | registry.plane.tools | Yes | The host that will serve the required Docker images; Don't change this. | + | dockerRegistry.loginid | | Yes | Sets the `loginid` for the Docker registry. This is the same as the REG_USER_ID value on prime. plane.so | + | dockerRegistry.password | | Yes | Sets the `password` for the Docker registry. This is the same as the REG_PASSWORD value on prime.plane.so | + + ### License + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | planeVersion | vX.XX.X | Yes | Specifies the version of Plane to be deployed. Copy this from prime.plane.so. | + | license.licenseServer | https://prime.plane.so | Yes | Sets the value of the `licenseServer` that gets you your license and validates it periodically. Don't change this. | + | license.licenseKey | | Yes | Holds your license key to Plane One. Copy this from prime.plane.so. | + | license.licenseDomain | 'plane.example.com' | Yes | The fully-qualified domain name (FQDN) in the format `sudomain.domain.tld` or `domain.tld` that the license is bound to. It is also attached to your `ingress` host to access Plane. | + + + ### Postgres + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.postgres.local_setup | true | | Plane uses `postgres` as the primary database to store all the transactional data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `postgres`. Mark it as `false` when using a remotely hosted database | + | services.postgres.image | registry.plane.tools/plane/postgres:15.5-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `postgres`. (must be set when `services.postgres.local_setup=true`) | + | services.postgres.servicePort | 5432 | | This key sets the default port number to be used while setting up stateful deployment of `postgres`. | + | services.postgres.cliConnectPort | | | If you intend to access the hosted stateful deployment of postgres using any of the client tools (e.g Postico), this key helps you expose the port. The mentioned port must not be occupied by any other applicaiton | + | services.postgres.volumeSize | 2Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | + | env.pgdb_username | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the username for the stateful deployment. | + | env.pgdb_password | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the password for the stateful deployment. | + | env.pgdb_name | plane | | Database name to be used while setting up stateful deployment of `Postgres` | + | env.pgdb_remote_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `services.postgres.local_setup` to `false` and set this key with remote connection url. | + + + ### Redis Setup + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.redis.local_setup | true | | Plane uses `redis` to cache the session authentication and other static data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `redis`. Mark it as `false` when using a remotely hosted database | + | services.redis.image | registry.plane.tools/plane/redis:7.2.4-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `redis`. (must be set when `services.redis.local_setup=true`) | + | services.redis.servicePort | 6379 | | This key sets the default port number to be used while setting up stateful deployment of `redis`. | + | services.redis.volumeSize | 500Mi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | + | env.remote_redis_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `services.redis.local_setup` to `false` and set this key with remote connection url. | + + ### Doc Store (Minio/S3) Setup + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.minio.local_setup | true | | Plane uses `minio` as the default file storage drive. This storage can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws S3 or similar services). Set this to `true` when you choose to setup stateful deployment of `minio`. Mark it as `false` when using a remotely hosted database | + | services.minio.image | registry.plane.tools/plane/minio:latest | | Using this key, user must provide the docker image name to setup the stateful deployment of `minio`. (must be set when `services.minio.local_setup=true`) | + | services.minio.volumeSize | 3Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | + | services.minio.root_user | admin | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the username for the stateful deployment. | + | services.minio.root_password | password | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the password for the stateful deployment. | + | env.docstore_bucket | uploads | Yes | Storage bucket name is required as part of configuration. This is where files will be uploaded irrespective of if you are using `Minio` or external `S3` (or compatible) storage service | + | env.doc_upload_size_limit | 5242880 | Yes | Document Upload Size Limit (default to 5Mb) | + | env.aws_access_key | | | External `S3` (or compatible) storage service provides `access key` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + | env.aws_secret_access_key | | | External `S3` (or compatible) storage service provides `secret access key` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + | env.aws_region | | | External `S3` (or compatible) storage service providers creates any buckets in user selected region. This is also shared with the user as `region` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + | env.aws_s3_endpoint_url | | | External `S3` (or compatible) storage service providers shares a `endpoint_url` for the integration purpose for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + + + ### Web Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.web.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.web.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.web.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.web.image | registry.plane.tools/plane/web-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + ### Space Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.space.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.space.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.space.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.space.image | registry.plane.tools/plane/space-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + ### Admin Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.admin.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.admin.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.admin.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.admin.image | registry.plane.tools/plane/admin-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + ### API Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.api.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.api.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.api.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.api.image | registry.plane.tools/plane/backend-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + | env.sentry_dsn | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry provided DSN for this integration. | + | env.sentry_environment | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry environment name (as configured in Sentry) for this integration. | + + ### Worker Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.worker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.worker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.worker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + + ### Beat-Worker deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.beatworker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.beatworker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.beatworker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + + ### Ingress and SSL Setup + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | ingress.enabled | true | | Ingress setup in kubernetes is a common practice to expose application to the intended audience. Set it to `false` if you are using external ingress providers like `Cloudflare` | + | ingress.minioHost | 'plane-services.minio.example.com' | | Based on above configuration, if you want to expose the `minio` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. | + | ingress.ingressClass | 'nginx' | Yes | Kubernetes cluster setup comes with various options of `ingressClass`. Based on your setup, set this value to the right one (eg. nginx, traefik, etc). Leave it to default in case you are using external ingress provider. | + | ingress.clientMaxBodySize | 5m | Yes | Ingress controllers comes with various configuration options. One of which is `max payload size limit`. Setting this value lets you change the default value to user required. | + | ssl.createIssuer | false | | Kubernets cluster setup supports creating `issuer` type resource. After deployment, this is step towards creating secure access to the ingress url. Issuer is required for you generate SSL certifiate. Kubernetes can be configured to use any of the certificate authority to generate SSL (depending on CertManager configuration). Set it to `true` to create the issuer. Applicable only when `ingress.enabled=true` | + | ssl.issuer | http | | CertManager configuration allows user to create issuers using `http` or any of the other DNS Providers like `cloudflare`, `digitalocean`, etc. As of now Plane supports `http`, `cloudflare`, `digitalocean` | + | ssl.token | | | To create issuers using DNS challenge, set the issuer api token of dns provider like cloudflare` or `digitalocean`(not required for http) | + | ssl.server | https://acme-v02.api.letsencrypt.org/directory | | Issuer creation configuration need the certificate generation authority server url. Default URL is the `Let's Encrypt` server | + | ssl.email | plane@example.com | | Certificate generation authority needs a valid email id before generating certificate. Required when `ssl.createIssuer=true` | + | ssl.generateCerts | false | | After creating the issuers, user can still not create the certificate untill sure of configuration. Setting this to `true` will try to generate SSL certificate and associate with ingress. Applicable only when `ingress.enabled=true` and `ssl.createIssuer=true` | + + + ### Common Environment Settings + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | env.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + | env.secret_key | 60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 | Yes | This must a random string which is used for hashing/encrypting the sensitive data within the application. Once set, changing this might impact the already hashed/encrypted data | + + + ## Custom Ingress Routes + + If you are planning to use 3rd party ingress providers, here is the available route configuration + + | Host | Path | Service | + |--- |:---: |--- | + | plane.example.com | / | http://plane-web.plane-one:3000 | + | plane.example.com | /spaces/* | http://plane-space.plane-one:3000 | + | plane.example.com | /god-mode/* | http://plane-admin.plane-one:8000 | + | plane.example.com | /api/* | http://plane-api.plane-one:8000 | + | plane.example.com | /auth/* | http://plane-api.plane-one:8000 | + | plane.example.com | /uploads/* | http://plane-minio.plane-one:9000 | + | plane-minio.example.com | / | http://plane-minio.plane-one:9090 | diff --git a/charts/plane-enterprise/questions.yml b/charts/plane-enterprise/questions.yml new file mode 100644 index 0000000..034a466 --- /dev/null +++ b/charts/plane-enterprise/questions.yml @@ -0,0 +1,356 @@ +questions: + +- variable: dockerRegistry.enabled + label: Docker Registry Enabled + type: boolean + default: true + group: "Docker Registry" + show_subquestion_if: true + subquestions: + - variable: dockerRegistry.registry + label: "Docker Registry Url" + type: string + - variable: dockerRegistry.loginid + label: "Login ID" + type: string + - variable: dockerRegistry.password + label: "Password/Token" + type: password + +- variable: planeVersion + label: Plane Version (Docker Image Tag) + type: string + default: latest + required: true + group: "Docker Registry" + subquestions: + - variable: services.web.image + label: Frontend Docker Image + type: string + required: true + default: "registry.plane.tools/plane/web-enterprise" + - variable: services.space.image + label: Space Docker Image + type: string + required: true + default: "registry.plane.tools/plane/space-enterprise" + - variable: services.admin.image + label: Admin Docker Image + type: string + required: true + default: "registry.plane.tools/plane/admin-enterprise" + - variable: services.api.image + label: Backend Docker Image + type: string + required: true + default: "registry.plane.tools/plane/backend-enterprise" + description: "Used by API, Worker, Beat-Worker" + +- variable: license.licenseServer + label: "License Server" + type: string + required: true + group: "License Setup" + subquestions: + - variable: license.licenseKey + label: "License Key" + type: string + required: true + - variable: license.licenseDomain + label: "License Domain" + type: string + required: true + +- variable: services.web.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Web Setup" + subquestions: + - variable: services.web.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: services.web.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: services.space.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Spaces Setup" + subquestions: + - variable: services.space.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: services.space.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: services.admin.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Admin Setup" + subquestions: + - variable: services.admin.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: services.admin.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: services.api.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "API Setup" + subquestions: + - variable: services.api.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: services.api.cpuLimit + label: "CPU Limit" + type: string + default: 500m + - variable: env.cors_allowed_origins + label: "CORS Allowed Origins" + type: string + default: "" + +- variable: services.worker.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Worker Setup" + subquestions: + - variable: services.worker.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: services.worker.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: services.beatworker.replicas + label: "Default Replica Count" + type: int + default: 1 + group: "Beat Worker Setup" + subquestions: + - variable: services.beatworker.memoryLimit + label: "Memory Limit" + type: string + default: 1000Mi + - variable: services.beatworker.cpuLimit + label: "CPU Limit" + type: string + default: 500m + +- variable: services.redis.local_setup + label: "Install Redis" + type: boolean + default: true + group: "Redis Setup" + subquestions: + - variable: services.redis.image + label: "Docker Image" + type: string + default: "redis:7.2.4-alpine" + show_if: "services.redis.local_setup=true" + - variable: services.redis.servicePort + label: Port + type: int + default: 6379 + show_if: "services.redis.local_setup=true" + - variable: services.redis.volumeSize + label: "Volume Size" + type: string + default: "500Mi" + show_if: "services.redis.local_setup=true" + - variable: env.remote_redis_url + label: "Remote Redis URL" + type: string + default: "redis://" + show_if: "services.redis.local_setup=false" + +- variable: services.postgres.local_setup + label: "Install Postgres" + type: boolean + default: true + group: "Postgres Setup" + # show_subquestion_if: true + subquestions: + - variable: services.postgres.image + label: "Docker Image" + type: string + default: "postgres:15.2-alpine" + show_if: "services.postgres.local_setup=true" + - variable: services.postgres.servicePort + label: Service Port + type: int + default: 5432 + show_if: "services.postgres.local_setup=true" + - variable: services.postgres.cliConnectPort + label: CLI Connect Port + type: int + show_if: "services.postgres.local_setup=true" + - variable: services.postgres.volumeSize + label: "Volume Size" + type: string + default: "5Gi" + show_if: "services.postgres.local_setup=true" + - variable: env.pgdb_username + label: "Username" + type: string + default: "plane" + show_if: "services.postgres.local_setup=true" + - variable: env.pgdb_password + label: "Password" + type: password + default: "plane" + show_if: "services.postgres.local_setup=true" + - variable: env.pgdb_name + label: "DB Name" + type: string + default: "plane" + show_if: "services.postgres.local_setup=true" + - variable: env.pgdb_remote_url + label: "Remote URL" + type: string + default: "postgresql://" + show_if: "services.postgres.local_setup=false" + +- variable: services.minio.local_setup + label: "Install Minio" + type: boolean + default: true + group: "Storage Setup" + subquestions: + - variable: services.minio.image + label: "Docker Image" + type: string + default: "minio/minio:RELEASE.2023-10-25T06-33-25Z" + show_if: "services.minio.local_setup=true" + - variable: services.minio.root_user + label: "Root User" + type: string + default: "admin" + show_if: "services.minio.local_setup=true" + - variable: services.minio.root_password + label: "Root Password" + type: password + default: "password" + show_if: "services.minio.local_setup=true" + - variable: services.minio.volumeSize + label: "Volume Size" + type: string + default: "5Gi" + show_if: "services.minio.local_setup=true" + - variable: env.aws_access_key + label: "AWS Access Key" + type: string + default: "" + show_if: "services.minio.local_setup=false" + - variable: env.aws_secret_access_key + label: "AWS Secret Key" + type: password + default: "" + show_if: "services.minio.local_setup=false" + - variable: env.aws_region + label: "AWS Region" + type: string + default: "" + show_if: "services.minio.local_setup=false" + - variable: env.aws_s3_endpoint_url + label: "AWS S3 Endpoint URL" + type: string + default: "" + show_if: "services.minio.local_setup=false" + - variable: env.docstore_bucket + label: "Bucket Name" + type: string + default: "uploads" + - variable: env.doc_upload_size_limit + label: "FIle Upload Size Limit" + type: string + default: "5242880" + +- variable: ingress.ingressClass + label: "Ingress Classname" + type: string + required: true + default: "nginx" + group: "Ingress" + subquestions: + - variable: ingress.clientMaxBodySize + label: "Max Body Size" + type: string + required: true + default: "10m" + - variable: ingress.minioHost + label: "Minio Host" + type: string + default: "plane-minio.example.com" + show_if: "services.minio.local_setup=true" + +- variable: ssl.createIssuer + label: "Create Issuer" + type: boolean + default: false + group: "Ingress" + show_subquestion_if: true + subquestions: + - variable: ssl.issuer + label: "SSL Issuer" + type: enum + options: + - "http" + - "cloudflare" + - "digitalocean" + default: "http" + - variable: ssl.server + label: "Let's Encrypt Server URL" + type: string + default: "https://acme-v02.services.api.letsencrypt.org/directory" + - variable: ssl.email + label: "Let's Encrypt Reg. Email" + type: string + default: "plane@example.com" + - variable: ssl.token + label: "Provider API Token" + type: password + default: "" + description: "Not required for 'http' issuer" + - variable: ssl.generateCerts + label: "Enable to generate certificates" + type: boolean + default: false + +- variable: env.sentry_dsn + label: "Sentry DSN" + type: string + default: "" + group: "Misc." + subquestions: + - variable: env.sentry_environment + label: "Sentry Environment" + type: string + default: "Development" + - variable: env.secret_key + label: "Random Secret Key" + type: string + required: true + default: "60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5" + - variable: env.storageClass + label: "Storage Class" + type: string + default: "longhorn" diff --git a/charts/plane-enterprise/templates/_helpers.tpl b/charts/plane-enterprise/templates/_helpers.tpl new file mode 100644 index 0000000..e5de9ec --- /dev/null +++ b/charts/plane-enterprise/templates/_helpers.tpl @@ -0,0 +1,7 @@ +{{- define "imagePullSecret" }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\"}}}" .Values.dockerRegistry.registry .Values.dockerRegistry.loginid .Values.dockerRegistry.password | b64enc }} +{{- end }} + +{{- define "hashString" -}} +{{- printf "%s%s%s%s%s" .Values.license.licenseServer .Values.license.licenseDomain .Values.license.licenseKey .Release.Namespace .Release.Name | sha256sum -}} +{{- end -}} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/certs/cert-issuers.yaml b/charts/plane-enterprise/templates/certs/cert-issuers.yaml new file mode 100644 index 0000000..5b70cf8 --- /dev/null +++ b/charts/plane-enterprise/templates/certs/cert-issuers.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.ingress.enabled .Values.ssl.createIssuer }} + +apiVersion: v1 +kind: Secret +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-issuer-api-token-secret +type: Opaque +stringData: + api-token: {{ .Values.ssl.token | default "default-api-token" | quote }} + +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-cert-issuer +spec: + acme: + email: {{ .Values.ssl.email }} + server: {{ .Values.ssl.server }} + privateKeySecretRef: + name: {{ .Release.Name }}-cert-issuer-key + solvers: + {{- if eq .Values.ssl.issuer "cloudflare" }} + - dns01: + cloudflare: + apiTokenSecretRef: + name: {{ .Release.Name }}-issuer-api-token-secret + key: api-token + {{- end }} + {{- if eq .Values.ssl.issuer "digitalocean" }} + - dns01: + digitalocean: + tokenSecretRef: + name: {{ .Release.Name }}-issuer-api-token-secret + key: api-token + {{- end }} + {{- if eq .Values.ssl.issuer "http" }} + - http01: + ingress: + ingressClassName: {{ .Values.ingress.ingressClass }} + {{- end }} + +--- +{{- end}} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/certs/certs.yaml b/charts/plane-enterprise/templates/certs/certs.yaml new file mode 100644 index 0000000..6dc26df --- /dev/null +++ b/charts/plane-enterprise/templates/certs/certs.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ingress.enabled .Values.ssl.createIssuer .Values.ssl.generateCerts }} + +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-ssl-cert +spec: + dnsNames: + - {{ .Values.license.licenseDomain | quote }} + {{- if and .Values.services.minio.local_setup .Values.ingress.minioHost }} + - {{ .Values.ingress.minioHost | quote }} + {{- end }} + issuerRef: + name: {{ .Release.Name }}-cert-issuer + secretName: {{ .Release.Name }}-ssl-cert + +{{- end}} diff --git a/charts/plane-enterprise/templates/config-secrets/app-env.yaml b/charts/plane-enterprise/templates/config-secrets/app-env.yaml new file mode 100644 index 0000000..2beac71 --- /dev/null +++ b/charts/plane-enterprise/templates/config-secrets/app-env.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-app-secrets +data: + SECRET_KEY: {{ .Values.env.secret_key | default "60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5" | b64enc | quote }} + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-app-vars +data: + PRIME_HOST: {{ .Values.license.licenseServer | quote }} + LICENSE_KEY: {{ .Values.license.licenseKey | quote }} + MACHINE_SIGNATURE: {{ include "hashString" . | quote }} + LICENSE_DOMAIN: {{ .Values.license.licenseDomain | quote }} + LICENSE_VERSION: {{ .Values.planeVersion | quote }} + DEPLOY_PLATFORM: "KUBERNETES" + + SENTRY_DSN: {{ .Values.env.sentry_dsn | default "" | quote}} + SENTRY_ENVIRONMENT: {{ .Values.env.sentry_environment | default "" | quote}} + DEBUG: "0" + DOCKERIZED: "1" + GUNICORN_WORKERS: "1" + + WEB_URL: "http://{{ .Values.license.licenseDomain }}" + + {{- if eq .Values.env.cors_allowed_origins "*"}} + CORS_ALLOWED_ORIGINS: "*" + {{- else if .Values.env.cors_allowed_origins }} + CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }},{{ .Values.env.cors_allowed_origins }}" + {{- else}} + CORS_ALLOWED_ORIGINS: "http://{{ .Values.license.licenseDomain }},https://{{ .Values.license.licenseDomain }}" + {{- end }} + + {{- if .Values.services.redis.local_setup }} + REDIS_URL: "redis://{{ .Release.Name }}-redis.{{ .Release.Namespace }}.svc.cluster.local:6379/" + {{- else }} + REDIS_URL: {{ .Values.env.remote_redis_url | default "" | quote }} + {{- end }} + + {{ if .Values.services.postgres.local_setup }} + DATABASE_URL: "postgresql://{{ .Values.env.pgdb_username }}:{{ .Values.env.pgdb_password }}@{{ .Release.Name }}-pgdb.{{ .Release.Namespace }}.svc.cluster.local/{{ .Values.env.pgdb_name }}" + {{ else if .Values.env.pgdb_remote_url }} + DATABASE_URL: {{ .Values.env.pgdb_remote_url}} + {{ else }} + DATABASE_URL: "" + {{ end }} diff --git a/charts/plane-enterprise/templates/config-secrets/doc-strore.yaml b/charts/plane-enterprise/templates/config-secrets/doc-strore.yaml new file mode 100644 index 0000000..54e6770 --- /dev/null +++ b/charts/plane-enterprise/templates/config-secrets/doc-strore.yaml @@ -0,0 +1,38 @@ + +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-doc-store-secrets +data: + {{ if .Values.services.minio.local_setup }} + MINIO_ROOT_PASSWORD: {{ .Values.services.minio.root_password | default "password" | b64enc | quote}} + AWS_SECRET_ACCESS_KEY: {{ .Values.services.minio.root_password | default "password" | b64enc | quote }} + {{ else }} + AWS_SECRET_ACCESS_KEY: {{ .Values.env.aws_secret_access_key | default "" | b64enc | quote }} + {{ end }} + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-doc-store-vars +data: + FILE_SIZE_LIMIT: {{ .Values.env.doc_upload_size_limit | default 5242880 | quote }} + AWS_S3_BUCKET_NAME: {{ .Values.env.docstore_bucket | default "" | quote }} + + {{- if .Values.services.minio.local_setup }} + MINIO_ROOT_USER: {{ .Values.services.minio.root_user | default "admin" | quote }} + AWS_ACCESS_KEY_ID: {{ .Values.services.minio.root_user | default "admin" | quote }} + AWS_S3_ENDPOINT_URL: http://{{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc.cluster.local:9000 + USE_MINIO: "1" + {{- else }} + USE_MINIO: "0" + AWS_ACCESS_KEY_ID: {{ .Values.env.aws_access_key | default "" | quote }} + AWS_REGION: {{ .Values.env.aws_region | default "" | quote }} + AWS_S3_ENDPOINT_URL: {{ .Values.env.aws_s3_endpoint_url | quote }} + {{- end }} +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/config-secrets/docker-registry.yaml b/charts/plane-enterprise/templates/config-secrets/docker-registry.yaml new file mode 100644 index 0000000..14e6b3d --- /dev/null +++ b/charts/plane-enterprise/templates/config-secrets/docker-registry.yaml @@ -0,0 +1,12 @@ +{{- if .Values.dockerRegistry.enabled }} + +apiVersion: v1 +kind: Secret +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-docker-registry-credentials +data: + .dockerconfigjson: {{ include "imagePullSecret" .}} +type: kubernetes.io/dockerconfigjson + +{{- end }} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/config-secrets/pgdb.yaml b/charts/plane-enterprise/templates/config-secrets/pgdb.yaml new file mode 100644 index 0000000..d1053a2 --- /dev/null +++ b/charts/plane-enterprise/templates/config-secrets/pgdb.yaml @@ -0,0 +1,21 @@ +{{- if .Values.services.postgres.local_setup }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-secrets +data: + POSTGRES_PASSWORD: {{ .Values.env.pgdb_password | default "plane" | b64enc | quote }} +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-vars +data: + POSTGRES_DB: {{ .Values.env.pgdb_name | default "plane" | quote }} + POSTGRES_USER: {{ .Values.env.pgdb_username | default "plane" | quote }} +--- +{{- end}} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/ingress.yaml b/charts/plane-enterprise/templates/ingress.yaml new file mode 100644 index 0000000..6283ba2 --- /dev/null +++ b/charts/plane-enterprise/templates/ingress.yaml @@ -0,0 +1,83 @@ +{{- if and .Values.ingress.enabled .Values.license.licenseDomain }} + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-ingress + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: {{ .Values.ingress.clientMaxBodySize | default "5m" | quote}} +spec: + ingressClassName: {{ .Values.ingress.ingressClass }} + rules: + - host: {{ .Values.license.licenseDomain }} + http: + paths: + - backend: + service: + port: + number: 3000 + name: {{ .Release.Name }}-web + path: / + pathType: Prefix + - backend: + service: + port: + number: 3000 + name: {{ .Release.Name }}-space + path: /spaces/ + pathType: Prefix + - backend: + service: + port: + number: 3000 + name: {{ .Release.Name }}-admin + path: /god-mode/ + pathType: Prefix + - backend: + service: + port: + number: 8000 + name: {{ .Release.Name }}-api + path: /api/ + pathType: Prefix + - backend: + service: + port: + number: 8000 + name: {{ .Release.Name }}-api + path: /auth/ + pathType: Prefix + {{- if and .Values.services.minio.local_setup .Values.env.docstore_bucket }} + - backend: + service: + port: + number: 9000 + name: {{ .Release.Name }}-minio + path: /{{ .Values.env.docstore_bucket }}/ + pathType: Prefix + {{- end }} + + {{- if and .Values.services.minio.local_setup .Values.ingress.minioHost }} + - host: {{ .Values.ingress.minioHost }} + http: + paths: + - backend: + service: + port: + number: 9090 + name: {{ .Release.Name }}-minio + path: / + pathType: Prefix + {{- end }} + {{- if .Values.ssl.generateCerts }} + tls: + - hosts: + - {{ .Values.license.licenseDomain | quote }} + {{- if and .Values.services.minio.local_setup .Values.ingress.minioHost }} + - {{ .Values.ingress.minioHost | quote }} + {{ end }} + secretName: {{ .Release.Name }}-ssl-cert + {{- end }} + +{{- end }} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/service-account.yaml b/charts/plane-enterprise/templates/service-account.yaml new file mode 100644 index 0000000..6eed2f5 --- /dev/null +++ b/charts/plane-enterprise/templates/service-account.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-srv-account +{{- if .Values.dockerRegistry.enabled }} +imagePullSecrets: + - name: {{ .Release.Name }}-docker-registry-credentials +{{- end}} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/admin.deployment.yaml b/charts/plane-enterprise/templates/workloads/admin.deployment.yaml new file mode 100644 index 0000000..639a1ae --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/admin.deployment.yaml @@ -0,0 +1,60 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-admin + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin +spec: + clusterIP: None + ports: + - name: admin-3000 + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-admin-wl +spec: + replicas: {{ .Values.services.admin.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-admin + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-admin + imagePullPolicy: Always + image: {{ .Values.services.admin.image | default "registry.plane.tools/plane/admin-enterprise" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.services.admin.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.services.admin.cpuLimit | default "500m" | quote}} + command: + - node + args: + - admin/server.js + - admin + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/api.deployment.yaml b/charts/plane-enterprise/templates/workloads/api.deployment.yaml new file mode 100644 index 0000000..7fd161b --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/api.deployment.yaml @@ -0,0 +1,80 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-api + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api +spec: + clusterIP: None + ports: + - name: api-8000 + port: 8000 + protocol: TCP + targetPort: 8000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-api-wl +spec: + replicas: {{ .Values.services.api.replicas | default 1}} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-api + imagePullPolicy: Always + image: {{ .Values.services.api.image | default "registry.plane.tools/plane/backend-enterprise" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.services.api.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.services.api.cpuLimit | default "500m" | quote}} + command: + - ./bin/docker-entrypoint-api-ee.sh + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + readinessProbe: + failureThreshold: 30 + httpGet: + path: / + port: 8000 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/beat-worker.deployment.yaml b/charts/plane-enterprise/templates/workloads/beat-worker.deployment.yaml new file mode 100644 index 0000000..b0d4317 --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/beat-worker.deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-beat-worker-wl +spec: + replicas: {{ .Values.services.beatworker.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-beat-worker + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-beat-worker + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-beat-worker + imagePullPolicy: Always + image: {{ .Values.services.api.image | default "registry.plane.tools/plane/backend-enterprise" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.services.beatworker.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.services.beatworker.cpuLimit | default "500m" | quote}} + command: + - ./bin/docker-entrypoint-beat.sh + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/migrator.job.yaml b/charts/plane-enterprise/templates/workloads/migrator.job.yaml new file mode 100644 index 0000000..4d01243 --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/migrator.job.yaml @@ -0,0 +1,38 @@ + +apiVersion: batch/v1 +kind: Job +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-api-migrate-{{ .Release.Revision }} +spec: + backoffLimit: 3 + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-api-migrate + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-api-migrate + image: {{ .Values.services.api.image | default "registry.plane.tools/plane/backend-enterprise" }}:{{ .Values.planeVersion }} + command: + - ./bin/docker-entrypoint-migrator.sh + imagePullPolicy: Always + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + restartPolicy: OnFailure + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/minio.stateful.yaml b/charts/plane-enterprise/templates/workloads/minio.stateful.yaml new file mode 100644 index 0000000..b172091 --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/minio.stateful.yaml @@ -0,0 +1,122 @@ +{{- if .Values.services.minio.local_setup }} + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-minio + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio +spec: + clusterIP: None + ports: + - name: minio-api-9000 + port: 9000 + protocol: TCP + targetPort: 9000 + - name: minio-console-9090 + port: 9090 + protocol: TCP + targetPort: 9090 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-minio-wl +spec: + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio + serviceName: {{ .Release.Name }}-minio + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-minio + spec: + containers: + - image: {{ .Values.services.minio.image }} + imagePullPolicy: Always + name: {{ .Release.Name }}-minio + stdin: true + tty: true + # command: + args: + - server + - /data + - --console-address + - :9090 + envFrom: + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + volumeMounts: + - mountPath: /data + name: pvc-{{ .Release.Name }}-minio-vol + subPath: '' + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + creationTimestamp: null + namespace: {{ .Release.Namespace }} + name: pvc-{{ .Release.Name }}-minio-vol + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.services.minio.volumeSize | default "5Gi" | quote }} + storageClassName: {{ .Values.env.storageClass | quote }} + volumeMode: Filesystem + +--- + +apiVersion: batch/v1 +kind: Job +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-minio-bucket +spec: + backoffLimit: 6 + completionMode: NonIndexed + template: + metadata: + namespace: {{ .Release.Namespace }} + spec: + restartPolicy: OnFailure + initContainers: + - name: init + image: busybox + command: ['sh', '-c', "until nslookup {{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc.cluster.local; do echo waiting for {{ .Release.Name }}-minio; sleep 2; done"] + containers: + - command: + - /bin/sh + args: + - '-c' + - >- + /usr/bin/mc config host add plane-app-minio + http://{{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc.cluster.local:9000 "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY"; + /usr/bin/mc mb plane-app-minio/$AWS_S3_BUCKET_NAME; + /usr/bin/mc anonymous set download plane-app-minio/$AWS_S3_BUCKET_NAME; exit 0; + envFrom: + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + image: minio/mc + imagePullPolicy: Always + name: {{ .Release.Name }}-minio-bucket + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + terminationGracePeriodSeconds: 120 +{{- end }} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/postgres.stateful.yaml b/charts/plane-enterprise/templates/workloads/postgres.stateful.yaml new file mode 100644 index 0000000..4cfd5c7 --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/postgres.stateful.yaml @@ -0,0 +1,98 @@ +{{- if .Values.services.postgres.local_setup }} + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb +spec: + clusterIP: None + ports: + - name: pg-{{ .Values.services.postgres.servicePort }} + port: {{ .Values.services.postgres.servicePort }} + protocol: TCP + targetPort: 5432 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb +--- +{{- if and .Values.services.postgres.cliConnectPort .Values.services.postgres.cliConnectPort | int }} +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-cli-connect +spec: + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: pg-{{ .Values.services.postgres.cliConnectPort | default 30000 }} + nodePort: {{ .Values.services.postgres.cliConnectPort | default 30000 }} + port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb + sessionAffinity: None + type: NodePort +--- +{{- end }} + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-pgdb-wl +spec: + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb + serviceName: {{ .Release.Name }}-pgdb + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-pgdb + spec: + containers: + - image: {{ .Values.services.postgres.image }} + imagePullPolicy: Always + name: {{ .Release.Name }}-pgdb + stdin: true + tty: true + env: + - name: PGDATA + value: /var/lib/postgresql/data/plane + envFrom: + - configMapRef: + name: {{ .Release.Name }}-pgdb-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-pgdb-secrets + optional: false + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: pvc-{{ .Release.Name }}-pgdb-vol + subPath: '' + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + creationTimestamp: null + namespace: {{ .Release.Namespace }} + name: pvc-{{ .Release.Name }}-pgdb-vol + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.services.postgres.volumeSize | default "5Gi" | quote }} + storageClassName: {{ .Values.env.storageClass | quote }} + volumeMode: Filesystem + +{{- end }} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/redis.stateful.yaml b/charts/plane-enterprise/templates/workloads/redis.stateful.yaml new file mode 100644 index 0000000..4a7a816 --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/redis.stateful.yaml @@ -0,0 +1,66 @@ +{{- if .Values.services.redis.local_setup }} + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-redis + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis +spec: + clusterIP: None + ports: + - name: redis-{{ .Values.services.redis.servicePort }} + port: {{ .Values.services.redis.servicePort }} + protocol: TCP + targetPort: 6379 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis +--- + +# REDIS WORKLOAD + +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-redis-wl +spec: + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis + serviceName: {{ .Release.Name }}-redis + template: + metadata: + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-redis + spec: + containers: + - image: {{ .Values.services.redis.image }} + imagePullPolicy: Always + name: {{ .Release.Name }}-redis + stdin: true + tty: true + volumeMounts: + - mountPath: /data + name: pvc-{{ .Release.Name }}-redis-vol + subPath: '' + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + creationTimestamp: null + namespace: {{ .Release.Namespace }} + name: pvc-{{ .Release.Name }}-redis-vol + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.services.redis.volumeSize | default "1Gi" | quote }} + storageClassName: {{ .Values.env.storageClass | quote }} + volumeMode: Filesystem + +{{- end }} \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/space.deployment.yaml b/charts/plane-enterprise/templates/workloads/space.deployment.yaml new file mode 100644 index 0000000..d687342 --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/space.deployment.yaml @@ -0,0 +1,60 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-space + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space +spec: + clusterIP: None + ports: + - name: space-3000 + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-space-wl +spec: + replicas: {{ .Values.services.space.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-space + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-space + imagePullPolicy: Always + image: {{ .Values.services.space.image | default "registry.plane.tools/plane/space-enterprise" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.services.space.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.services.space.cpuLimit | default "500m" | quote}} + command: + - node + args: + - space/server.js + - space + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/web.deployment.yaml b/charts/plane-enterprise/templates/workloads/web.deployment.yaml new file mode 100644 index 0000000..2cc189d --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/web.deployment.yaml @@ -0,0 +1,60 @@ + +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-web + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web +spec: + clusterIP: None + ports: + - name: web-3000 + port: 3000 + protocol: TCP + targetPort: 3000 + selector: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-web-wl +spec: + replicas: {{ .Values.services.web.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-web + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-web + imagePullPolicy: Always + image: {{ .Values.services.web.image | default "registry.plane.tools/plane/web-enterprise" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.services.web.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.services.web.cpuLimit | default "500m" | quote}} + command: + - node + args: + - web/server.js + - web + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-enterprise/templates/workloads/worker.deployment.yaml b/charts/plane-enterprise/templates/workloads/worker.deployment.yaml new file mode 100644 index 0000000..9209a2c --- /dev/null +++ b/charts/plane-enterprise/templates/workloads/worker.deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ .Release.Namespace }} + name: {{ .Release.Name }}-worker-wl +spec: + replicas: {{ .Values.services.worker.replicas | default 1 }} + selector: + matchLabels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-worker + template: + metadata: + namespace: {{ .Release.Namespace }} + labels: + app.name: {{ .Release.Namespace }}-{{ .Release.Name }}-worker + annotations: + timestamp: {{ now | quote }} + spec: + containers: + - name: {{ .Release.Name }}-worker + imagePullPolicy: Always + image: {{ .Values.services.api.image | default "registry.plane.tools/plane/backend-enterprise" }}:{{ .Values.planeVersion }} + stdin: true + tty: true + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: {{ .Values.services.worker.memoryLimit | default "1000Mi" | quote }} + cpu: {{ .Values.services.worker.cpuLimit | default "500m" | quote}} + command: + - ./bin/docker-entrypoint-worker.sh + envFrom: + - configMapRef: + name: {{ .Release.Name }}-app-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-app-secrets + optional: false + - configMapRef: + name: {{ .Release.Name }}-doc-store-vars + optional: false + - secretRef: + name: {{ .Release.Name }}-doc-store-secrets + optional: false + + serviceAccount: {{ .Release.Name }}-srv-account + serviceAccountName: {{ .Release.Name }}-srv-account + +--- \ No newline at end of file diff --git a/charts/plane-enterprise/values.yaml b/charts/plane-enterprise/values.yaml new file mode 100644 index 0000000..d1efab7 --- /dev/null +++ b/charts/plane-enterprise/values.yaml @@ -0,0 +1,112 @@ +planeVersion: v0.0.0 + +dockerRegistry: + enabled: true + registry: registry.plane.tools + loginid: '' + password: '' + +license: + licenseServer: https://prime.plane.so + licenseKey: '' + licenseDomain: 'plane.example.com' + +ingress: + enabled: true + minioHost: '' + ingressClass: 'nginx' + clientMaxBodySize: 10m + +ssl: + createIssuer: false + issuer: http # Allowed : cloudflare, digitalocean, http + token: '' # not required for http + server: https://acme-v02.api.letsencrypt.org/directory + email: plane@example.com + generateCerts: false + +services: + redis: + local_setup: true + image: registry.plane.tools/plane/redis:7.2.4-alpine + servicePort: 6379 + volumeSize: 500Mi + + postgres: + local_setup: true + image: registry.plane.tools/plane/postgres:15.5-alpine + servicePort: 5432 + cliConnectPort: '' + volumeSize: 2Gi + + minio: + local_setup: true + image: registry.plane.tools/plane/minio:latest + volumeSize: 3Gi + root_user: admin + root_password: password + + web: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: registry.plane.tools/plane/web-enterprise + + space: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: registry.plane.tools/plane/space-enterprise + + admin: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: registry.plane.tools/plane/admin-enterprise + + api: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + image: registry.plane.tools/plane/backend-enterprise + + worker: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + + beatworker: + replicas: 1 + memoryLimit: 1000Mi + cpuLimit: 500m + +env: + pgdb_username: plane + pgdb_password: plane + pgdb_name: plane + pgdb_remote_url: '' #INCASE OF REMOTE PG DB URL ONLY + + storageClass: longhorn + + # NEXT_PUBLIC_DEPLOY_URL: '' + # REDIS + remote_redis_url: '' #INCASE OF REMOTE REDIS ONLY + # POSTGRES DB VALUES + + # DATA STORE + docstore_bucket: uploads + doc_upload_size_limit: '5242880' # 5MB + + # REQUIRED IF MINIO LOCAL SETUP IS FALSE + aws_access_key: '' + aws_secret_access_key: '' + aws_region: '' + aws_s3_endpoint_url: '' + + secret_key: "60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5" + + sentry_dsn: '' + sentry_environment: '' + + cors_allowed_origins: '' + instance_admin_email: '' diff --git a/content/plane-ce.md b/content/plane-ce.md new file mode 100644 index 0000000..0d369ab --- /dev/null +++ b/content/plane-ce.md @@ -0,0 +1,218 @@ +## Pre-requisite +- A working Kubernetes cluster +- `kubectl` and `helm` on the client system that you will use to install our Helm charts + +## Installing Plane + +1. Open Terminal or any other command-line app that has access to Kubernetes tools on your local system. +2. Add Helm Repo + ```bash + helm repo add makeplane https://helm.plane.so/ + ``` +3. Set-up and customization
+ - Quick set-up
+ This is the fastest way to deploy Plane with default settings. This will create stateful deployments for Postgres, Redis, and Minio with a persistent volume claim using the `longhorn` storage class. This also sets up the ingress routes for you using `nginx` ingress class. + > To customize this, see `Custom ingress routes` below. + + Continue to be on the same Terminal window as you have so far, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install plane-app makeplane/plane-ce \ + --create-namespace \ + --namespace plane-ce \ + --set planeVersion=stable \ + --set ingress.appHost="plane.example.com" \ + --set ingress.minioHost="plane-minio.example.com" \ + --set ingress.ingressClass=nginx \ + --set postgres.storageClass=longhorn \ + --set redis.storageClass=longhorn \ + --set minio.storageClass=longhorn \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + + > This is the minimum required to set up Plane-CE. You can change the default namespace from `plane-ce`, the default appname + from `plane-app`, the default storage class from `[postgres, redis, minio].storageClass`, and the default ingress class from `ingress.ingressClass` to + whatever you would like to.

+ You can also pass other settings referring to `Configuration Settings` section. + + - Advance set-up
+ For more control over your set-up, run the script below to download the `values.yaml` file and and edit using any editor like Vim or Nano. + + ```bash + helm show values makeplane/plane-ce > values.yaml + vi values.yaml + ``` + > See `Available customizations` for more details. + + After saving the `values.yaml` file, continue to be on the same Terminal window as on the previous steps, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install plane-app makeplane/plane-ce \ + --create-namespace \ + --namespace plane-ce \ + -f values.yaml \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + +## Configuration Settings Available + +### Plane Version +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| planeVersion | stable | Yes | | + +### Ingress Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| ingress.appHost | 'plane.example.com' | Yes | | +| ingress.minioHost | 'plane-minio.example.com' | | (Optional) Required to open minio console interface | +| ingress.ingressClass | 'nginx' | Yes | can be any of the supported ingress controller class (eg. nginx, traefik, etc) | +| ingress.clientMaxBodySize | 5m | Yes | This is set at the ingress controller level to support max data from client. | + +### SSL Settings +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| ssl.createIssuer | false | | Set it to true to create Let's Encrypt Service based issuer | +| ssl.issuer | http | | (Yes, if createIssuer = true) Allowed - cloudflare, digitalocean, http | +| ssl.token | | | (Yes, if createIssuer = true) api token of dns provider, not required for http | +| ssl.server | https://acme-v02.api.letsencrypt.org/directory | | (Yes, if createIssuer = true)Lets Encrypt SSL Generation API. Staging: https://acme-staging-v02.api.letsencrypt.org/directory | +| ssl.email | plane-admin@example.com | | (Yes, if createIssuer = true) Required by Let's Encrypt. Change to a valid email id | +| ssl.generateCerts | false | | | + +### Postgress DB Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| postgres.local_setup | true | | Plane uses `postgres` as the primary database to store all the transactional data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `postgres`. Mark it as `false` when using a remotely hosted database | +| postgres.image | postgres:15.5-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `postgres`. (must be set when `postgres.local_setup=true`) | +| postgres.servicePort | 5432 | | This key sets the default port number to be used while setting up stateful deployment of `postgres`. | +| postgres.cliConnectPort | | | | | If you intend to access the hosted stateful deployment of postgres using any of the client tools (e.g Postico), this key helps you expose the port. The mentioned port must not be occupied by any other applicaiton | +| postgres.volumeSize | 5Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | +| env.pgdb_username | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the username for the stateful deployment. | +| env.pgdb_password | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the password for the stateful deployment. | +| env.pgdb_name | plane | | Database name to be used while setting up stateful deployment of `Postgres` | +| env.pgdb_remote_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `postgres.local_setup` to `false` and set this key with remote connection url. | +| postgres.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + + +### Redis Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| redis.local_setup | true | | Plane uses `redis` to cache the session authentication and other static data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `redis`. Mark it as `false` when using a remotely hosted database | +| redis.image | redis:6.2.7-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `redis`. (must be set when `redis.local_setup=true`) | +| redis.servicePort | 6379 | | This key sets the default port number to be used while setting up stateful deployment of `redis`. | +| redis.volumeSize | 1Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | +| env.remote_redis_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `redis.local_setup` to `false` and set this key with remote connection url. | +| redis.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + + +### Doc Store (Minio/S3) Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| minio.local_setup | true | | Plane uses `minio` as the default file storage drive. This storage can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws S3 or similar services). Set this to `true` when you choose to setup stateful deployment of `postgres`. Mark it as `false` when using a remotely hosted database | +| minio.image | minio/minio:latest | | Using this key, user must provide the docker image name to setup the stateful deployment of `minio`. (must be set when `minio.local_setup=true`) | +| minio.volumeSize | 5Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | +| minio.root_user | admin | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the username for the stateful deployment. | +| minio.root_password | password | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the password for the stateful deployment. | +| env.docstore_bucket | uploads | Yes | Storage bucket name is required as part of configuration. This is where files will be uploaded irrespective of if you are using `Minio` or external `S3` (or compatible) storage service | +| env.doc_upload_size_limit | 5242880 | Yes | Document Upload Size Limit (default to 5Mb) | +| env.aws_access_key | | | External `S3` (or compatible) storage service provides `access key` for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| env.aws_secret_access_key | | | External `S3` (or compatible) storage service provides `secret access key` for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| env.aws_region | | | External `S3` (or compatible) storage service providers creates any buckets in user selected region. This is also shared with the user as `region` for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| env.aws_s3_endpoint_url | | | External `S3` (or compatible) storage service providers shares a `endpoint_url` for the integration purpose for the application to connect and do the necessary upload/download operations. To be provided when `minio.local_setup=false` | +| minio.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + +### Web Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| web.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| web.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| web.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| web.image | makeplane/plane-frontend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + +### Space Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| space.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| space.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| space.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| space.image | makeplane/plane-space | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + +### Admin Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| admin.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| admin.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| admin.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| admin.image | makeplane/plane-admin | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + +### API Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| api.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| api.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| api.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| api.image | makeplane/plane-backend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | +| env.sentry_dsn | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry provided DSN for this integration. | +| env.sentry_environment | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry environment name (as configured in Sentry) for this integration. | + + +### Worker Deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| worker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| worker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| worker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| worker.image | makeplane/plane-backend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + +### Beat-Worker deployment +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| beatworker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | +| beatworker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | +| beatworker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | +| beatworker.image | makeplane/plane-backend | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + + +### Ingress and SSL Setup +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| ingress.enabled | true | | Ingress setup in kubernetes is a common practice to expose application to the intended audience. Set it to `false` if you are using external ingress providers like `Cloudflare` | +| ingress.appHost | 'plane.example.com' | Yes | The fully-qualified domain name (FQDN) in the format `sudomain.domain.tld` or `domain.tld` that the license is bound to. It is also attached to your `ingress` host to access Plane. | +| ingress.minioHost | 'plane-minio.example.com' | | Based on above configuration, if you want to expose the `minio` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. | +| ingress.ingressClass | 'nginx' | Yes | Kubernetes cluster setup comes with various options of `ingressClass`. Based on your setup, set this value to the right one (eg. nginx, traefik, etc). Leave it to default in case you are using external ingress provider. | +| ingress.clientMaxBodySize | 5m | Yes | Ingress controllers comes with various configuration options. One of which is `max payload size limit`. Setting this value lets you change the default value to user required. | +| ssl.createIssuer | false | | Kubernets cluster setup supports creating `issuer` type resource. After deployment, this is step towards creating secure access to the ingress url. Issuer is required for you generate SSL certifiate. Kubernetes can be configured to use any of the certificate authority to generate SSL (depending on CertManager configuration). Set it to `true` to create the issuer. Applicable only when `ingress.enabled=true` | +| ssl.issuer | http | | CertManager configuration allows user to create issuers using `http` or any of the other DNS Providers like `cloudflare`, `digitalocean`, etc. As of now Plane supports `http`, `cloudflare`, `digitalocean` | +| ssl.token | | | To create issuers using DNS challenge, set the issuer api token of dns provider like cloudflare` or `digitalocean`(not required for http) | +| ssl.server | https://acme-v02.api.letsencrypt.org/directory | | Issuer creation configuration need the certificate generation authority server url. Default URL is the `Let's Encrypt` server | +| ssl.email | plane@example.com | | Certificate generation authority needs a valid email id before generating certificate. Required when `ssl.createIssuer=true` | +| ssl.generateCerts | false | | After creating the issuers, user can still not create the certificate untill sure of configuration. Setting this to `true` will try to generate SSL certificate and associate with ingress. Applicable only when `ingress.enabled=true` and `ssl.createIssuer=true` | + + +### Common Environment Settings +| Setting | Default | Required | Description | +|--- |:---: |:---: |--- | +| env.secret_key | 60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 | Yes | This must a random string which is used for hashing/encrypting the sensitive data within the application. Once set, changing this might impact the already hashed/encrypted data | + + +## Custom Ingress Routes + +If you are planning to use 3rd party ingress providers, here is the available route configuration + +| Host | Path | Service | +|--- |:---: |--- | +| plane.example.com | / | http://plane-web.plane-ce:3000 | +| plane.example.com | /spaces/* | http://plane-space.plane-ce:3000 | +| plane.example.com | /god-mode/* | http://plane-admin.plane-ce:8000 | +| plane.example.com | /api/* | http://plane-api.plane-ce:8000 | +| plane.example.com | /auth/* | http://plane-api.plane-ce:8000 | +| plane.example.com | /uploads/* | http://plane-minio.plane-ce:9000 | +| plane-minio.example.com | / | http://plane-minio.plane-ce:9090 | diff --git a/content/plane-one.md b/content/plane-one.md new file mode 100644 index 0000000..01bdc99 --- /dev/null +++ b/content/plane-one.md @@ -0,0 +1,231 @@ +## Pre-requisite +- A Plane One license
+ > If you don’t have a license, get it here. +- A working Kubernetes cluster +- `kubectl` and `helm` on the client system that you will use to install our Helm charts + +## Installing Plane One + + 1. Open Terminal or any other command-line app that has access to Kubernetes tools on your local system. + 2. Set the following environment variables.
+ Copy the format of constants below, paste it on Terminal to start setting environment variables, set values for each variable, and hit ENTER or RETURN. + > You will get the values for the variables from [prime.plane.so](https://prime.plane.so) under the Kuberntes tab of your license's details page. When installing Plane One for the first time, remember to specify a domain name. + + ```bash + LICENSE_KEY= + REG_USER_ID= + REG_PASSWORD=<******> + PLANE_VERSION= + DOMAIN_NAME= + ``` + + 3. Add Plane helm chart repo
+ Continue to be on the same Terminal window as with the previous steps, copy the code below, paste it on Terminal, and hit ENTER or RETURN. + + ```bash + helm repo add plane https://helm.plane.so/ + ``` + + 4. Set-up and customization
+ - Quick set-up
+ This is the fastest way to deploy Plane with default settings. This will create stateful deployments for Postgres, Redis, and Minio with a persistent volume claim using the `longhorn` storage class. This also sets up the ingress routes for you using `nginx` ingress class. + > To customize this, see `Custom ingress routes` below. + + Continue to be on the same Terminal window as you have so far, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install one-app plane/plane-enterprise \ + --create-namespace \ + --namespace plane-one \ + --set dockerRegistry.loginid=${REG_USER_ID} \ + --set dockerRegistry.password=${REG_PASSWORD} \ + --set license.licenseKey=${LICENSE_KEY} \ + --set license.licenseDomain=${DOMAIN_NAME} \ + --set license.licenseServer=https://prime.plane.so \ + --set planeVersion=${PLANE_VERSION} \ + --set ingress.ingressClass=nginx \ + --set env.storageClass=longhorn \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + + > This is the minimum required to set up Plane One. You can change the default namespace from `plane-one`, the default appname + from `one-app`, the default storage class from `env.storageClass`, and the default ingress class from `ingress.ingressClass` to + whatever you would like to.

+ You can also pass other settings referring to `Configuration Settings` section. + + - Advance set-up
+ For more control over your set-up, run the script below to download the `values.yaml` file and and edit using any editor like Vim or Nano. + + ```bash + helm show values plane/plane-enterprise > values.yaml + vi values.yaml + ``` + + Make sure you set the minimum required values as below. + - `planeVersion: ` + - `dockerRegistry.loginid: ` + - `dockerRegistry.password: ` + - `license.licenseKey: ` + - `license.licenseDomain: ` + - `license.licenseServer: https://prime.plane.so` + - `ingress.ingressClass: ` + - `env.storageClass: ` + + > See `Available customizations` for more details. + + After saving the `values.yaml` file, continue to be on the same Terminal window as on the previous steps, copy the code below, and paste it on your Terminal screen. + + ```bash + helm install one-app plane/plane-enterprise \ + --create-namespace \ + --namespace plane-one \ + -f values.yaml \ + --timeout 10m \ + --wait \ + --wait-for-jobs + ``` + + +## Available customizations + + ### Docker registry + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | dockerRegistry.enabled | true | Yes | Plane uses a private Docker registry which needs authenticated login. This must be set to `true` to install Plane One. | + | dockerRegistry.registry | registry.plane.tools | Yes | The host that will serve the required Docker images; Don't change this. | + | dockerRegistry.loginid | | Yes | Sets the `loginid` for the Docker registry. This is the same as the REG_USER_ID value on prime. plane.so | + | dockerRegistry.password | | Yes | Sets the `password` for the Docker registry. This is the same as the REG_PASSWORD value on prime.plane.so | + + ### License + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | planeVersion | vX.XX.X | Yes | Specifies the version of Plane to be deployed. Copy this from prime.plane.so. | + | license.licenseServer | https://prime.plane.so | Yes | Sets the value of the `licenseServer` that gets you your license and validates it periodically. Don't change this. | + | license.licenseKey | | Yes | Holds your license key to Plane One. Copy this from prime.plane.so. | + | license.licenseDomain | 'plane.example.com' | Yes | The fully-qualified domain name (FQDN) in the format `sudomain.domain.tld` or `domain.tld` that the license is bound to. It is also attached to your `ingress` host to access Plane. | + + + ### Postgres + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.postgres.local_setup | true | | Plane uses `postgres` as the primary database to store all the transactional data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `postgres`. Mark it as `false` when using a remotely hosted database | + | services.postgres.image | registry.plane.tools/plane/postgres:15.5-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `postgres`. (must be set when `services.postgres.local_setup=true`) | + | services.postgres.servicePort | 5432 | | This key sets the default port number to be used while setting up stateful deployment of `postgres`. | + | services.postgres.cliConnectPort | | | If you intend to access the hosted stateful deployment of postgres using any of the client tools (e.g Postico), this key helps you expose the port. The mentioned port must not be occupied by any other applicaiton | + | services.postgres.volumeSize | 2Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | + | env.pgdb_username | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the username for the stateful deployment. | + | env.pgdb_password | plane | | Database credentials are requried to access the hosted stateful deployment of `postgres`. Use this key to set the password for the stateful deployment. | + | env.pgdb_name | plane | | Database name to be used while setting up stateful deployment of `Postgres` | + | env.pgdb_remote_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `services.postgres.local_setup` to `false` and set this key with remote connection url. | + + + ### Redis Setup + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.redis.local_setup | true | | Plane uses `redis` to cache the session authentication and other static data. This database can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws rds or similar services). Set this to `true` when you choose to setup stateful deployment of `redis`. Mark it as `false` when using a remotely hosted database | + | services.redis.image | registry.plane.tools/plane/redis:7.2.4-alpine | | Using this key, user must provide the docker image name to setup the stateful deployment of `redis`. (must be set when `services.redis.local_setup=true`) | + | services.redis.servicePort | 6379 | | This key sets the default port number to be used while setting up stateful deployment of `redis`. | + | services.redis.volumeSize | 500Mi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | + | env.remote_redis_url | | | Users can also decide to use the remote hosted database and link to Plane deployment. Ignoring all the above keys, set `services.redis.local_setup` to `false` and set this key with remote connection url. | + + ### Doc Store (Minio/S3) Setup + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.minio.local_setup | true | | Plane uses `minio` as the default file storage drive. This storage can be hosted within kubernetes as part of helm chart deployment or can be used as hosted service remotely (e.g. aws S3 or similar services). Set this to `true` when you choose to setup stateful deployment of `minio`. Mark it as `false` when using a remotely hosted database | + | services.minio.image | registry.plane.tools/plane/minio:latest | | Using this key, user must provide the docker image name to setup the stateful deployment of `minio`. (must be set when `services.minio.local_setup=true`) | + | services.minio.volumeSize | 3Gi | | While setting up the stateful deployment, while creating the persistant volume, volume allocation size need to be provided. This key helps you set the volume allocation size. Unit of this value must be in Mi (megabyte) or Gi (gigabyte) | + | services.minio.root_user | admin | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the username for the stateful deployment. | + | services.minio.root_password | password | | Storage credentials are requried to access the hosted stateful deployment of `minio`. Use this key to set the password for the stateful deployment. | + | env.docstore_bucket | uploads | Yes | Storage bucket name is required as part of configuration. This is where files will be uploaded irrespective of if you are using `Minio` or external `S3` (or compatible) storage service | + | env.doc_upload_size_limit | 5242880 | Yes | Document Upload Size Limit (default to 5Mb) | + | env.aws_access_key | | | External `S3` (or compatible) storage service provides `access key` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + | env.aws_secret_access_key | | | External `S3` (or compatible) storage service provides `secret access key` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + | env.aws_region | | | External `S3` (or compatible) storage service providers creates any buckets in user selected region. This is also shared with the user as `region` for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + | env.aws_s3_endpoint_url | | | External `S3` (or compatible) storage service providers shares a `endpoint_url` for the integration purpose for the application to connect and do the necessary upload/download operations. To be provided when `services.minio.local_setup=false` | + + + ### Web Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.web.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.web.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.web.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.web.image | registry.plane.tools/plane/web-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + ### Space Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.space.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.space.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.space.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.space.image | registry.plane.tools/plane/space-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + ### Admin Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.admin.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.admin.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.admin.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.admin.image | registry.plane.tools/plane/admin-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + + ### API Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.api.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.api.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.api.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + | services.api.image | registry.plane.tools/plane/backend-enterprise | | This deployment needs a preconfigured docker image to function. Docker image name is provided by the owner and must not be changed for this deployment | + | env.sentry_dsn | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry provided DSN for this integration. | + | env.sentry_environment | | | (optional) API service deployment comes with some of the preconfigured integration. Sentry is one among those. Here user can set the Sentry environment name (as configured in Sentry) for this integration. | + + ### Worker Deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.worker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.worker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.worker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + + ### Beat-Worker deployment + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | services.beatworker.replicas | 1 | Yes | Kubernetes helps you with scaling up/down the deployments. You can run 1 or more pods for each deployment. This key helps you setting up number of replicas you want to run for this deployment. It must be >=1 | + | services.beatworker.memoryLimit | 1000Mi | | Every deployment in kubernetes can be set to use maximum memory they are allowed to use. This key sets the memory limit for this deployment to use. | + | services.beatworker.cpuLimit | 500m | | Every deployment in kubernetes can be set to use maximum cpu they are allowed to use. This key sets the cpu limit for this deployment to use. | + + ### Ingress and SSL Setup + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | ingress.enabled | true | | Ingress setup in kubernetes is a common practice to expose application to the intended audience. Set it to `false` if you are using external ingress providers like `Cloudflare` | + | ingress.minioHost | 'plane-services.minio.example.com' | | Based on above configuration, if you want to expose the `minio` web console to set of users, use this key to set the `host` mapping or leave it as `EMPTY` to not expose interface. | + | ingress.ingressClass | 'nginx' | Yes | Kubernetes cluster setup comes with various options of `ingressClass`. Based on your setup, set this value to the right one (eg. nginx, traefik, etc). Leave it to default in case you are using external ingress provider. | + | ingress.clientMaxBodySize | 5m | Yes | Ingress controllers comes with various configuration options. One of which is `max payload size limit`. Setting this value lets you change the default value to user required. | + | ssl.createIssuer | false | | Kubernets cluster setup supports creating `issuer` type resource. After deployment, this is step towards creating secure access to the ingress url. Issuer is required for you generate SSL certifiate. Kubernetes can be configured to use any of the certificate authority to generate SSL (depending on CertManager configuration). Set it to `true` to create the issuer. Applicable only when `ingress.enabled=true` | + | ssl.issuer | http | | CertManager configuration allows user to create issuers using `http` or any of the other DNS Providers like `cloudflare`, `digitalocean`, etc. As of now Plane supports `http`, `cloudflare`, `digitalocean` | + | ssl.token | | | To create issuers using DNS challenge, set the issuer api token of dns provider like cloudflare` or `digitalocean`(not required for http) | + | ssl.server | https://acme-v02.api.letsencrypt.org/directory | | Issuer creation configuration need the certificate generation authority server url. Default URL is the `Let's Encrypt` server | + | ssl.email | plane@example.com | | Certificate generation authority needs a valid email id before generating certificate. Required when `ssl.createIssuer=true` | + | ssl.generateCerts | false | | After creating the issuers, user can still not create the certificate untill sure of configuration. Setting this to `true` will try to generate SSL certificate and associate with ingress. Applicable only when `ingress.enabled=true` and `ssl.createIssuer=true` | + + + ### Common Environment Settings + | Setting | Default | Required | Description | + |--- |:---: |:---: |--- | + | env.storageClass | longhorn | | Creating the persitant volumes for the stateful deployments needs the `storageClass` name. Set the correct value as per your kubernetes cluster configuration. | + | env.secret_key | 60gp0byfz2dvffa45cxl20p1scy9xbpf6d8c5y0geejgkyp1b5 | Yes | This must a random string which is used for hashing/encrypting the sensitive data within the application. Once set, changing this might impact the already hashed/encrypted data | + + + ## Custom Ingress Routes + + If you are planning to use 3rd party ingress providers, here is the available route configuration + + | Host | Path | Service | + |--- |:---: |--- | + | plane.example.com | / | http://plane-web.plane-one:3000 | + | plane.example.com | /spaces/* | http://plane-space.plane-one:3000 | + | plane.example.com | /god-mode/* | http://plane-admin.plane-one:8000 | + | plane.example.com | /api/* | http://plane-api.plane-one:8000 | + | plane.example.com | /auth/* | http://plane-api.plane-one:8000 | + | plane.example.com | /uploads/* | http://plane-minio.plane-one:9000 | + | plane-minio.example.com | / | http://plane-minio.plane-one:9090 | diff --git a/cr.yaml b/cr.yaml new file mode 100644 index 0000000..b67a65c --- /dev/null +++ b/cr.yaml @@ -0,0 +1,12 @@ +sign: false + +# Enable automatic generation of release notes using GitHubs release notes generator. +# see: https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes +generate-release-notes: true + +# package-path: dist/packages +# index-path: dist/index.yaml +# skip-existing: true +git-base-url: https://github.com/gitapi/ +git-upload-url: https://uploads.github.com/ + diff --git a/images/favicon.png b/images/favicon.png new file mode 100644 index 0000000..be1a753 Binary files /dev/null and b/images/favicon.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..843cd70 --- /dev/null +++ b/index.html @@ -0,0 +1,77 @@ + + + + + + + Plane Helm Charts + + + + + + + +
+
+
Plane Helm Chart
+
+ + +
+
+
+ Plane is a simple, extensible, open source project and product management tool. + It allows users to start with a basic task tracking tool and gradually adopt various project management frameworks + like Agile, Waterfall, and many more. +
+ +
+
+ +
+
+ +
+
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/metadata/artifacthub-pkg.yml b/metadata/artifacthub-pkg.yml new file mode 100644 index 0000000..09f2152 --- /dev/null +++ b/metadata/artifacthub-pkg.yml @@ -0,0 +1,68 @@ +# # Artifact Hub package metadata file +# version: A SemVer 2 version (required) +# name: The name of the package (only alphanum, no spaces, dashes allowed) (required) +# alternativeName: Alternative name of the package (optional) +# category: Category of the package (optional) # One of: ai-machine-learning, database, integration-delivery, monitoring-logging, networking, security, storage, streaming-messaging or skip-prediction +# displayName: The name of the package nicely formatted (required) +# createdAt: The date this package was created (RFC3339 layout) (required) +# description: A short description of the package (required) +# logoPath: Path to the logo image file relative to the package directory (optional, but it improves package visibility) +# logoURL: The URL of the logo image (optional, an alternative to logoPath if the image is hosted somewhere else) +# digest: String that uniquely identifies this package version (optional) +# license: SPDX identifier of the package license (https://spdx.org/licenses/) (optional) +# homeURL: The URL of the project home page (optional) +# appVersion: The version of the app that this contains (optional) +# containersImages: # (optional) +# - name: Image identifier (optional) +# image: The format should match ${REGISTRYHOST}/${USERNAME}/${NAME}:${TAG} +# whitelisted: When set to true, this image won't be scanned for security vulnerabilities +# platforms: # (optional) +# - A list of platforms supported by this image (linux/amd64, etc) +# containsSecurityUpdates: Whether this package version contains security updates (optional, boolean) +# operator: Whether this package is an Operator (optional, boolean) +# deprecated: Whether this package is deprecated (optional, boolean) +# prerelease: Whether this package version is a pre-release (optional, boolean) +# keywords: # (optional) +# - A list of keywords about this package +# - Using one or more categories names as keywords will improve package visibility +# links: # (optional) +# - name: Title of the link (required for each link) +# url: URL of the link (required for each link) +# readme: | # (optional, can be provided from a README.md file as well) +# Package documentation in markdown format + +# Content added here will be rendered on Artifact Hub +# install: | # (optional) +# Brief install instructions in markdown format + +# Content added here will be displayed when the INSTALL button on the package details page is clicked. +# changes: # (optional - it is also possible to provide a list of strings with just the descriptions instead of using objects) +# - kind: added # Supported kinds are: added, changed, deprecated, removed, fixed and security +# description: cool feature +# links: +# - name: GitHub Issue +# url: https://github.com/issue-url +# - name: GitHub PR +# url: https://github.com/pr-url +# - kind: fixed +# description: minor bug +# links: +# - name: GitHub Issue +# url: https://github.com/issue-url +# maintainers: # (optional) +# - name: The maintainer name (required for each maintainer) +# email: The maintainer email (required for each maintainer) +# provider: # (optional) +# name: The name of the individual, company, or service that provides this package +# ignore: # (optional, used to ignore some falco rules or opa policies files in a package) +# - lib # Entries use .gitignore syntax) +# recommendations: # (optional, list of recommended packages) +# - url: https://artifacthub.io/packages/helm/artifact-hub/artifact-hub +# screenshots: # (optional, list of screenshots) +# - title: Sample screenshot 1 +# url: https://example.com/screenshot1.jpg +# - title: Sample screenshot 2 +# url: https://example.com/screenshot2.jpg +# annotations: # (optional, keys and values must be strings) +# key1: value1 +# key2: value2 \ No newline at end of file