diff --git a/404.html b/404.html index 7a6aadd..ff610c5 100644 --- a/404.html +++ b/404.html @@ -8,14 +8,14 @@ Page Not Found | Silta - +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/c5b54d81.23d5aa89.js b/c5b54d81.04d52404.js similarity index 65% rename from c5b54d81.23d5aa89.js rename to c5b54d81.04d52404.js index bb67b46..2769bc9 100644 --- a/c5b54d81.23d5aa89.js +++ b/c5b54d81.04d52404.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[21],{105:function(e,n,t){"use strict";t.d(n,"a",(function(){return p})),t.d(n,"b",(function(){return g}));var r=t(0),a=t.n(r);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=a.a.createContext({}),u=function(e){var n=a.a.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=u(e.components);return a.a.createElement(c.Provider,{value:n},e.children)},b={inlineCode:"code",wrapper:function(e){var n=e.children;return a.a.createElement(a.a.Fragment,{},n)}},d=a.a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(t),d=r,g=p["".concat(s,".").concat(d)]||p[d]||b[d]||o;return t?a.a.createElement(g,i(i({ref:n},c),{},{components:t})):a.a.createElement(g,i({ref:n},c))}));function g(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,s=new Array(o);s[0]=d;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i.mdxType="string"==typeof e?e:r,s[1]=i;for(var c=2;c=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=a.a.createContext({}),u=function(e){var n=a.a.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return a.a.createElement(c.Provider,{value:n},e.children)},b={inlineCode:"code",wrapper:function(e){var n=e.children;return a.a.createElement(a.a.Fragment,{},n)}},d=a.a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),p=u(t),d=r,m=p["".concat(i,".").concat(d)]||p[d]||b[d]||o;return t?a.a.createElement(m,s(s({ref:n},c),{},{components:t})):a.a.createElement(m,s({ref:n},c))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,i=new Array(o);i[0]=d;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s.mdxType="string"==typeof e?e:r,i[1]=s;for(var c=2;c Silta project build process | Silta - + @@ -43,7 +43,7 @@ that it gets included from your settings.php.

Lando configuration file#

This file is not actually needed to deploy a project to Silta, but it configures the project for usage in local developemnt environments with Lando. Silta doesn't specify how you should run your code locally, but Lando and Silta have compatible of working.

There is no plan to consolidate Silta and Lando, as they have very different requirements (for example Lando mounts the codebase as a volume, whereas Silta copies it into dedicated Docker images).

phpcs.xml#

This file is also not required for Silta, but we use phpcs for validation by default.

- + diff --git a/docs/circleci-conf-examples/index.html b/docs/circleci-conf-examples/index.html index 944c8b4..faa7e99 100644 --- a/docs/circleci-conf-examples/index.html +++ b/docs/circleci-conf-examples/index.html @@ -8,7 +8,7 @@ CircleCI configuration examples | Silta - + @@ -35,7 +35,7 @@ You should also update the drupal specific deployment steps to include the appropriate silta-cms.yml files.

Note 2: Add nested silta configurations (i.e. web/themes/custom/yourtheme/silta/) and non-public files located in web subdirectory to .dockerignore file, to exclude them from nginx and php images.

See https://wunderio.github.io/silta/docs/silta-examples for example on how to split the silta configuration part for this kind of setup. There is also a more complex example in [https://github.com/wunderio/decoupled-project](decoupled-project -template)

- + diff --git a/docs/circleci-context/index.html b/docs/circleci-context/index.html index d4e6c07..851911c 100644 --- a/docs/circleci-context/index.html +++ b/docs/circleci-context/index.html @@ -8,7 +8,7 @@ circleci-context | Silta - + @@ -23,7 +23,7 @@

circleci-context

Silta CircleCI Context variables#

Kubernetes cluster connection data#

  • CLUSTER_NAME: Used for kubernetes connection. Example: silta.
  • KUBECTL_CONFIG: Optional when dashboard rbac autocreation is used. Otherwise required, contains kubectl config file contents.
  • KUBECONFIG: Optional, defaults to ~/.kube/config.
  • CLUSTER_TYPE Options: aks, eks, minikube, microk8s. Default value: gke.

Cluster connection, GKE specifics

  • USE_GKE_GCLOUD_AUTH_PLUGIN: Mandatory for GKE clusters <1.26, set to True.

Used for gcloud authentication when environment variables are available (when kubectl config is undefined)

  • GCLOUD_PROJECT_NAME: GCP project name. Example: silta-test-123456.
  • GCLOUD_COMPUTE_REGION: Optional. Example: europe-north1.
  • GCLOUD_COMPUTE_ZONE: Optional. Example europe-north1-a.

Cluster connection, AKS specifics

  • AKS_RESOURCE_GROUP: Example: siltaResourceGroup.
  • AKS_SP_APP_ID: ServicePrincipal Application ID.
  • AKS_SP_PASSWORD
  • AKS_TENANT_ID

Chart variables (drupal, simple, frontend)#

  • CLUSTER_DOMAIN: Used as base domain for deployments. Example: silta-test.wdr.io.
  • DB_ROOT_PASS: MySQL DB password. Used on first deployment for account creation and for connection. Do not change after site is deployed!
  • DB_USER_PASS: MySQL DB password. Used on first deployment for account creation and for connection. Do not change after site is deployed!
  • SECRET_KEY: Used for secrets encryption. Do not change without re-encoding secrets with the new key or deploymens will fail.
  • GITAUTH_USERNAME: Used for getting list of allowed ssh keys. See gitAuth.keyserver variables in silta-cluster chart for more details.
  • GITAUTH_PASSWORD: Used for getting list of allowed ssh keys. See gitAuth.keyserver variables in silta-cluster chart for more details.
  • VPN_IP: Injected into nginx.noauthips variables for allowlisting basic auth requests.
  • VPC_NATIVE: Adds vpc native (NEG) annotation for GKE clusters (cloud.google.com/neg). Set to true on GKE.

Container image registry#

  • IMAGE_REPO_HOST: Example: europe-north1-docker.pkg.dev.
  • DOCKER_REPO_HOST: Use IMAGE_REPO_HOST instead!
  • DOCKER_REPO_PROJ: Example: silta-test-123456/images.

Image registry, GCR & AR specifics

  • GOOGLE_APPLICATION_CREDENTIALS: Example: /home/circleci/gcp-service-key.json.
  • GCLOUD_KEY_JSON: Plaintex serviceaccount key, newlines replaced with "\n".
  • SILTA_USE_GCLOUD: Force using gcloud cli for existing image lookups. Will be removed soon.

Image registry, ACR specifics Note: This uses az login currently, change in progress.

  • AKS_RESOURCE_GROUP: Example: siltaResourceGroup.
  • AKS_SP_APP_ID: ServicePrincipal Application ID.
  • AKS_SP_PASSWORD
  • AKS_TENANT_ID

Silta dashboard RBAC creation#

  • SILTA_CLUSTER_ID: Dashboard configuration machine name. Example: silta_test.
  • SILTA_DASHBOARD_URL: Dashboard url. Basicauth in url (or proxy ip/cloud nat + whitelist). Example: https://username:password@master.silta-dashboard.[cluster-domain].
  • SILTA_DASHBOARD_KEY: Required for dashboard rbac creation, can be found in dashboard settings.
  • ${SILTA_CLUSTER_ID}_KUBECTL_CONFIG: Normally does not exist in context, but rather in project's environment variables. Variable is injected by Silta Dashboard.

CircleCI connection proxy (optional)#

Allows connecting to cluster via ssh jumphost. Does not work with all projects (some npm installs fail).

  • TUNNEL_USER_HOST: ssh jumphost user. Example: user@ssh.example.com.
  • TUNNEL_PRIVATE_KEY: Private key of jumphost user, replace newlines with \n.

Deprecation list:#

  • VPC_NATIVE: Adds vpc native (NEG) annotation for GKE clusters (cloud.google.com/neg). This should be set to true in charts by default now since all new clusters are vpc native and all gke clusters we deal with are vpc native.
  • DOCKER_REPO_PROJ: Implement IMAGE_REPO_PROJ, set this as a fallback.
  • SILTA_USE_GCLOUD: Force using gcloud cli for existing image lookups. This can be removed since build images without gcloud are used by default now.

Deprecated (if you see these in your context, You can remove them)#

  • DOCKER_REPO_ORG
  • DOCKER_REPO_URL
  • DOCKER_PASSWORD
  • DOCKER_USER
  • GCLOUD_EMAIL
  • GCLOUD_CLUSTER_NAME
  • SLACK_ACCESS_TOKEN
- + diff --git a/docs/compatibility_matrix/index.html b/docs/compatibility_matrix/index.html index 54145ee..db33af8 100644 --- a/docs/compatibility_matrix/index.html +++ b/docs/compatibility_matrix/index.html @@ -8,7 +8,7 @@ compatibility_matrix | Silta - + @@ -23,7 +23,7 @@

compatibility_matrix

Component \ VendorGKE (Google)AKS (Azure)EKS (Amazon)UKS (UpCloud)microk8s (self-hosted)minikube (local)
Container Image RegistryArtifact RegistryAzure Container RegistryElastic Container RegistryMissing**docker-registry*docker-registry*
Read-write many storageFilestoreAzure Files (azurefile-csi)Amazon S3 File Gateway (untested)***Missing**nfs-server*nfs-server*
Silta-shared storage backend (rwx)Google Cloud StorageBlob StorageAmazon S3Missing**MinIO*MinIO*
Load BalancerGKE IngressStandard Load BalancerELB* & ALBCCMmetallb*metallb*
Static, reserved Ingress IPYesYesUntested***YesYes
Static, reserved Egress IPCloudNAT (private clusters only), silta-proxy*YesYesYesYes
Network PolicyCalicoCalico or Network Policy ManagerHave to install*CiliumHave to install* / Untested***Have to install* / Untested***
Managed DBsCloudSQLAzure Database for MySQLRDS***Managed Databases
K8s versionsMultipleMultipleMultiple1.26MultipleMultiple
Web Application Firewall*Cloud Armor (only for GKE ingress)Application Gateway (only for azure/application-gateway ingress)AWS WAF***

Notes:

  • Load Balancing - all vendors support installing own ingress controller (Ingress-Nginx, Traefik)
  • Web Application Firewall - all vendors support Signal Sciences WAF (in cluster agent)
  • ELB provides client ip via PROXY protocol
  • silta-proxy - requires separate nodepool and taints, does not work with all applications

*Have to install
Missing
*
Untested

- + diff --git a/docs/configuring-cdn/index.html b/docs/configuring-cdn/index.html index 51d721f..a4e3545 100644 --- a/docs/configuring-cdn/index.html +++ b/docs/configuring-cdn/index.html @@ -8,7 +8,7 @@ Configuring CDN | Silta - + @@ -22,7 +22,7 @@

Configuring CDN

CloudFront#

You need to configure your matching CloudFront domain name with exposedDomain directive:

# silta.yml
exposedDomain:
cloudfront:
hostname: www.example.com # matching domain name configured in CloudFront

Origin connection during Lets Encrypt certificate verification process#

Eventually you want your CDN to use Silta origin using https-only origin protocol policy.

However, it is important to understand that you may need to temporarly use http-only during the phase of initial Lets Encrypt certificate verification process. Also, during this phase, you want to disable all https to http redirects from CloudFront Cache behaviors and from silta.yml:

# silta.yml (when using Lets Encrypt)
ingress:
default:
# Allow HTTP connections for CloudFront, when
# Lets Encrypt verifies certs for the first time.
redirect-https: false

Note: If you don't allow http traffic, and your environment is issuing a certificate with Lets Encrypt for the first time, Silta provides temporarly self-signed certificate which will cause CloudFront to not trust the origin and causes 502 Bad Gateway error, thus failing the actual certificate verification process.

Custom certificates#

If you decide to use custom verified certificate, then you may configure everything directly to https-only and skip steps allowing http origin requests temporarly.

Forwarding Host header#

You want Drupal to generate URLs according to the domain and scheme that user is accessing the site.

Without forwarding Host header, Drupal would use its' Silta domain and scheme (for example https://production.my-project.dev.[clusterDomain]) to generate content URL addresses.

To overcome this problem, you must configure CloudFront to forward Host header to origin.

To do this, apply cache policies under "Cache behaviors" tab and either:

Summary#

Summarized in a picture

- + diff --git a/docs/creating-new-project/index.html b/docs/creating-new-project/index.html index c821bf5..c7969a8 100644 --- a/docs/creating-new-project/index.html +++ b/docs/creating-new-project/index.html @@ -8,7 +8,7 @@ Creating a new project | Silta - + @@ -22,7 +22,7 @@

Creating a new project

Drupal project guidelines#

  • Make a copy of Wunder's drupal-project, and push it as a new repository within the wunderio Github organisation.
  • Setup your project:
    • Run your project locally with lando: lando start (follow local environment setup instructions at https://github.com/wunderio/drupal-project#setup)
    • Install composer dependencies with lando composer install and commit composer.lock and generated files in the web folder. If Drupal adds additional database credentials in settings.php, these should not be committed and can be discarded.
    • Install javascript dependencies with npm install and commit the package-lock.json file.
    • Install Drupal with lando drush site-install and export the default configuration with lando drush config-export.
  • Log in to CircleCI with your Github credentials, select "wunderio" and enable your project.
  • Watch your project build, the CircleCI output has a link to your deployed environment.

Frontend project guidelines#

  • Make a copy of Wunder's frontend-project, and push it as a new repository within the wunderio Github organisation.
  • Log in to CircleCI with your Github credentials and enable your project.
  • Watch your project build, the CircleCI output has a link to your deployed environment.
- + diff --git a/docs/deployment-workflow/index.html b/docs/deployment-workflow/index.html index 33ca35d..fe17ee9 100644 --- a/docs/deployment-workflow/index.html +++ b/docs/deployment-workflow/index.html @@ -8,7 +8,7 @@ Deployment workflow | Silta - + @@ -22,7 +22,7 @@ - + diff --git a/docs/docker-images/index.html b/docs/docker-images/index.html index 82754f8..d64864f 100644 --- a/docs/docker-images/index.html +++ b/docs/docker-images/index.html @@ -8,7 +8,7 @@ Docker images | Silta - + @@ -23,7 +23,7 @@

Docker images

Base images#

Base images for silta deployments available at https://hub.docker.com/u/wunderio. Image source available at https://github.com/wunderio/silta-images

Cluster tools#

sshd Gitauth#

https://github.com/wunderio/sshd-gitauth

This image provides an SSH jumphost, a single point to log into the Drupal shell containers.

Silta-Splash#

https://github.com/wunderio/silta-splash

A minimal image with general web assets served by nginx, used to serve simple responses such as default "project not found" page for Silta.

Silta-deployment-remover#

https://github.com/wunderio/silta-deployment-remover

This image provides a web server that can be configured to respond to certain requests from Github webhooks, so that silta environments are deleted automatically when the related branch is removed.

Tools#

Silta CLI#

https://github.com/wunderio/silta-cli

CI/CD deployment command abstraction, utilities and tools for Silta.

- + diff --git a/docs/encrypting-sensitive-configuration/index.html b/docs/encrypting-sensitive-configuration/index.html index 9496e1b..e7f4d3d 100644 --- a/docs/encrypting-sensitive-configuration/index.html +++ b/docs/encrypting-sensitive-configuration/index.html @@ -8,7 +8,7 @@ Encrypting sensitive configuration | Silta - + @@ -31,7 +31,7 @@ Click the gear icon on a build page > Environment variables > Add Variable. Use a name like MYPROJECT_SECRET_KEY and the value of your choice (preferably a strong key).
  • Use the same step as above, but specify the environment variable to be used as the decryption key:
    - silta/decrypt-files:
    files: path/to/file
    secret_key_env: MYPROJECT_SECRET_KEY
  • Decrypting existing secrets file#

    Check the port and IP address by Rerunning the latest workflow in CircleCI: > Rerun job with SSH

    Using the SSH port and IP address securely copy your silta/secrets file to CircleCI

    scp -P 64537 silta/secrets 3.80.240.10:/tmp/encrypted_file

    SSH to CircleCI using the correct port/IP you got from rerunning the job with SSH

    ssh -p 64537 3.80.240.10

    Run following command in CircleCI:

    openssl aes-256-cbc -pbkdf2 -d -in /tmp/encrypted_file -out /tmp/decrypted_file -pass env:SECRET_KEY

    Check /tmp/decrypted_file or scp it back to your local using

    scp -P 64537 3.80.240.10:/tmp/decrypted_file silta/secrets_decrypted
    - + diff --git a/docs/gcp_filestore_migration/index.html b/docs/gcp_filestore_migration/index.html index 2fa15b4..8cb5c0d 100644 --- a/docs/gcp_filestore_migration/index.html +++ b/docs/gcp_filestore_migration/index.html @@ -8,7 +8,7 @@ gcp_filestore_migration | Silta - + @@ -28,7 +28,7 @@
    USER www-data
  • Deploy

  • Check owners of the files directory, it should be www-data

    ls -alh /app/web/sites/default/files

    If some of the files are owned by root - rerun step 5, but for the files path (not files-new)

  • Check that the public files path shows up correctly when running drush status. If it doesn't, make sure that it has not been overridden in settings.php file.

  • Changing storage for a new deployment, project:#

    1. Redefine the default public and private files volumes.
    mounts:
    public-files:
    enabled: true
    storage: 10G
    mountPath: /app/web/sites/default/files
    storageClassName: nfs-shared
    private-files:
    enabled: true
    storage: 1G
    mountPath: /app/private
    storageClassName: nfs-shared
    1. Deploy - this is your first deployment for the project or environment.
    - + diff --git a/docs/go-live-checklist/index.html b/docs/go-live-checklist/index.html index ea36e8a..4108cd5 100644 --- a/docs/go-live-checklist/index.html +++ b/docs/go-live-checklist/index.html @@ -8,7 +8,7 @@ Go-live checklist | Silta - + @@ -28,7 +28,7 @@ for high availability.
  • Do a basic load test to make sure that autoscaling works.
  • Configuration#

    • Sparkpost key is set (if applicable)
    • Backups are enabled
    • Make sure the production static IP is set up if any whitelisting is needed for third-party integrations

    Web access#

    • Recommended: set up a beta.example.com domain that can be used to test the process of configuring DNS.
    • Domain names are set in silta.yml, configured to use SSL with letsencrypt or custom certifcates
    • Some time before switching the DNS, set the TTL of any existing DNS entries to be short, like 1 minute (cached DNS entries can cause a variety of issues, like failing letsencrypt DNS challenges).
    • BasicAuth is disabled
    - + diff --git a/docs/help-with-silta-dev/index.html b/docs/help-with-silta-dev/index.html index 914549d..5f14b81 100644 --- a/docs/help-with-silta-dev/index.html +++ b/docs/help-with-silta-dev/index.html @@ -8,7 +8,7 @@ Helping with Silta development | Silta - + @@ -23,7 +23,7 @@

    Helping with Silta development

    Development workflow#

    Each chart (drupal, frontend, simple) has respective project that uses the chart as subfolder under /charts. So adjustments to chart can be made on each commit. Check .cirlceci/config.yml in Drupal chart to see how it's defined. So you make a PR for a specific chart (either drupal-project-k8s or frontend-project-k8s or simple-project-k8s)

    Testing#

    Before making a pull request you should install the unittest helm plugin:

    helm plugin install https://github.com/quintush/helm-unittest --version 0.2.4

    and run in on your updated chart:

    helm unittest ./charts/drupal --helm3

    To test charts locally You will need related helm repositories to be installed locally (see charts/chartname/Chart.yaml) and subcharts downloaded.

    1. Adding helm repository:
    helm repo add wunderio https://storage.googleapis.com/charts.wdr.io
    1. Download / rebuild the charts/ directory based on the Chart.lock file
    helm dependency build charts/drupal
    1. Dry-run chart and check kubernetes resource definitions for expected output
    helm upgrade --install test charts/drupal --dry-run --debug --values silta/silta.yml

    Contribution#

    1. Someone from silta dev team will review changes and review the PR. Once accepted by one of them, it can be merged to master.
    2. Once changes are merged to project there are 2 options:
      1. Silta developers diff wunderio/charts/drupal to wunderio/drupal-project-k8s/charts/drupal before next release by copying over multiple changes in bulk and increment chart version in both repos, making them in sync again.
      2. You can make a copy of that accepted PR to wunderio/charts repo where it will be accepted again.

    If you want to test a feature PR:

    1. Create a new branch from feature/myAwesomeThing -> feature/myAwesomeThing-test.
    2. Enable the myAwesomeThing related functionality or apply new configuration related to the feature.
    3. Commit the changes to the test branch and push to origin.
    4. Check that functionality works as it should.
    5. Write tests when possible and push them to the original feature branch or request the original author to add them.
    6. Delete the test branch if everything works.

    Some tips and external documentation when working with HELM charts#

    Helm template guide - control structures
    Goland Sprig functions

    - + diff --git a/docs/index.html b/docs/index.html index d7d37ce..f9909f5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,7 +8,7 @@ Style Guide | Silta - + @@ -22,7 +22,7 @@

    Style Guide

    You can write content using GitHub-flavored Markdown syntax.

    Markdown Syntax#

    To serve as an example page when styling markdown based Docusaurus sites.

    Headers#

    H1 - Create the best documentation#

    H2 - Create the best documentation#

    H3 - Create the best documentation#

    H4 - Create the best documentation#

    H5 - Create the best documentation#
    H6 - Create the best documentation#

    Emphasis#

    Emphasis, aka italics, with asterisks or underscores.

    Strong emphasis, aka bold, with asterisks or underscores.

    Combined emphasis with asterisks and underscores.

    Strikethrough uses two tildes. Scratch this.


    Lists#

    1. First ordered list item
    2. Another item
      • Unordered sub-list.
    3. Actual numbers don't matter, just that it's a number
      1. Ordered sub-list
    4. And another item.
    • Unordered list can use asterisks
    • Or minuses
    • Or pluses

    Links#

    I'm an inline-style link

    I'm an inline-style link with title

    I'm a reference-style link

    You can use numbers for reference-style link definitions

    Or leave it empty and use the link text itself.

    URLs and URLs in angle brackets will automatically get turned into links. http://www.example.com/ or http://www.example.com/ and sometimes example.com (but not on GitHub, for example).

    Some text to show that the reference links can follow later.


    Images#

    Here's our logo (hover to see the title text):

    Inline-style: alt text

    Reference-style: alt text

    Images from any folder can be used by providing path to file. Path should be relative to markdown file.

    img


    Code#

    var s = 'JavaScript syntax highlighting';
    alert(s);
    s = "Python syntax highlighting"
    print(s)
    No language indicated, so no syntax highlighting.
    But let's throw in a <b>tag</b>.
    function highlightMe() {
    console.log('This line can be highlighted!');
    }

    Tables#

    Colons can be used to align columns.

    TablesAreCool
    col 3 isright-aligned\$1600
    col 2 iscentered\$12
    zebra stripesare neat\$1

    There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown.

    MarkdownLessPretty
    Stillrendersnicely
    123

    Blockquotes#

    Blockquotes are very handy in email to emulate reply text. This line is part of the same quote.

    Quote break.

    This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can put Markdown into a blockquote.


    Inline HTML#

    Definition list
    Is something people use sometimes.
    Markdown in HTML
    Does *not* work **very** well. Use HTML tags.

    Line Breaks#

    Here's a line for us to start with.

    This line is separated from the one above by two newlines, so it will be a separate paragraph.

    This line is also a separate paragraph, but... This line is only separated by a single newline, so it's a separate line in the same paragraph.


    Admonitions#

    note

    This is a note

    tip

    This is a tip

    important

    This is important

    caution

    This is a caution

    warning

    This is a warning

    - + diff --git a/docs/key-components/index.html b/docs/key-components/index.html index 3349e8e..999311e 100644 --- a/docs/key-components/index.html +++ b/docs/key-components/index.html @@ -8,7 +8,7 @@ Key components | Silta - + @@ -32,7 +32,7 @@ CircleCI Contexts and are available to any repository in our Github organisation.

    See CircleCI context variable requirements for Silta deployments in docs: Silta CircleCI Context.

    Kubernetes#

    Kubernetes is an open source container orchestration platform supported by all major cloud hosting providers.

    Helm#

    Helm is a package manager for Kubernetes. We published our own chart repository: https://github.com/wunderio/charts. The chart is referenced from the CircleCI configuration, and each repository can also override the default values to adapt the configuration.

    - + diff --git a/docs/mdx/index.html b/docs/mdx/index.html index 60daac4..7661c25 100644 --- a/docs/mdx/index.html +++ b/docs/mdx/index.html @@ -8,7 +8,7 @@ Powered by MDX | Silta - + @@ -22,7 +22,7 @@

    Powered by MDX

    You can write JSX and use React components within your Markdown thanks to MDX.

    Docusaurus green and Facebook blue are my favorite colors.

    I can write Markdown alongside my JSX!

    - + diff --git a/docs/migrating-an-existing-drupal-project/index.html b/docs/migrating-an-existing-drupal-project/index.html index 0a236cc..3888715 100644 --- a/docs/migrating-an-existing-drupal-project/index.html +++ b/docs/migrating-an-existing-drupal-project/index.html @@ -8,7 +8,7 @@ Migrating an existing Drupal project | Silta - + @@ -29,7 +29,7 @@ This is the reference environment by default, meaning that new environments will be created with a copy of this content.

  • Congratulations, your project is now up and running! Please share any issues you had or ideas for improvements.

  • Drupal 7 migration tips#

    Project uses make file for builds#

    Have something like this in .circleci/config.yml

    codebase-build:
    - run:
    name: Build from makefile
    command: |
    composer install
    vendor/drush/drush/drush make ~/project/drupal/conf/site.make ~/project/drupal/web/
    mkdir -p web/sites/all/modules
    cp -r code/modules/custom web/sites/all/modules/

    Missing drush#

    Add composer.json in Drupal folder

    {
    "require": {
    "drush/drush": "8.*"
    },
    "extra": {
    "installer-paths": {
    "web/": ["type:drupal-core"]
    }
    }
    }

    And then in .circleci/config.yml add

    command: |
    composer install
    - + diff --git a/docs/request-workflow/index.html b/docs/request-workflow/index.html index 30518d8..a3ae76c 100644 --- a/docs/request-workflow/index.html +++ b/docs/request-workflow/index.html @@ -8,7 +8,7 @@ Request workflow | Silta - + @@ -22,7 +22,7 @@ - + diff --git a/docs/silta-examples/index.html b/docs/silta-examples/index.html index a2d5a3d..373fdab 100644 --- a/docs/silta-examples/index.html +++ b/docs/silta-examples/index.html @@ -8,7 +8,7 @@ Silta examples | Silta - + @@ -45,7 +45,7 @@ separate deployment can be easily done even using different chart. See https://wunderio.github.io/silta/docs/circleci-conf-examples for the deployment setup part.

    When using different charts (e.g. drupal and simple) you need to separate chart specific configurations to their own silta-*.yml files if you want to share any configs between the application deployments (for example basic auth credentials). Best way to do it is to put only the shared configurations to the silta.yml file and have e.g. silta-cms.yml and silta-storybook.yml for application specific configurations.

    Add custom subcharts to deployment#

    1. In silta folder, create extra_charts.yml which contains list of subcharts to add.

    Following examples add a redis subchart to drupal chart deployment.

    charts:
    - name: redis
    version: 16.8.x
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled

    To use a local subchart, replace repository link with file://<path>/<to>/<subchart>

    1. Add these 2 parameters to drupal-build-deploy CircleCI job:
    - silta/drupal-build-deploy:
    source_chart: wunderio/drupal
    extension_file: silta/extra_charts.yml
    1. If desired, modify variables for the subchart in silta.yml under the key of subcharts' name. For example above, it's redis.
    [..]
    redis:
    enabled: true
    auth:
    password: test

    Sets redis password to test

    Notice the condition key in extra_charts.yml for the redis subchart. It makes it possible to deploy this subchart conditionally, when redis: enabled is passed in silta.yml.

    Delete the condition: redis.enabled line if you want this subchart installed in all your future deployments, regardless of settings in silta.yml.

    - + diff --git a/docs/ssl_certificates/index.html b/docs/ssl_certificates/index.html index ef06671..a301cce 100644 --- a/docs/ssl_certificates/index.html +++ b/docs/ssl_certificates/index.html @@ -8,7 +8,7 @@ ssl_certificates | Silta - + @@ -38,7 +38,7 @@ -----BEGIN PRIVATE KEY-----
    openssl will take care of correct decoding. List of all supported formats.

    - + diff --git a/docs/troubleshooting/index.html b/docs/troubleshooting/index.html index 6b96ec8..e4294d9 100644 --- a/docs/troubleshooting/index.html +++ b/docs/troubleshooting/index.html @@ -8,7 +8,7 @@ Troubleshooting and FAQ | Silta - + @@ -39,7 +39,7 @@
    RUN apk add wget
    • The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.

    See Dockerfile refrence for more instructions: https://docs.docker.com/engine/reference/builder/

    Q: How to test docker images?#

    If You want to test docker images locally, You'd need to install docker or other runtime that allows running docker images. This tutorial won't list instructions for that and will assume You can run docker command (it also needs to be at least version 20.10 to be able to run alpine 3.14+ images. Related document).

    Running a docker image:

    docker run -it --entrypoint sh wunderio/silta-php-shell:php7.4-v1

    This will download shell image and run a shell inside it. Typing exit will quit and stop the container.

    This also allows running other images like nginx:

    # running official nginx image from https://hub.docker.com/_/nginx
    docker run -p 8080:80 nginx

    This way You can also run silta images, as long as You have access to image repository. See "How to run silta image locally" for instructions.

    If You want to test your customized dockerfile, You need to build the image and run it

    # Build image and tag it with `shell_test_build` tag
    docker build -t shell_test_build -f silta/shell.Dockerfile .
    # Run tagged image and and exec into it with `sh` shell
    docker run -it --entrypoint sh shell_test_build
    # Remove test image
    docker image rm shell_test_build

    More about running docker images via docker cli at "Docker Command-line reference"

    Q: How to run Silta images locally?#

    TLDR: You can run those images locally, but there are missing resources (storage mounts, environment variables, secrets) that are only available in the cluster. You can still run containers and debug node applications if You have to.

    If You want to run some silta image locally for debugging or other purpose, follow these steps:

    1. Make sure You have access to kubernetes cluster.

    2. Get the docker image URL for the container You are need to run using kubectl:

      $ kubectl get deployments -o wide -n drupal-project-k8s
      NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
      master-drupal 1/1 1 1 448d php,nginx eu.gcr.io/[gcp-project]/drupal-project-k8s-php:v5-76e9f99eb3c4293fa14184b546bc1af980ea3760,eu.gcr.io/[gcp-project]/drupal-project-k8s-nginx:v5-bef5cba1137eaaa73a986bad07221bbab3ae5ca2 app=drupal,deployment=drupal,release=master
      master-shell 1/1 1 1 448d shell eu.gcr.io/[gcp-project]/drupal-project-k8s-shell:v6-3879d81221f34e79ff8674efca539c8d7410dd0a app=drupal,release=master,service=shell
      • drupal-project-k8s is kubernetes namespace, in Silta it's also a project name.
      • master-drupal is drupal pod of master branch deployment
      • master-drupal pod contains two containers, nginx and drupal. These containers are using two images (see "IMAGES" column). See Google Kubernetes Engine Pod documentation if you need to grasp the "Pod" concept. Pod resource is not GKE exclusive, this documentation applies to all kubernetes clusters.
      • master-shell is a shell pod for master branch deployment.
    3. Make sure You have image pull access. Try pulling it:

      docker pull eu.gcr.io/[gcp-project]/drupal-project-k8s-shell:v6-3879d81221f34e79ff8674efca539c8d7410dd0a
    4. Run Silta shell image:

      docker run -it --entrypoint sh eu.gcr.io/[gcp-project]/drupal-project-k8s-shell:v6-3879d81221f34e79ff8674efca539c8d7410dd0a
      • You can't run nginx image properly in local environment because silta mounts resources (storage, secrets, environment variables) that are only available in the cluster
      • There will be some resources (mounts) missing in shell container (i.e. no content in sites/default/files) and some environment variables missing.

    Q: CloudFront responses with 502 Bad Gateway#

    It may be because of CDN using https origin request and Silta is not providing a valid certificate request.

    You must verify that given domain has a verified certificate and is mapped correctly in the certificate under SubjectName and/or CommonName.

    Assuming your:

    • exposedDomain index domain name is cloudfront
    • namepsace: my-project
    • branch is develop

    ...you may inspect your certificate with following command:

    kubectl get develop-tls-cloudfront -n my-project -o json | jq -r '.data["tls.crt"]' | base64 -d | openssl x509 -text

    In certificate details, confirm that www.example.com domain matches your CDN domain:

    Subject: CN = www.example.com

    Otherwise you might need to delete TLS secret and restart the verification process.

    Please read more about configuring CDN

    Q: Drupal is generating wrong URLs with CDN#

    You may not be properly forwarding your Host header to the origin requests.

    Drupal will pickup the scheme and hostname properly from request headers. If these are not properly forwarded, Drupal wont be able to initialize those and generate URLs properly.

    Please read more about configuring CDN

    - + diff --git a/docs/vendor-aks/index.html b/docs/vendor-aks/index.html index f4b7850..4672b28 100644 --- a/docs/vendor-aks/index.html +++ b/docs/vendor-aks/index.html @@ -8,7 +8,7 @@ vendor-aks | Silta - + @@ -25,7 +25,7 @@
    1. Replacing default ingress class with Application Gateway. This will require additional DNS entry changes.
    exposeDomains:
    example:
    hostname: example.com
    ingress:
    default:
    type: azure/application-gateway

    Note: You can define custom annotations for ingress using ingress.[ingressname].extraAnnotations.

    - + diff --git a/docs/vendor-eks/index.html b/docs/vendor-eks/index.html index 59a73d0..c371755 100644 --- a/docs/vendor-eks/index.html +++ b/docs/vendor-eks/index.html @@ -8,7 +8,7 @@ vendor-eks | Silta - + @@ -22,7 +22,7 @@

    vendor-eks

    Amazon Web Services compatibility#

    Silta is mostly AWS compatible, there are some requirements for environments deployed to EKS cluster.

    Cluster requirements#

    • Ingress-nginx as the Ingress choice
    • Amazon VPC CNI plugin for NetworkPolicy
    • Amazon EBS CSI Driver plugin for default storage class (gp2)

    Preparation steps#

    On new, empty cluster, before installing silta-cluster chart:

    1. Install Amazon VPC CNI plugin (plugins are located in EKS -> cluster > Add-ons tab)
    2. Install Amazon EBC CSI Driver plugin
    3. Create and attach IAM role to worker nodes with these permissions:
      • AmazonEC2ContainerRegistryFullAccess
      • AmazonEC2FullAccess
      • AmazonEKSWorkerNodePolicy
      • AmazonElasticFileSystemFullAccess
      • AmazonS3FullAccess

    Silta-cluster chart requirements#

    Enabling proxy protocol over ingress-nginx, for passing client IP to pods:

    ingress-nginx:
    controller:
    config:
    use-proxy-protocol: true
    service:
    annotations:
    "service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*"

    SSH uses NLB as ingress point. Apply these annotations:

    gitAuth:
    enabled: true
    scope: 'https://github.com/wunderio'
    annotations:
    "service.beta.kubernetes.io/aws-load-balancer-backend-protocol": "tcp"
    "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "60"
    # "service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled": "true"
    "service.beta.kubernetes.io/aws-load-balancer-type": "nlb"
    # the length of the list must be equal to the number of subnets
    "service.beta.kubernetes.io/aws-load-balancer-eip-allocations": "<elastic IP id>"
    "service.beta.kubernetes.io/aws-load-balancer-subnets": "<subnet name here"
    "service.beta.kubernetes.io/aws-load-balancer-nlb-target-type": "instance"
    "service.beta.kubernetes.io/aws-load-balancer-ip-address-type": "ipv4"
    "service.beta.kubernetes.io/aws-load-balancer-target-group-attributes": "stickiness.enabled=true,stickiness.type=source_ip,preserve_client_ip.enabled=true"

    For NLB, it is required to have 1 Elastic IP per subnet (defined by Availability Zones)

    EIP Allocation ID is in Network & Security -> Elastic IPs

    Subnet names are in VPC Dashboard -> Virtual Private Cloud -> Subnets

    There are few more requirements listed on silta-cluster chart page, those are common for all silta-cluster installations

    Missing functionality#

    • NLB for HTTP/HTTPS ingress

    Deployment specifics#

    There is no extra configuration required for basic deployments. The only change would be cluster.type but it's normally overridden in CI pipeline.

    Drupal, frontend and simple charts:

    cluster:
    type: aws
    - + diff --git a/docs/vendor-gcs/index.html b/docs/vendor-gcs/index.html index 5edb663..683350c 100644 --- a/docs/vendor-gcs/index.html +++ b/docs/vendor-gcs/index.html @@ -8,7 +8,7 @@ vendor-gcs | Silta - + @@ -16,20 +16,20 @@ - +

    vendor-gcs

    Google Cloud compatibility#

    Silta is fully GKE compatible since it's primarily used on it.

    Cluster requirements#

    Requirements are listed on silta-cluster chart page, those are common for all silta-cluster installations.

    Deployment specifics#

    There is no extra configuration required for basic deployments. The only change would be cluster.type but it's normally overridden in CI pipeline.

    Drupal, frontend and simple charts:

    cluster:
    type: gke

    Google Cloud features#

    VPC native cluster#

    GKE clusters are VPC native the default now, but for compatibility reasons silta deployments are set to route-based mode by default now. This is normally overridden in CI, according to cluster.

    cluster:
    type: gke
    vpcNative: true

    GKE Ingress for HTTP(S) Load Balancing#

    Projects can define exposeDomain hosts and use GKE Ingress Class

    exposeDomains:
    example-gce-ingress:
    hostname: example.com
    # see ingress.gce definition. This can also be a custom ingress too.
    ingress: gce
    ingress:
    gce:
    # Request a global static ip from cluster administrator first
    staticIpAddressName: custom-ip-name
    nginx:
    # Reverse proxy IP's to trust with contents of X-Forwarded-For header
    realipfrom:
    # Load Balancer IP (static ip you were given)
    gce-lb-ip: 1.2.3.4/32

    Cloud Armor#

    Cloud Armor can only be used with GKE Ingress. Once enabled, You can define security policy (Cloud Armor policy) for Your service's backendConfig.

    Silta uses "silta-ingress" security policy name by default, it can be adjusted.

    backendConfig:
    securityPolicy:
    name: "silta-ingress"

    Filestore#

    Filestore - add an alternate storageclass with a shared Filestore volume.
    Public and private files can be stored on Google Filestore via NFS mount, providing higher i/o access than default storage. This option is useful for projects with lots of files served.
    -Have an exported share named /main_share.

    Example configuration for new deployments.

    mounts:
    public-files:
    enabled: true
    storage: 1G
    mountPath: /app/web/sites/default/files
    storageClassName: nfs-shared
    private-files:
    enabled: true
    storage: 1G
    mountPath: /app/private
    storageClassName: nfs-shared

    Full example on using the provisioned storageclass in new and existing projects here

    ingress-nginx load balancer on GKE private cluster#

    When using GKE private cluster, ingress-nginx requires an additional firewall rule that allows control plane connection to nodes on port 8443. +Have an exported share named /main_share.

    Example configuration for new deployments.

    mounts:
    public-files:
    enabled: true
    storage: 1G
    mountPath: /app/web/sites/default/files
    storageClassName: nfs-shared
    private-files:
    enabled: true
    storage: 1G
    mountPath: /app/private
    storageClassName: nfs-shared

    Add USER directive to silta/php.Dockerfile right after the COPY line so files are created with correct permissions and can be modified via shell (i.e. drush cr).

    USER www-data

    Dockerfile example of a project

    FROM wunderio/silta-php-fpm:8.2-fpm-v1
    COPY --chown=www-data:www-data . /app
    USER www-data

    Full example on using the provisioned storageclass in new and existing projects here

    ingress-nginx load balancer on GKE private cluster#

    When using GKE private cluster, ingress-nginx requires an additional firewall rule that allows control plane connection to nodes on port 8443. Example and solution is borrowed from https://github.com/kubernetes/ingress-nginx/issues/5401

    # Control pane range (normally 172.16.0.0/28)
    # gcloud container clusters describe [CLUSTER_NAME] --region europe-north1 --format json | jq -r '.privateClusterConfig.masterIpv4CidrBlock'
    CONTROL_PLANE_RANGE=172.16.0.0/28
    # Get cluster tag
    NETWORK_TAGS=$(gcloud compute instances describe \
    $(kubectl get nodes -o jsonpath='{.items[0].metadata.name}') \
    --format="value(tags.items[0])")
    # Print firewall rule command
    echo gcloud compute firewall-rules create silta-nginx-lb-ingress \
    --action ALLOW \
    --direction INGRESS \
    --source-ranges ${CONTROL_PLANE_RANGE} \
    --rules tcp:8443 \
    --target-tags ${NETWORK_TAGS}

    Review and execute command printed above.

    - + @@ -37,6 +37,6 @@ - + \ No newline at end of file diff --git a/docs/vendor-uks/index.html b/docs/vendor-uks/index.html index 3804e4a..e021f53 100644 --- a/docs/vendor-uks/index.html +++ b/docs/vendor-uks/index.html @@ -8,7 +8,7 @@ vendor-uks | Silta - + @@ -22,7 +22,7 @@

    vendor-uks

    Upcloud compatibility#

    Silta is mostly Upcloud compatible, there are some requirements for environments deployed to UKS cluster.

    Cluster requirements#

    • Load balancers are configured using json in annotations, see https://github.com/UpCloudLtd/uks-instructions/blob/main/ccm/README.md#customising-load-balancer-configuration

      • By default, they are in HTTP mode, which needs to be changed to TCP
      • Example configuration for ingress-nginx:
        ingress-nginx:
        controller:
        admissionWebhooks:
        enabled: true
        autoscaling:
        enabled: false
        config:
        use-forwarded-headers: "true"
        compute-full-forwarded-for: "true"
        use-proxy-protocol: "true"
        real-ip-header: "proxy_protocol"
        service:
        type: LoadBalancer
        annotations:
        service.beta.kubernetes.io/upcloud-load-balancer-config: |
        {
        "name": "silta-ingress-1",
        "plan": "production-small",
        "frontends": [
        {
        "name": "https",
        "mode": "tcp",
        "port": 443
        },
        {
        "name": "http",
        "mode": "tcp",
        "port": 80
        }
        ],
        "backends": [
        {
        "name": "https",
        "properties": { "outbound_proxy_protocol": "v1"}
        },
        {
        "name": "http",
        "properties": { "outbound_proxy_protocol": "v1"}
        }
        ]
        }
        • To enable whitelist for VPN, SSH service has to annotated with:
        gitAuth:
        annotations:
        service.beta.kubernetes.io/upcloud-load-balancer-config: |
        {
        "name": "silta-ssh-1",
        "plan": "development",
        "frontends": [
        {
        "name": "ssh",
        "mode": "tcp",
        "port": 22,
        "rules": [
        {
        "name": "allow-vpn",
        "priority": 100,
        "matchers": [
        {
        "type": "src_ip",
        "inverse": true,
        "match_src_ip": {
        "value": "<VPN_IP_HERE>"
        }
        }
        ],
        "actions": [
        {
        "type": "tcp_reject",
        "action_tcp_reject": {}
        }
        ]
        }
        ]
        }
        ]
        }
    • Creating an object storage and configuring rclone is quite well explained at https://upcloud.com/resources/tutorials/migrate-object-storage-rclone

      • Example configuration:
        rclone:
        params:
        remote: s3
        remotePath: silta-shared
        s3-access-key-id: <ACCESS_KEY>
        s3-acl: private
        s3-endpoint: xyz.fi-hel2.upcloudobjects.com
        s3-provider: Other
        s3-region: fi-hel2
        s3-secret-access-key: <SECRET_KEY>
    • If using managed database, create a new database user and set authentication method to mysql_native_password

    • Smallest size for UKS storage volumes is 1Gi - set this for mariadb, elasticsearch pods

    There are few more requirements listed on silta-cluster chart page, those are common for all silta-cluster installations

    Missing functionality#

    • Managed Docker image registry
    • Managed NFS storage

    Deployment specifics#

    There is no extra configuration required for basic deployments. The only change would be cluster.type but it's normally overridden in CI pipeline.

    - + diff --git a/index.html b/index.html index 7237ab0..7e74894 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ Hello from Silta | Silta - + @@ -18,7 +18,7 @@

    Your Docusaurus site did not load properly.

    A very common reason is a wrong site baseUrl configuration.

    Current configured baseUrl = /silta/

    We suggest trying baseUrl =

    Silta

    Silta is a combination of open source tools and cloud services to provide a simple but flexible, self-service infrastructure for development teams, as well as a stable production hosting.

    What does Silta mean?

    What does Silta mean?

    It means "bridge" in Finnish.

    Can I use Silta outside of Wunder?

    Can I use Silta outside of Wunder?

    Yes, our code is open. However, we haven't put special attention to this use case at this point.

    Does Silta support multisite?

    Does Silta support multisite?

    This might be technically possible, but multisite setups provide little benefits in a container-based environment. Instead, it is recommended to trigger the deployment of multiple sites into dedicated environments from the same repository.

    - + diff --git a/runtime~main.5c899479.js b/runtime~main.2649cf66.js similarity index 71% rename from runtime~main.5c899479.js rename to runtime~main.2649cf66.js index 1eb5cbd..6bbfa76 100644 --- a/runtime~main.5c899479.js +++ b/runtime~main.2649cf66.js @@ -1 +1 @@ -!function(e){function r(r){for(var n,o,f=r[0],d=r[1],u=r[2],b=0,l=[];b Search the documentation | Silta - + @@ -18,7 +18,7 @@

    Search the documentation

    - +