<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>aht on</title><link>https://stackgres.io/blog/planet/aht/</link><description>Recent content in aht on</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 12 Feb 2024 14:00:00 +0100</lastBuildDate><atom:link href="https://stackgres.io/blog/planet/aht/index.xml" rel="self" type="application/rss+xml"/><item><title>How to Run Metis on Top Of StackGres</title><link>https://stackgres.io/blog/how-to-run-metis-on-top-of-stackgres/</link><pubDate>Mon, 12 Feb 2024 14:00:00 +0100</pubDate><guid>https://stackgres.io/blog/how-to-run-metis-on-top-of-stackgres/</guid><description>&lt;h1 id="how-to-run-metis-on-top-of-stackgres">How To Run Metis On Top Of StackGres&lt;/h1>
&lt;p>In this how-to guide, we&amp;rsquo;ll walk you through the whole process of setting up &lt;a href="https://www.metisdata.io/">Metis&lt;/a> on a Kubernetes cluster using &lt;a href="https://stackgres.io/">StackGres&lt;/a>.&lt;/p>
&lt;p>Metis is a comprehensive database observability tool. It can track your live database activity, suggest improvements for schema, indexes, queries, configuration, and more. By onboarding your PostgreSQL server with Metis, you get access to live infrastructural metrics (CPU, memory usage) and database metrics (transactions, buffers, caches). Metis can look for anomalies in performance, index usage, or data distribution. See &lt;a href="https://docs.metisdata.io/Monitor%20and%20troubleshoot%20databases">the documentation on how to monitor &amp;amp; troubleshoot your databases&lt;/a>.&lt;/p>
&lt;p>This guide is also available as a &lt;a href="https://www.youtube.com/watch?v=neB0JH7hfjE">video&lt;/a>&lt;/p>
&lt;br/>
&lt;hr/>
&lt;br/>
&lt;div class="box smPad relative">
&lt;div class="whiteGradient border">&lt;/div>
This post has been published with explicit permission from Metis. It's a copy of an article originally published on Metis website &lt;a href="https://www.metisdata.io/blog/how-to-run-metis-on-top-of-stackgres" target="_blank">on February 12, 2024&lt;/a>.
&lt;/div>
&lt;br/>
&lt;hr/>
&lt;br/>
&lt;h2 id="ongres-stackgres">OnGres (StackGres)&lt;/h2>
&lt;p>&lt;a href="https://stackgres.io/">StackGres&lt;/a> is the full-stack Postgres Platform. Fully open-source software to run your own Postgres-as-a-Service on any cloud or on-prem. StackGres is a project from &lt;a href="https://ongres.com/">OnGres&lt;/a>, the Postgres laser-focused startup (&amp;ldquo;OnGres&amp;rdquo; means &amp;ldquo;ON postGRES&amp;rdquo;).&lt;/p>
&lt;p>StackGres is a Kubernetes Operator for Postgres. It allows you to create production-ready Postgres clusters in seconds. No advanced Postgres expertise is required. You can use the built-in Web Console or the high-level Kubernetes CRDs for CLI and GitOps.&lt;/p>
&lt;p>With StackGres, writing a simple YAML manifest (or point-and-click on the Web Console) is all that is needed to create production-ready Postgres clusters including high availability with Patroni, replication, connection pooling, automated backups, monitoring, and centralized logs.&lt;/p>
&lt;p>With support for &lt;a href="https://stackgres.io/extensions">more than 150 Postgres extensions&lt;/a>, StackGres is the most extensible Postgres platform available. It also provides support for &lt;a href="https://babelfishpg.org/">Babelfish for Postgres&lt;/a> (which brings SQL Server compatibility, at the wire protocol level, SQL and T-SQL) and integrations with Citus for sharding Postgres, Timescale for time-series, Supabase and now, FerretDB.&lt;/p>
&lt;h2 id="metis">Metis&lt;/h2>
&lt;p>Metis is a powerful observability tool that can track all the aspects of your databases and database servers. It integrates with your database server with the help of an agent that you need to deploy in your cluster so it can monitor the ongoing activity.&lt;/p>
&lt;p>Metis is distributed as a Docker container. You can install it in any environment supporting OCI containers, including AWS ECS, Kubernetes, AKS, or GKE. This makes using Metis straightforward and lets you configure everything in seconds.&lt;/p>
&lt;p>Metis connects to your database and extracts details of the database activity. This includes metrics around infrastructure (CPU, memory usage, files opened), databases (transactions, caches, temporary files), live queries (and their execution plans), configuration, schema details, index usage, and much more. Metis explains what is happening in your databases. Metis can look for anomalies and detect drifts between environments. Metis can suggest &lt;a href="https://www.metisdata.io/blog/8-proven-strategies-to-improve-database-performance">actionable performance improvements&lt;/a> and notify you when things degrade.&lt;/p>
&lt;h2 id="setting-up-metis-on-top-of-stackgres">Setting Up Metis On Top Of StackGres&lt;/h2>
&lt;p>We’ll need to install the Kubernetes cluster, then install StackGres, then configure the StackGres cluster, and then configure Metis. Instructions below are for Amazon Linux 2 x86_64 but will work the same way on other operating systems like Mac OS and Windows (with slight syntax changes for PowerShell or other shells), and on ARM64 architecture.&lt;/p>
&lt;h3 id="installing-kubernetes-with-minikube">Installing Kubernetes With Minikube&lt;/h3>
&lt;p>Before installing StackGres, you will need a running Kubernetes cluster and the usual command line tools &lt;a href="https://kubernetes.io/docs/tasks/tools/">kubectl&lt;/a> and &lt;a href="https://helm.sh/docs/intro/install/">Helm&lt;/a>. Please refer to the respective installation pages if you don&amp;rsquo;t have these tools. As for Kubernetes, if you don&amp;rsquo;t have one you can try easily with &lt;a href="https://minikube.sigs.k8s.io/docs/start/">minikube&lt;/a>. It can be installed like this:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">sudo install minikube-linux-amd64 /usr/local/bin/minikube
&lt;/code>&lt;/pre>&lt;/div>&lt;p>This should give you a running single-node cluster in seconds (depending on your Internet connection speed). You can install it in other operating systems the way it’s described &lt;a href="https://minikube.sigs.k8s.io/docs/start/">in the docs&lt;/a>.&lt;/p>
&lt;p>Keep in mind that minikube uses Docker behind the scenes. It works natively in Linux, and with a virtual machine in MacOS and Windows. Refer to installation instructions for &lt;a href="https://www.docker.com/products/docker-desktop/">Docker Desktop&lt;/a> to learn how to install it on your machine.&lt;/p>
&lt;p>You can now create the minikube cluster with:&lt;/p>
&lt;p>This should give you the output similar to this:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">* minikube v1.32.0 on Amazon &lt;span style="color:#ae81ff">2&lt;/span>
* Automatically selected the docker driver. Other choices: none, ssh
* Using Docker driver with root privileges
* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Creating docker container &lt;span style="color:#f92672">(&lt;/span>CPUs&lt;span style="color:#f92672">=&lt;/span>2, Memory&lt;span style="color:#f92672">=&lt;/span>3900MB&lt;span style="color:#f92672">)&lt;/span> ...
* Preparing Kubernetes v1.28.3 on Docker 24.0.7 ...
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Configuring bridge CNI &lt;span style="color:#f92672">(&lt;/span>Container Networking Interface&lt;span style="color:#f92672">)&lt;/span> ...
* Verifying Kubernetes components...
- Using image gcr.io/k8s-minikube/storage-provisioner:v5
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use &lt;span style="color:#e6db74">&amp;#34;minikube&amp;#34;&lt;/span> cluster and &lt;span style="color:#e6db74">&amp;#34;default&amp;#34;&lt;/span> namespace by default
&lt;/code>&lt;/pre>&lt;/div>&lt;p>When you’re done with the examples, you can easily delete the cluster with:&lt;/p>
&lt;p>Let’s now install StackGres.&lt;/p>
&lt;h3 id="installing-stackgres">Installing StackGres&lt;/h3>
&lt;p>The best way to install StackGres is through the official Helm chart. You can install it in this way:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">curl -LO https://get.helm.sh/helm-v3.14.0-linux-amd64.tar.gz
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">tar -zxvf helm-v3.14.0-linux-amd64.tar.gz
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">sudo mv linux-amd64/helm /usr/local/bin/helm
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Follow &lt;a href="https://helm.sh/docs/intro/install/">this page&lt;/a> to install Helm on your machine.&lt;/p>
&lt;p>For our particular setup, we use the following Helm commands:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">helm repo add stackgres-charts https://stackgres.io/downloads/stackgres-k8s/stackgres/helm/
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">helm install --create-namespace --namespace stackgres stackgres-operator stackgres-charts/stackgres-operator
&lt;/code>&lt;/pre>&lt;/div>&lt;p>To confirm that the operator is running while also waiting for setup to complete, run the following commands:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl wait -n stackgres deployment -l group&lt;span style="color:#f92672">=&lt;/span>stackgres.io --for&lt;span style="color:#f92672">=&lt;/span>condition&lt;span style="color:#f92672">=&lt;/span>Available
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl get pods -n stackgres -l group&lt;span style="color:#f92672">=&lt;/span>stackgres.io
&lt;/code>&lt;/pre>&lt;/div>&lt;p>As you run the first &lt;strong>&lt;em>kubectl&lt;/em>&lt;/strong> command, it should wait for the successful deployment, and the second command will list the pods running in the &lt;strong>&lt;em>stackgres&lt;/em>&lt;/strong> namespace.&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">NAME READY STATUS RESTARTS AGE
stackgres-operator-57bff75d-xlnfp 1/1 Running &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#f92672">(&lt;/span>2m36s ago&lt;span style="color:#f92672">)&lt;/span> 2m58s
&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="creating-a-stackgres-cluster">Creating a StackGres Cluster&lt;/h3>
&lt;p>Here, we&amp;rsquo;ll create an SGCluster configured to fit Metis requirements. We’re going to use some resources created inline. Metis requires the &lt;a href="https://www.postgresql.org/docs/current/pgstatstatements.html">pg_stat_statements&lt;/a> extension, a separate user, and permissions to monitor databases.&lt;/p>
&lt;p>Let’s create a password for the user that will get initialized based on the SQL command:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl -n stackgres create secret generic metis-user-password-secret --from-literal&lt;span style="color:#f92672">=&lt;/span>metis-create-user-sql&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;create user metis password &amp;#39;admin123&amp;#39;&amp;#34;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let’s now create a script that will create a database named &lt;strong>&lt;em>metis&lt;/em>&lt;/strong> and a user &lt;strong>&lt;em>metis&lt;/em>&lt;/strong>:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">cat &lt;span style="color:#e6db74">&amp;lt;&amp;lt; EOF | kubectl apply -f -
&lt;/span>&lt;span style="color:#e6db74">apiVersion: stackgres.io/v1
&lt;/span>&lt;span style="color:#e6db74">kind: SGScript
&lt;/span>&lt;span style="color:#e6db74">metadata:
&lt;/span>&lt;span style="color:#e6db74"> namespace: stackgres
&lt;/span>&lt;span style="color:#e6db74"> name: cluster-scripts
&lt;/span>&lt;span style="color:#e6db74">spec:
&lt;/span>&lt;span style="color:#e6db74"> scripts:
&lt;/span>&lt;span style="color:#e6db74"> - name: create-metis-user
&lt;/span>&lt;span style="color:#e6db74"> scriptFrom:
&lt;/span>&lt;span style="color:#e6db74"> secretKeyRef:
&lt;/span>&lt;span style="color:#e6db74"> name: metis-user-password-secret
&lt;/span>&lt;span style="color:#e6db74"> key: metis-create-user-sql
&lt;/span>&lt;span style="color:#e6db74"> - name: grant-monitor-to-metis
&lt;/span>&lt;span style="color:#e6db74"> script: |
&lt;/span>&lt;span style="color:#e6db74"> GRANT pg_monitor TO metis
&lt;/span>&lt;span style="color:#e6db74"> - name: create-metis-database
&lt;/span>&lt;span style="color:#e6db74"> script: |
&lt;/span>&lt;span style="color:#e6db74"> CREATE DATABASE metis OWNER metis
&lt;/span>&lt;span style="color:#e6db74"> - name: grant-conntent-to-metis-database
&lt;/span>&lt;span style="color:#e6db74"> script: |
&lt;/span>&lt;span style="color:#e6db74"> GRANT CONNECT ON DATABASE metis TO metis
&lt;/span>&lt;span style="color:#e6db74"> - name: create-pgstatstatements-extension
&lt;/span>&lt;span style="color:#e6db74"> database: metis
&lt;/span>&lt;span style="color:#e6db74"> script: |
&lt;/span>&lt;span style="color:#e6db74"> CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
&lt;/span>&lt;span style="color:#e6db74">EOF&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can see the script has five parts. First, we create the user with a password and store the password in the Kubernetes secret. Next, we give &lt;strong>&lt;em>pg_monitor&lt;/em>&lt;/strong> permissions to the user. Next, we create the database. Then, we let the user connect to the database. Finally, we create the &lt;strong>&lt;em>pg_stat_statements&lt;/em>&lt;/strong> extension in the &lt;strong>&lt;em>metis&lt;/em>&lt;/strong> database.&lt;/p>
&lt;p>We are now ready to create the Postgres cluster:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">cat &lt;span style="color:#e6db74">&amp;lt;&amp;lt; EOF | kubectl apply -f -
&lt;/span>&lt;span style="color:#e6db74">apiVersion: stackgres.io/v1
&lt;/span>&lt;span style="color:#e6db74">kind: SGCluster
&lt;/span>&lt;span style="color:#e6db74">metadata:
&lt;/span>&lt;span style="color:#e6db74"> namespace: stackgres
&lt;/span>&lt;span style="color:#e6db74"> name: cluster
&lt;/span>&lt;span style="color:#e6db74">spec:
&lt;/span>&lt;span style="color:#e6db74"> postgres:
&lt;/span>&lt;span style="color:#e6db74"> version: &amp;#39;15.0&amp;#39;
&lt;/span>&lt;span style="color:#e6db74"> instances: 1
&lt;/span>&lt;span style="color:#e6db74"> pods:
&lt;/span>&lt;span style="color:#e6db74"> persistentVolume:
&lt;/span>&lt;span style="color:#e6db74"> size: &amp;#39;5Gi&amp;#39;
&lt;/span>&lt;span style="color:#e6db74"> managedSql:
&lt;/span>&lt;span style="color:#e6db74"> scripts:
&lt;/span>&lt;span style="color:#e6db74"> - sgScript: cluster-scripts
&lt;/span>&lt;span style="color:#e6db74">EOF&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>It should take a few seconds to a few minutes for the cluster to be up and running:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl get pods -n stackgres
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">NAME READY STATUS RESTARTS AGE
cluster-0 6/6 Running &lt;span style="color:#ae81ff">0&lt;/span> 74s
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Likewise, a database named &lt;strong>&lt;em>metis&lt;/em>&lt;/strong> must exist and be owned by the same user:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl -n stackgres exec -it cluster-0 -c postgres-util -- psql -l metis
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash"> List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
--------+----------+----------+---------+---------+------------+-----------------+--------------------
metis | metis | UTF8 | C.UTF-8 | C.UTF-8 | | libc | &lt;span style="color:#f92672">=&lt;/span>Tc/metis
...
&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="deploying-metis">Deploying Metis&lt;/h3>
&lt;p>We can now add monitoring of the database to Metis. Go to &lt;a href="https://app.metisdata.io/monitoring">Metis&lt;/a> and click &lt;strong>&lt;em>Deploy&lt;/em>&lt;/strong>:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-deploy.png" alt="Metis Deploy" title="Deploy">&lt;/p>
&lt;p>Select &lt;strong>&lt;em>Postgres&lt;/em>&lt;/strong> and click &lt;strong>&lt;em>Next&lt;/em>&lt;/strong>:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-select-vendor.png" alt="Metis Select Vendor" title="Select vendor">&lt;/p>
&lt;p>Metis instructs us how to configure the user and grant necessary permissions. We already did that. Click &lt;strong>&lt;em>Next&lt;/em>&lt;/strong>.&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-host-connection.png" alt="Metis Host Connection" title="Metis Host Connection">&lt;/p>
&lt;p>Metis asks for the connection string now:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-configuration.png" alt="Metis Configuration" title="Metis Configuration">&lt;/p>
&lt;p>Let’s extract the server name:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl get svc -n stackgres
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">NAME TYPE CLUSTER-IP EXTERNAL-IP PORT&lt;span style="color:#f92672">(&lt;/span>S&lt;span style="color:#f92672">)&lt;/span> AGE
cluster ClusterIP 10.99.23.208 &amp;lt;none&amp;gt; 5432/TCP,5433/TCP 2m34s
cluster-config ClusterIP None &amp;lt;none&amp;gt; &amp;lt;none&amp;gt; 2m34s
cluster-primary ExternalName &amp;lt;none&amp;gt; cluster.stackgres.svc.cluster.local &amp;lt;none&amp;gt; 2m34s
cluster-replicas ClusterIP 10.103.149.23 &amp;lt;none&amp;gt; 5432/TCP,5433/TCP 2m34s
cluster-rest ClusterIP 10.104.238.166 &amp;lt;none&amp;gt; 8008/TCP 2m34s
stackgres-operator ClusterIP 10.108.192.220 &amp;lt;none&amp;gt; 443/TCP 34m
stackgres-restapi ClusterIP 10.103.146.192 &amp;lt;none&amp;gt; 443/TCP 33m
&lt;/code>&lt;/pre>&lt;/div>&lt;p>The service name is &lt;strong>cluster.stackgres.svc.cluster.local&lt;/strong>. The final URL should be like this:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">postgresql://metis:admin123@cluster.stackgres.svc.cluster.local:5432/postgres?sslmode&lt;span style="color:#f92672">=&lt;/span>disable
&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-connection-string.png" alt="Metis Connection String" title="Metis Connection String">&lt;/p>
&lt;p>Click &lt;strong>&lt;em>Next&lt;/em>&lt;/strong>. Finally, click on &lt;strong>&lt;em>Helm&lt;/em>&lt;/strong> and copy the script to deploy Metis.&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-helm.png" alt="Metis Helm" title="Metis Helm">&lt;/p>
&lt;p>Extend the script with &lt;strong>&lt;em>--namespace stackgres&lt;/em>&lt;/strong> and run it. Your API key will be different as its a specific API key to be used with your project:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">helm repo add metis https://charts.metisdata.io
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">helm install mmc metis/mmc-chart --namespace stackgres --set API_KEY&lt;span style="color:#f92672">=&lt;/span>YOURAPIKEY --set-json CONNECTION_STRING&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;[{ &amp;#34;uri&amp;#34;:&amp;#34;postgresql://metis:admin123@cluster.stackgres.svc.cluster.local:5432/metis?sslmode=disable&amp;#34; }]&amp;#39;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>When you execute the script, you should get the following:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">NAME: mmc
LAST DEPLOYED: Tue Jan &lt;span style="color:#ae81ff">23&lt;/span> 11:24:14 &lt;span style="color:#ae81ff">2024&lt;/span>
NAMESPACE: stackgres
STATUS: deployed
REVISION: &lt;span style="color:#ae81ff">1&lt;/span>
TEST SUITE: None
&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can verify that it works with:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl get pods -n stackgres
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">NAME READY STATUS RESTARTS AGE
cluster-0 6/6 Running &lt;span style="color:#ae81ff">0&lt;/span> 25m
mmc-deployment-58dbb76fcc-vnnd5 1/1 Running &lt;span style="color:#ae81ff">0&lt;/span> 13s
&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can now go to &lt;a href="https://app.metisdata.io/monitoring">Metis Monitoring&lt;/a> and see that the new host has been added:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-monitoring.png" alt="Metis Monitoring" title="Metis Monitoring">&lt;/p>
&lt;p>When you click on the host, you should see the properties and databases:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-databases.png" alt="Metis Database" title="Metis Database">&lt;/p>
&lt;p>You can also click on database &lt;strong>&lt;em>metis&lt;/em>&lt;/strong> and get all the details:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-observability.png" alt="Metis Observability" title="Metis Observability">&lt;/p>
&lt;p>Notice that many charts are empty as it’s a completely new database.&lt;/p>
&lt;h2 id="monitoring-live-database-activity">Monitoring Live Database Activity&lt;/h2>
&lt;p>Let’s now add some data and run some queries in the database.&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl -n stackgres exec -it cluster-0 -c postgres-util -- psql --username&lt;span style="color:#f92672">=&lt;/span>metis --dbname&lt;span style="color:#f92672">=&lt;/span>metis -c &lt;span style="color:#e6db74">&amp;#34;CREATE TABLE orders(region VARCHAR(100), amount INT, product VARCHAR(100))&amp;#34;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl -n stackgres exec -it cluster-0 -c postgres-util -- psql --username&lt;span style="color:#f92672">=&lt;/span>metis --dbname&lt;span style="color:#f92672">=&lt;/span>metis -c &lt;span style="color:#e6db74">&amp;#34;INSERT INTO orders(region, amount, product)VALUES (&amp;#39;EU&amp;#39;, 10, &amp;#39;Product1&amp;#39;), (&amp;#39;EU&amp;#39;, 20, &amp;#39;Product2&amp;#39;), (&amp;#39;US&amp;#39;, 1, &amp;#39;XYZ&amp;#39;), (&amp;#39;JP&amp;#39;, 10, &amp;#39;ABC&amp;#39;)&amp;#34;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">kubectl -n stackgres exec -it cluster-0 -c postgres-util -- psql --username&lt;span style="color:#f92672">=&lt;/span>metis --dbname&lt;span style="color:#f92672">=&lt;/span>metis -c &lt;span style="color:#e6db74">&amp;#34;SELECT region, product, (SELECT SUM(amount) AS total_sales FROM orders AS o2 WHERE o2.region = o.region GROUP BY region)
&lt;/span>&lt;span style="color:#e6db74">FROM orders AS o
&lt;/span>&lt;span style="color:#e6db74">WHERE region IN (
&lt;/span>&lt;span style="color:#e6db74"> SELECT region
&lt;/span>&lt;span style="color:#e6db74"> FROM orders
&lt;/span>&lt;span style="color:#e6db74"> GROUP BY region
&lt;/span>&lt;span style="color:#e6db74"> HAVING SUM(amount) &amp;gt; (
&lt;/span>&lt;span style="color:#e6db74"> SELECT SUM(amount)
&lt;/span>&lt;span style="color:#e6db74"> FROM orders
&lt;/span>&lt;span style="color:#e6db74"> ) / 10
&lt;/span>&lt;span style="color:#e6db74">)&amp;#34;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>We create table &lt;strong>&lt;em>orders&lt;/em>&lt;/strong>, insert some data, and then run a query that extracts the rows with some aggregation. This is the output:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-bash" data-lang="bash">region | product | total_sales
--------+----------+-------------
EU | Product1 | &lt;span style="color:#ae81ff">30&lt;/span>
EU | Product2 | &lt;span style="color:#ae81ff">30&lt;/span>
JP | ABC | &lt;span style="color:#ae81ff">10&lt;/span>
&lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">3&lt;/span> rows&lt;span style="color:#f92672">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can now go to Metis and check the &lt;strong>&lt;em>Table Sizes&lt;/em>&lt;/strong> widget. It shows the &lt;strong>&lt;em>orders&lt;/em>&lt;/strong> table:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-table-sizes.png" alt="Metis Table Sizes" title="Metis Table Sizes">&lt;/p>
&lt;p>You can also go to &lt;strong>&lt;em>Top Queries&lt;/em>&lt;/strong> widget and notice that new queries are flowing to the database:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/metis-top-queries.png" alt="Metis Top Queries" title="Metis Top Queries">&lt;/p>
&lt;p>Metis captures the live activity of your database and can suggest how to improve things.&lt;/p>
&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>Throughout this article, we have explored the process of setting up a Kubernetes cluster, deploying the StackGres operator, and running Metis on top of it. We have covered steps such as creating an SGCluster, and monitoring basic database operations with Metis.&lt;/p>
&lt;p>If you&amp;rsquo;re eager to try Metis and experience its capabilities firsthand, we encourage you to try it out in your own Kubernetes environment, through the StackGres operator.&lt;/p>
&lt;p>Here&amp;rsquo;s the &lt;a href="https://stackgres.io/doc/latest/runbooks/">Stackgres runbook&lt;/a> and &lt;a href="https://docs.metisdata.io/SetupMetis/">Metis Guide&lt;/a> to get you started.&lt;/p>
&lt;p>If you encounter any issue or just wish to say &amp;ldquo;Hi!&amp;rdquo; and tell us how Metis works on StackGres, you may drop a line at the:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://metisdata.io/metis-discord">Metis Discord&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://slack.stackgres.io/">StackGres Community Slack&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>‍&lt;/p></description></item><item><title>How to Run FerretDB on Top of StackGres</title><link>https://stackgres.io/blog/how-to-run-ferretdb-on-top-of-stackgres/</link><pubDate>Wed, 16 Aug 2023 12:05:34 +0100</pubDate><guid>https://stackgres.io/blog/how-to-run-ferretdb-on-top-of-stackgres/</guid><description>&lt;p>In this how-to guide, we’ll walk you through the whole process of setting up &lt;a href="https://www.ferretdb.io/">FerretDB&lt;/a> on a Kubernetes cluster using &lt;a href="https://stackgres.io/">StackGres&lt;/a>.&lt;/p>
&lt;p>As an open-source MongoDB alternative, FerretDB translates MongoDB wire protocols to SQL using a &lt;a href="https://www.postgresql.org/">PostgreSQL&lt;/a> backend. And by using the StackGres operator, you can easily deploy and manage PostgreSQL instances, as well as access all the management features you need.&lt;/p>
&lt;p>So if you&amp;rsquo;re exploring a scalable and open-source MongoDB alternative on your Kubernetes cluster, then this article on FerretDB and StackGres should pique your interest.&lt;/p>
&lt;br/>
&lt;hr/>
&lt;br/>
&lt;div class="box smPad relative">
&lt;div class="whiteGradient border">&lt;/div>
This post has been published with explicit permission from FerretDB. It's a copy of an article originally published on FerretDB's website &lt;a href="https://blog.ferretdb.io/run-ferretdb-on-stackgres/" target="_blank">on July 13, 2023&lt;/a>.
&lt;/div>
&lt;br/>
&lt;hr/>
&lt;br/>
&lt;h2 id="ongres-stackgres">OnGres (StackGres)&lt;/h2>
&lt;p>&lt;a href="https://stackgres.io">StackGres&lt;/a> is the full-stack Postgres Platform. A fully open source software to run your own Postgres-as-a-Service on any cloud or on-prem. StackGres is a project from &lt;a href="https://ongres.com">OnGres&lt;/a>, the Postgres laser-focused startup (“OnGres” means “ON postGRES”).&lt;/p>
&lt;p>StackGres is a Kubernetes Operator for Postgres. It allows you to create production-ready Postgres clusters in seconds. No advanced Postgres expertise required. You can use the built-in Web Console or the high level Kubernetes CRDs for CLI and GitOps.&lt;/p>
&lt;p>With StackGres, writing a simple YAML manifest (or point-and-click on the Web Console) is all that is needed to create production-ready Postgres clusters including high availability with Patroni, replication, connection pooling, automated backups, monitoring and centralized logs.&lt;/p>
&lt;p>With support for &lt;a href="https://stackgres.io/extensions">more than 150 Postgres extensions&lt;/a>, StackGres is the most extensible Postgres platform available. It also provides support for &lt;a href="https://babelfishpg.org/">Babelfish for Postgres&lt;/a> (which brings SQL Server compatibility, at the wire protocol level, SQL and T-SQL) and integrations with Citus for sharding Postgres, Timescale for time-series, Supabase and now, FerretDB.&lt;/p>
&lt;h2 id="ferretdb">FerretDB&lt;/h2>
&lt;p>FerretDB is the defacto open-source replacement for MongoDB with the popular and reliable PostgreSQL as the database backend. What FerretDB does is convert MongoDB wire protocols in BSON format into JSONB in PostgreSQL. See &lt;a href="https://blog.ferretdb.io/pjson-how-to-store-bson-in-jsonb/">this article to learn more about how this works&lt;/a>.&lt;/p>
&lt;p>Despite MongoDB’s popularity as an open-source database and its popularity among developers, after the switch from open source license to SSPL (&lt;a href="https://blog.ferretdb.io/open-source-is-in-danger/">get the full story on that here!&lt;/a>), it was important to restore MongoDB workloads back to open-source so users can have complete control of their data without vendor lock-in.&lt;/p>
&lt;p>Built on an ever-reliable PostgreSQL database backend, you can host FerretDB anywhere or run it locally on your own machine. Another significant advantage of FerretDB is that you get to use the same syntax and commands as you’re used to in MongoDB. Besides, you can also query it with SQL in PostgreSQL (in some cases, you may also need intricate knowledge of JSONB for more advanced queries).&lt;/p>
&lt;p>At present, FerretDB is compatible with the most common MongoDB use cases and plans on improving and adding more features as needs arise. Plus, we’ve just recently released &lt;a href="https://github.com/FerretDB/FerretDB/releases/tag/v1.5.0">FerretDB version 1.5.0&lt;/a>, which includes beta support for SQLite backend.&lt;/p>
&lt;p>&lt;br/>&lt;br/>&lt;/p>
&lt;hr/>
&lt;h2 id="setting-up-ferretdb-on-top-of-stackgres">Setting up FerretDB on top of StackGres&lt;/h2>
&lt;p>Before installing StackGres, you will need a running Kubernetes cluster and the usual command line tools &lt;a href="https://kubernetes.io/docs/tasks/tools/">&lt;code>kubectl&lt;/code>&lt;/a> and &lt;a href="https://helm.sh/docs/intro/install/">&lt;code>Helm&lt;/code>&lt;/a>. Please refer to the respective installation pages if you don&amp;rsquo;t have these tools.&lt;/p>
&lt;p>As for Kubernetes, if you don&amp;rsquo;t have one you can try easily with &lt;a href="https://k3s.io/">K3s&lt;/a>. It can be installed with a single command line as in:&lt;/p>
&lt;pre>&lt;code>curl -sfL https://get.k3s.io | sh -
&lt;/code>&lt;/pre>&lt;p>This should give you a running single-node cluster in seconds (depending
on your Internet connection speed).&lt;/p>
&lt;p>Keep in mind that K3s is not available natively on macOS. If you want to run it on macOS, you&amp;rsquo;ll have to use a virtual machine or a Docker container running Linux.&lt;/p>
&lt;p>First, you need to install Docker Desktop for Mac from the Docker website. After installing Docker Desktop, go to preferences and navigate to the Kubernetes tab to “Enable Kubernetes”, then click “Apply &amp;amp; Restart”.&lt;/p>
&lt;p>Fortunately, K3D is a tool that makes it easy to run K3s inside Docker, which works on macOS. You can install K3D using Homebrew and if successful, create a Kubernetes cluster:&lt;/p>
&lt;pre>&lt;code>brew install k3d &amp;amp;&amp;amp;k3d cluster create &amp;lt;cluster-name&amp;gt; --image rancher/k3s:v1.25.9-k3s1
&lt;/code>&lt;/pre>&lt;p>Then you can get the configuration so that you can connect and operate with it via both &lt;code>kubectl&lt;/code> and &lt;code>Helm&lt;/code>:&lt;/p>
&lt;pre>&lt;code>mkdir -p ~/.kube/; sudo k3s kubectl config view --raw &amp;gt;&amp;gt; ~/.kube/config
&lt;/code>&lt;/pre>&lt;p>For macOS users, using the command above might create some issues so it’s better to use this one below:&lt;/p>
&lt;pre>&lt;code>k3d kubeconfig get &amp;lt;cluster-name&amp;gt; &amp;gt; ~/.kube/config
&lt;/code>&lt;/pre>&lt;p>Once you are done you can uninstall k3s if you wish with &lt;code>sudo /usr/local/bin/k3s-uninstall.sh&lt;/code>.&lt;/p>
&lt;h2 id="installing-stackgres">Installing StackGres&lt;/h2>
&lt;p>The best way to install StackGres is through the official Helm chart. Here’s the installation guide in the official docs.&lt;/p>
&lt;p>For our particular setup, we use the following Helm commands:&lt;/p>
&lt;pre>&lt;code>helm repo add stackgres-charts https://stackgres.io/downloads/stackgres-k8s/stackgres/helm/
helm install --create-namespace --namespace stackgres stackgres-operator stackgres-charts/stackgres-operator
&lt;/code>&lt;/pre>&lt;p>To confirm that the operator is running while also waiting for setup to complete, run the following commands:&lt;/p>
&lt;pre>&lt;code>kubectl wait -n stackgres deployment -l group=stackgres.io --for=condition=Available
kubectl get pods -n stackgres -l group=stackgres.io
&lt;/code>&lt;/pre>&lt;p>As you run the first &lt;code>kubectl&lt;/code> command, it should wait for the successful deployment, and the second command will list the pods running in the &lt;code>stackgres&lt;/code> namespace.&lt;/p>
&lt;pre>&lt;code>NAME READY STATUS RESTARTS AGE
stackgres-operator-c4c6b4bcd-trsgp 1/1 Running 0 4m50s
stackgres-restapi-6986cc8997-lfwql 2/2 Running 0 4m49s
&lt;/code>&lt;/pre>&lt;h2 id="creating-a-stackgres-cluster">Creating a StackGres Cluster&lt;/h2>
&lt;p>Here, we’ll create an SGCluster configured to fit FerretDB’s requirements. Resources for the example are available in the &lt;a href="https://github.com/ongres/apps-on-stackgres/tree/main/examples/ferretdb">apps-on-stackgres GitHub repository&lt;/a>.&lt;/p>
&lt;p>Please clone the repository and navigate to the examples/ferretdb directory, which contains all the files referenced in this guide.&lt;/p>
&lt;p>To properly group all related resources together, let’s first create a namespace:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">Namespace&lt;/span>
&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">v1&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>From the apps-on-stackgres GitHub repository on your local machine, navigate to the &lt;code>examples/ferretdb&lt;/code> folder within your terminal and apply the configurations specified in the &lt;code>01-namespace.yaml&lt;/code> file to your Kubernetes cluster using this command:&lt;/p>
&lt;pre>&lt;code>kubectl apply -f 01-namespace.yaml
&lt;/code>&lt;/pre>&lt;p>During startup, FerretDB will try to configure the &lt;code>search_path&lt;/code> parameter in PostgreSQL.&lt;/p>
&lt;p>However, PgBouncer, the Postgres sidecar deployed by StackGres by default, does not support this.&lt;/p>
&lt;p>You can either choose to disable PgBouncer’s sidecar (not recommended) or customize PgBouncer’s connection pooling configuration so it ignores this parameter:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">stackgres.io/v1&lt;/span>
&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">SGPoolingConfig&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">sgpoolingconfig1&lt;/span>
&lt;span style="color:#f92672">namespace&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">pgBouncer&lt;/span>:
&lt;span style="color:#f92672">pgbouncer.ini&lt;/span>:
&lt;span style="color:#f92672">pgbouncer&lt;/span>:
&lt;span style="color:#f92672">ignore_startup_parameters&lt;/span>: &lt;span style="color:#ae81ff">extra_float_digits,search_path&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Create with:&lt;/p>
&lt;pre>&lt;code>kubectl apply -f 02-sgpoolingconfig.yaml
&lt;/code>&lt;/pre>&lt;p>FerretDB uses one or more Postgres databases, and requires them to be created and owned by a given user. In this guide, we will create one database, with one user and a unique password, but we will not be using a Potgres superuser for this.&lt;/p>
&lt;p>We plan to use the StackGres' &lt;a href="https://stackgres.io/doc/latest/reference/crd/sgscript/">SGScript&lt;/a> facility to create, manage and apply SQL scripts in the database automatically.&lt;/p>
&lt;p>First, we’ll start by creating a &lt;code>Secret&lt;/code> containing the SQL command that will generate a random password for the user.&lt;/p>
&lt;pre>&lt;code>#!/bin/sh
PASSWORD=&amp;quot;$(dd if=/dev/urandom bs=1 count=8 status=none | base64 | tr / 0)&amp;quot;
kubectl -n ferretdb create secret generic createuser \
--from-literal=sql=&amp;quot;create user ferretdb with password '&amp;quot;${PASSWORD}&amp;quot;'&amp;quot;
&lt;/code>&lt;/pre>&lt;pre>&lt;code>./03-createuser_secret.sh
&lt;/code>&lt;/pre>&lt;p>The next step is to create SGScript, which contains two scripts: a script for creating a password-protected user by obtaining the SQL literal from this &lt;code>Secret&lt;/code>, and another one to create the database, owned by this user, and configured to FerretDB&amp;rsquo;s requirements:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">stackgres.io/v1&lt;/span>
&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">SGScript&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">createuserdb&lt;/span>
&lt;span style="color:#f92672">namespace&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">scripts&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">create-user&lt;/span>
&lt;span style="color:#f92672">scriptFrom&lt;/span>:
&lt;span style="color:#f92672">secretKeyRef&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">createuser&lt;/span>
&lt;span style="color:#f92672">key&lt;/span>: &lt;span style="color:#ae81ff">sql&lt;/span>
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">create-database&lt;/span>
&lt;span style="color:#f92672">script&lt;/span>: |&lt;span style="color:#e6db74">
&lt;/span>&lt;span style="color:#e6db74"> &lt;/span> &lt;span style="color:#ae81ff">create database ferretdb owner ferretdb encoding &amp;#39;UTF8&amp;#39; locale &amp;#39;en_US.UTF-8&amp;#39; template template0;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>kubectl apply -f 04-sgscript.yaml
&lt;/code>&lt;/pre>&lt;p>We are now ready to create the Postgres cluster:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">stackgres.io/v1&lt;/span>
&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">SGCluster&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">namespace&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">postgres&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">postgres&lt;/span>:
&lt;span style="color:#f92672">version&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;15&amp;#39;&lt;/span>
&lt;span style="color:#f92672">instances&lt;/span>: &lt;span style="color:#ae81ff">1&lt;/span>
&lt;span style="color:#f92672">pods&lt;/span>:
&lt;span style="color:#f92672">persistentVolume&lt;/span>:
&lt;span style="color:#f92672">size&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;5Gi&amp;#39;&lt;/span>
&lt;span style="color:#f92672">configurations&lt;/span>:
&lt;span style="color:#f92672">sgPoolingConfig&lt;/span>: &lt;span style="color:#ae81ff">sgpoolingconfig1&lt;/span>
&lt;span style="color:#f92672">managedSql&lt;/span>:
&lt;span style="color:#f92672">scripts&lt;/span>:
- &lt;span style="color:#f92672">sgScript&lt;/span>: &lt;span style="color:#ae81ff">createuserdb&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>kubectl apply -f 05-sgcluster.yaml
&lt;/code>&lt;/pre>&lt;p>It should take a few seconds to a few minutes for the cluster to be up and running:&lt;/p>
&lt;pre>&lt;code>kubectl -n ferretdb get pods
NAME READY STATUS RESTARTS AGE
postgres-0 6/6 Running 0 16m
&lt;/code>&lt;/pre>&lt;p>Likewise, a database named &lt;code>ferretdb&lt;/code> must exist and be owned by the same user:&lt;/p>
&lt;pre>&lt;code>kubectl -n ferretdb exec -it postgres-0 -c postgres-util -- psql -l ferretdb
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
ferretdb | ferretdb | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
...
&lt;/code>&lt;/pre>&lt;h2 id="deploying-ferretdb">Deploying FerretDB&lt;/h2>
&lt;p>FerretDB itself is a stateless application, and as such, so we can just use the standard &lt;code>Deployment&lt;/code> pattern (for easy scaling) with a &lt;code>Service&lt;/code> to deploy it:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">apps/v1&lt;/span>
&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">Deployment&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">ferretdb-dep&lt;/span>
&lt;span style="color:#f92672">namespace&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">labels&lt;/span>:
&lt;span style="color:#f92672">app&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">replicas&lt;/span>: &lt;span style="color:#ae81ff">1&lt;/span>
&lt;span style="color:#f92672">selector&lt;/span>:
&lt;span style="color:#f92672">matchLabels&lt;/span>:
&lt;span style="color:#f92672">app&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">template&lt;/span>:
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">labels&lt;/span>:
&lt;span style="color:#f92672">app&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">containers&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">ghcr.io/ferretdb/ferretdb&lt;/span>
&lt;span style="color:#f92672">ports&lt;/span>:
- &lt;span style="color:#f92672">containerPort&lt;/span>: &lt;span style="color:#ae81ff">27017&lt;/span>
&lt;span style="color:#f92672">env&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">FERRETDB_POSTGRESQL_URL&lt;/span>
&lt;span style="color:#f92672">value&lt;/span>: &lt;span style="color:#ae81ff">postgres://postgres/ferretdb&lt;/span>
---
&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">v1&lt;/span>
&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">Service&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">namespace&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">selector&lt;/span>:
&lt;span style="color:#f92672">app&lt;/span>: &lt;span style="color:#ae81ff">ferretdb&lt;/span>
&lt;span style="color:#f92672">ports&lt;/span>:
- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">mongo&lt;/span>
&lt;span style="color:#f92672">protocol&lt;/span>: &lt;span style="color:#ae81ff">TCP&lt;/span>
&lt;span style="color:#f92672">port&lt;/span>: &lt;span style="color:#ae81ff">27017&lt;/span>
&lt;span style="color:#f92672">targetPort&lt;/span>: &lt;span style="color:#ae81ff">27017&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>kubectl apply -f 06-ferretdb.yaml
&lt;/code>&lt;/pre>&lt;p>Note the line where we pass the &lt;code>FERRETDB_POSTGRESQL_URL&lt;/code> environment variable to FerretDB’s container, set with the value &lt;code>postgres://postgres/ferretdb&lt;/code>: the second &lt;code>postgres&lt;/code> on the string is the &lt;code>Service&lt;/code> name that StackGres exposes pointing to the primary instance of the created cluster, which is named after the &lt;code>SGCluster&lt;/code>’s name; and &lt;code>ferretdb&lt;/code> is the name of the database.&lt;/p>
&lt;p>If all goes well, you should see the pod up &amp;amp; running. To test it, we need to run a MongoDB client. For example, we can use &lt;code>kubectl run&lt;/code> to run a &lt;code>mongosh&lt;/code> image:&lt;/p>
&lt;pre>&lt;code>kubectl -n ferretdb run mongosh --image=rtsp/mongosh --rm -it -- bash
&lt;/code>&lt;/pre>&lt;p>FerretDB exposes the same Postgres database, usernames, and passwords over the MongoDB wire protocol. In that case, we have access to the user, password, and database that were created previously using &lt;code>SGScript&lt;/code>.&lt;/p>
&lt;p>When the terminal prompt appears, type the command:&lt;/p>
&lt;pre>&lt;code>mongosh mongodb://ferretdb:${PASSWORD}@${FERRETDB_SVC}/ferretdb?authMechanism=PLAIN
&lt;/code>&lt;/pre>&lt;p>where &lt;code>${PASSWORD}&lt;/code> represents the randomly generated password for the &lt;code>ferretdb&lt;/code> user in Postgres:&lt;/p>
&lt;pre>&lt;code>kubectl -n ferretdb get secret createuser --template '{{ printf &amp;quot;%s\n&amp;quot; (.data.sql | base64decode) }}'
&lt;/code>&lt;/pre>&lt;p>and &lt;code>${FERRETDB_SVC}&lt;/code> is the address and port exposed by the FerretDB &lt;code>Service&lt;/code> (&lt;code>10.43.94.52:27017&lt;/code> in the example below):&lt;/p>
&lt;pre>&lt;code>kubectl -n ferretdb get svc ferretdb
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ferretdb ClusterIP 10.43.94.52 &amp;lt;none&amp;gt; 27017/TCP 10m
&lt;/code>&lt;/pre>&lt;h2 id="quickstart-example">QuickStart Example&lt;/h2>
&lt;p>Once the mongosh command is executed, you can try inserting and querying data:&lt;/p>
&lt;pre>&lt;code>ferretdb&amp;gt; db.test.insertOne({a:1})
{
acknowledged: true,
insertedId: ObjectId(&amp;quot;646dca174663396264d4bfeb&amp;quot;)
}
ferretdb&amp;gt; db.test.find()
[ { _id: ObjectId(&amp;quot;646dca174663396264d4bfeb&amp;quot;), a: 1 } ]
&lt;/code>&lt;/pre>&lt;p>If you are curious, you can see how data was materialized on the Postgres database:&lt;/p>
&lt;pre>&lt;code>kubectl -n ferretdb exec -it postgres-0 -c postgres-util -- psql ferretdb
psql (15.1 (OnGres 15.1-build-6.18))
Type &amp;quot;help&amp;quot; for help.
ferretdb=# set search_path to ferretdb;
SET
ferretdb=# \dt
List of relations
Schema | Name | Type | Owner
----------+-----------------------------+-------+----------
ferretdb | _ferretdb_database_metadata | table | ferretdb
ferretdb | test_afd071e5 | table | ferretdb
(2 rows)
ferretdb=# table test_afd071e5;
_jsonb
-----------------------------------------------------------------------------------------------------------------------------
{&amp;quot;a&amp;quot;: 1, &amp;quot;$s&amp;quot;: {&amp;quot;p&amp;quot;: {&amp;quot;a&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;int&amp;quot;}, &amp;quot;_id&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;objectId&amp;quot;}}, &amp;quot;$k&amp;quot;: [&amp;quot;_id&amp;quot;, &amp;quot;a&amp;quot;]}, &amp;quot;_id&amp;quot;: &amp;quot;646dca174663396264d4bfeb&amp;quot;}
(1 row)
&lt;/code>&lt;/pre>&lt;h2 id="creating-a-meteor-example-with-ferretdb-on-top-of-stackgres">Creating a Meteor example with FerretDB on top of Stackgres&lt;/h2>
&lt;p>To test and run our entire setup locally, we can use port forwarding with &lt;code>kubectl&lt;/code> command, which should forward all connections from our local machine port to the &lt;code>ferretdb&lt;/code> service’s port &lt;code>27017&lt;/code> in the cluster.&lt;/p>
&lt;pre>&lt;code>kubectl port-forward svc/ferretdb 27017:27017 -n ferretdb
&lt;/code>&lt;/pre>&lt;p>In a new terminal, run this command to be sure your connection is working. Note that this requires that you have mongosh installed.&lt;/p>
&lt;pre>&lt;code>mongosh 'mongodb://ferretdb:${PASSWORD}@localhost:27017/ferretdb?authMechanism=PLAIN'
&lt;/code>&lt;/pre>&lt;p>To test our database locally, we’ll be executing commands from a Meteor application.&lt;/p>
&lt;p>If you don’t have Meteor installed, you can install it by following the steps in their documentation. Then create a project using&lt;/p>
&lt;pre>&lt;code>meteor create &amp;lt;app-name&amp;gt;
cd &amp;lt;app-name&amp;gt;
meteor npm install
&lt;/code>&lt;/pre>&lt;p>Be sure to replace &lt;code>&amp;lt;app-name&amp;gt;&lt;/code> with that of your project.&lt;/p>
&lt;p>Without making any changes, on startup, the function will insert documents with the fields &lt;code>title&lt;/code>, &lt;code>url&lt;/code>, &lt;code>createdAt&lt;/code> as long as there are none present.&lt;/p>
&lt;pre>&lt;code>async function insertLink({ title, url }) {
await LinksCollection.insertAsync({ title, url, createdAt: new Date() });
}
Meteor.startup(async () =&amp;gt; {
// If the Links collection is empty, add some data.
if (await LinksCollection.find().countAsync() === 0) {
await insertLink({
title: 'Do the Tutorial',
url: 'https://www.meteor.com/tutorials/react/creating-an-app',
});
await insertLink({
title: 'Follow the Guide',
url: 'https://guide.meteor.com',
});
await insertLink({
title: 'Read the Docs',
url: 'https://docs.meteor.com',
});
await insertLink({
title: 'Discussions',
url: 'https://forums.meteor.com',
});
}
// We publish the entire Links collection to all clients.
// In order to be fetched in real-time to the clients
Meteor.publish(&amp;quot;links&amp;quot;, function () {
return LinksCollection.find();
});
});
&lt;/code>&lt;/pre>&lt;p>Once installed, you can run it locally by connecting the MongoDB URL with Meteor, which then sets the environment variable for the MongoDB connection string. This way, Meteor will use an external MongoDB database instead of starting its own.&lt;/p>
&lt;pre>&lt;code>MONGO_URL='mongodb://username:password@localhost:27017/mydatabase' meteor
&lt;/code>&lt;/pre>&lt;p>You can check out these documents in the Postgres database.&lt;/p>
&lt;pre>&lt;code>ferretdb-# \dt
List of relations
Schema | Name | Type | Owner
----------+-----------------------------+-------+----------
ferretdb | _ferretdb_database_metadata | table | ferretdb
ferretdb | links_e9ca9aee | table | ferretdb
ferretdb | test_afd071e5 | table | ferretdb
(3 rows)
ferretdb=# table links_e9ca9aee;
_jsonb
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{&amp;quot;$s&amp;quot;: {&amp;quot;p&amp;quot;: {&amp;quot;_id&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;url&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;title&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;createdAt&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;date&amp;quot;}}, &amp;quot;$k&amp;quot;: [&amp;quot;_id&amp;quot;, &amp;quot;title&amp;quot;, &amp;quot;url&amp;quot;, &amp;quot;createdAt&amp;quot;]}, &amp;quot;_id&amp;quot;: &amp;quot;7NmpEw6k7z7HNTJpf&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://www.meteor.com/tutorials/react/creating-an-app&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;Do the Tutorial&amp;quot;, &amp;quot;createdAt&amp;quot;: 1687291371079}
{&amp;quot;$s&amp;quot;: {&amp;quot;p&amp;quot;: {&amp;quot;_id&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;url&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;title&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;createdAt&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;date&amp;quot;}}, &amp;quot;$k&amp;quot;: [&amp;quot;_id&amp;quot;, &amp;quot;title&amp;quot;, &amp;quot;url&amp;quot;, &amp;quot;createdAt&amp;quot;]}, &amp;quot;_id&amp;quot;: &amp;quot;f3D3wB25KGduKzbsc&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://guide.meteor.com&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;Follow the Guide&amp;quot;, &amp;quot;createdAt&amp;quot;: 1687291371148}
{&amp;quot;$s&amp;quot;: {&amp;quot;p&amp;quot;: {&amp;quot;_id&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;url&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;title&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;createdAt&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;date&amp;quot;}}, &amp;quot;$k&amp;quot;: [&amp;quot;_id&amp;quot;, &amp;quot;title&amp;quot;, &amp;quot;url&amp;quot;, &amp;quot;createdAt&amp;quot;]}, &amp;quot;_id&amp;quot;: &amp;quot;rdJH59NGgnonSSe5o&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://docs.meteor.com&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;Read the Docs&amp;quot;, &amp;quot;createdAt&amp;quot;: 1687291371159}
{&amp;quot;$s&amp;quot;: {&amp;quot;p&amp;quot;: {&amp;quot;_id&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;url&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;title&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;string&amp;quot;}, &amp;quot;createdAt&amp;quot;: {&amp;quot;t&amp;quot;: &amp;quot;date&amp;quot;}}, &amp;quot;$k&amp;quot;: [&amp;quot;_id&amp;quot;, &amp;quot;title&amp;quot;, &amp;quot;url&amp;quot;, &amp;quot;createdAt&amp;quot;]}, &amp;quot;_id&amp;quot;: &amp;quot;zoGgwqbofdGDvPyj4&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://forums.meteor.com&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;Discussions&amp;quot;, &amp;quot;createdAt&amp;quot;: 1687291371164}
(4 rows)
&lt;/code>&lt;/pre>&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>With FerretDB, you can seamlessly store and access your data, enabling the flexibility and freedom of using MongoDB&amp;rsquo;s document model and syntax without the vendor lock-in.&lt;/p>
&lt;p>Throughout this article, we have explored the process of setting up a Kubernetes cluster, deploying the StackGres operator, and running FerretDB on top of it. We have covered steps such as creating an SGCluster, and performing basic database operations in FerretDB.&lt;/p>
&lt;p>If you&amp;rsquo;re eager to try FerretDB and experience its capabilities firsthand, we encourage you to try it out in your own Kubernetes environment, through the StackGres operator.&lt;/p>
&lt;p>Here’s the &lt;a href="https://stackgres.io/doc/latest/runbooks/ferretdb-stackgres/">Stackgres runbook&lt;/a> and &lt;a href="https://docs.ferretdb.io/quickstart-guide/">FerretDB installation guide&lt;/a> to get you started.&lt;/p>
&lt;p>If you encounter any issue or just wish to say “Hi!” and tell us how FerretDB works on StackGres, you may drop a line at the:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.ferretdb.io/#community">FerretDB Community channels&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://slack.stackgres.io">StackGres Community Slack&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Easily Running Babelfish for PostgreSQL on Kubernetes</title><link>https://stackgres.io/blog/easily-running-babelfish-for-postgresql-on-kubernetes/</link><pubDate>Mon, 15 Nov 2021 20:05:34 +0100</pubDate><guid>https://stackgres.io/blog/easily-running-babelfish-for-postgresql-on-kubernetes/</guid><description>&lt;h1 id="easily-running-babelfish-for-postgresql-on-kubernetes">Easily Running Babelfish for PostgreSQL on Kubernetes&lt;/h1>
&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Babelfish for PostgreSQL (&amp;ldquo;Babelfish&amp;rdquo; in short) is &lt;a href="https://babelfishpg.org">an open source project&lt;/a> created by Amazon AWS that adds SQL Server compatibility on top of Postgres. It was made public a couple of weeks ago both as a managed service and as an open source project. Using the latter involves as of today compiling it from source, which requires some effort and expertise. To contribute a better user’s experience, &lt;strong>the upcoming StackGres 1.1.0 release has added Babelfish, making it trivially easy to run Babelfish on Kubernetes&lt;/strong>.&lt;/p>
&lt;p>If, for any reason, you don’t have a Kubernetes cluster handy; and/or you are not familiar with Kubernetes, please jump first to the &lt;strong>Appendix in the last section, where I show how to get up &amp;amp; running a lightweight Kubernetes cluster in 1 minute&lt;/strong>.&lt;/p>
&lt;h2 id="babelfish-for-postgresql">Babelfish for PostgreSQL&lt;/h2>
&lt;p>Around one year ago, Amazon surprised us all by announcing &lt;strong>Babelfish for PostgreSQL&lt;/strong>, a project that would bring a SQL Server compatibility layer on top of Postgres. Babelfish would become both an AWS managed service (on Aurora); as well as an open source project! I then &lt;a href="https://www.ongres.com/blog/aws_announces_open_source_postgres_with_sql_server_compatibility/">blogged about it&lt;/a>, knowing that this was a disruption point for Postgres. Babelfish enables Postgres to reach out to many other use cases, users and Communities: the SQL Server ecosystem.&lt;/p>
&lt;p>Adding yet another capability to Postgres reflects on the thoughts shared by Stephen O’Grady on a recent post, &lt;a href="https://redmonk.com/sogrady/2021/10/26/general-purpose-database/">A Return to the General Purpose Database&lt;/a>. Postgres is not only a feature-full relational database; but with its extensions, it’s also a time-series database; a sharded database; a graph database; and now, also a SQL Server-compatible database. Postgres is, and will be, the unifying database for almost every imaginable database workload.&lt;/p>
&lt;p>At StackGres we were almost literally eating our finger’s nails, waiting for Babelfish to be finally published as open source. It finally happened &lt;a href="https://babelfishpg.org/blog/releases/2021/10/babelfish-launch/">a couple of weeks ago&lt;/a>. Since then, &lt;strong>our team has been working tirelessly to give you an easy way to run Babelfish on Kubernetes, by integrating Babelfish in StackGres. Kudos to the whole team for such an amazing job!&lt;/strong>&lt;/p>
&lt;p>Not only are we making Babelfish available on Kubernetes; but also giving to the Community the first (as far as we know) mechanism to run the open source Babelfish version without having to go through the (somehow involved) process of &lt;a href="https://babelfishpg.org/docs/installation/compiling-babelfish-from-source/">compiling it from the source code&lt;/a>. &lt;strong>With StackGres, you can go from zero to Babelfish in one command to install StackGres; and a 15-lines YAML to create a Babelfish-enabled cluster. It can’t hardly get easier than this&lt;/strong>.&lt;/p>
&lt;h2 id="install-stackgres-110-beta1-with-babelfish-support">Install StackGres 1.1.0-beta1 with Babelfish support&lt;/h2>
&lt;p>Installation is just one command. The recommended installation method is with &lt;a href="https://helm.sh/">Helm&lt;/a>:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ helm install --namespace stackgres --create-namespace stackgres &lt;span style="color:#ae81ff">\
&lt;/span>&lt;span style="color:#ae81ff">&lt;/span> https://stackgres.io/downloads/stackgres-k8s/stackgres/1.1.0-beta1/helm/stackgres-operator.tgz
&lt;/code>&lt;/pre>&lt;/div>&lt;p>In some seconds / a minute you should have StackGres installed. If you see the StackGres ascii-art logo, you are ready to go!&lt;/p>
&lt;h2 id="create-a-babelfish-cluster">Create a Babelfish cluster&lt;/h2>
&lt;p>Creating a Babelfish cluster is not so much different from creating a simple Postgres cluster. The few differences will be highlighted. Follow the instructions on either of the next two sections (&amp;quot;&lt;strong>Using kubectl&lt;/strong>&amp;quot; or &amp;ldquo;&lt;strong>Using the Web Console&lt;/strong>&amp;quot;), depending on your preferences. You can use either method interchangeably.&lt;/p>
&lt;p>First, create a namespace:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl create namespace notmssql
&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="using-kubectl">Using kubectl&lt;/h3>
&lt;p>Create the following 15-line file &lt;code>bbf.yaml&lt;/code> with the following content:&lt;/p>
&lt;pre class="language-yaml">
&lt;span class="pink">kind&lt;/span>: SGCluster
&lt;span class="pink">apiVersion&lt;/span>: stackgres.io/v1
&lt;span class="pink">metadata&lt;/span>:
&lt;span class="pink">namespace&lt;/span>: notmssql
&lt;span class="pink">name&lt;/span>: bbf
&lt;span class="pink">spec&lt;/span>:
&lt;span class="pink">instances&lt;/span>: 1
&lt;span class="pink">postgres&lt;/span>:
&lt;span class="pink">version&lt;/span>: &lt;span class="yellow">'latest'&lt;/span>
&lt;b class="highlight">&lt;span class="pink">flavor&lt;/span>: babelfish&lt;/b>
&lt;span class="pink">pods&lt;/span>:
&lt;span class="pink">persistentVolume&lt;/span>:
&lt;span class="pink">size&lt;/span>: &lt;span class="yellow">'5Gi'&lt;/span>
&lt;b class="highlight">&lt;span class="pink">nonProductionOptions&lt;/span>:
&lt;span class="pink">enabledFeatureGates&lt;/span>: [ &lt;span class="yellow">"babelfish-flavor"&lt;/span> ]&lt;/b>
&lt;/pre>
&lt;p>The main differences between creating a Babelfish cluster and a regular (vanilla Postgres) cluster are:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The &lt;code>.spec.postgres.flavor&lt;/code> field must be set to &lt;code>babelfish&lt;/code>. If unset, it is assumed the default &amp;ldquo;vanilla&amp;rdquo; Postgres flavor. Also note that the version: &lt;code>latest&lt;/code> field automatically resolves to different versions, depending on the flavor (14.0 for the default Postgres flavor and 13.4 for Babelfish).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Babelfish is in preview mode in StackGres. It is not considered production ready. As such, you need to explicitly enable a feature gate named &lt;code>babelfish-flavor&lt;/code> or cluster creation would be rejected by StackGres. This is what the two last lines do.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Finally apply it with:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl apply -f bbf.yaml
&lt;/code>&lt;/pre>&lt;/div>&lt;p>In around a minute, &lt;strong>you should get your Babelfish cluster running on StackGres&lt;/strong>! It wasn’t hard, was it? You can check that the cluster is up and running:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl -n notmssql get pods
NAME READY STATUS RESTARTS AGE
bbf-0 6/6 Running &lt;span style="color:#ae81ff">0&lt;/span> 11m
&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="using-the-web-console">Using the Web Console&lt;/h3>
&lt;p>StackGres comes bundled with a fully-featured Web Console, that it’s installed by default. For simplicity, let’s use the port-forwarding mechanism of kubectl to expose it on a port local to your computer:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ WEBC&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>kubectl --namespace stackgres get pods -l &lt;span style="color:#e6db74">&amp;#34;app=stackgres-restapi&amp;#34;&lt;/span> -o jsonpath&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;{.items[0].metadata.name}&amp;#34;&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>
$ kubectl --namespace stackgres port-forward &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$WEBC&lt;span style="color:#e6db74">&amp;#34;&lt;/span> 8443:9443
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Open in your web browser the address &lt;a href="https://localhost:8443">https://localhost:8443&lt;/a>. You will see a warning (expected, the certificate is self-signed, you may also bring your own with custom Helm parameters). The default username is admin. The password is generated randomly and can be queried with the following command:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl -n stackgres get secret stackgres-restapi --template &lt;span style="color:#e6db74">&amp;#39;{{ printf &amp;#34;%s\n&amp;#34; (.data.clearPassword | base64decode) }}&amp;#39;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Select the notmssql namespace in the dropdown. And proceed to create a new SGCluster. Select the Babelfish flavor (you will see that the feature gate &amp;ldquo;Babelfish Flavor&amp;rdquo; becomes enabled). It should look like the following screenshot:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/create_babelfish_cluster-web_console.png" alt="Create a Babelfish cluster from the Web Console">&lt;/p>
&lt;h2 id="connecting-to-your-babelfish-cluster-via-the-tds-protocol">Connecting to your Babelfish cluster via the TDS protocol&lt;/h2>
&lt;p>Babelfish speaks the TDS protocol, like SQL Server. By default it listens in the same TCP port, 1433, and this is also what StackGres exposes.&lt;/p>
&lt;p>To easily get connected using the TDS protocol, this StackGres release also includes with the &lt;code>postgres-util&lt;/code> sidecar of every pod the command line utility &lt;a href="https://github.com/xo/usql">usql&lt;/a>, a database client that supports many databases, including SQL Server. By default, StackGres installation creates a database named &lt;code>babelfish&lt;/code>, owned by a superuser named &lt;code>babelfish&lt;/code>, that is initialized to be connected via the TDS protocol, with all the required Babelfish extensions already loaded. The password is generated randomly and can be obtained from the secret named after the cluster name:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl -n notmssql get secret bbf --template &lt;span style="color:#e6db74">&amp;#39;{{ printf &amp;#34;%s&amp;#34; (index .data &amp;#34;babelfish-password&amp;#34; | base64decode) }}&amp;#39;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Knowing the password, we can trivially connect to Babelfish with usql, using the SQL Server protocol, and run some example &lt;strong>T-SQL&lt;/strong> queries:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl -n notmssql exec -it bbf-0 -c postgres-util -- usql --password ms://babelfish@localhost
Enter password:
Connected with driver sqlserver &lt;span style="color:#f92672">(&lt;/span>Microsoft SQL Server 12.0.2000.8, , Standard Edition&lt;span style="color:#f92672">)&lt;/span>
Type &lt;span style="color:#e6db74">&amp;#34;help&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">for&lt;/span> help.
ms:babelfish@localhost&lt;span style="color:#f92672">=&lt;/span>&amp;gt; &lt;span style="color:#66d9ef">select&lt;/span> @@version;
version
----------------------------------------------------------------------
Babelfish &lt;span style="color:#66d9ef">for&lt;/span> PostgreSQL with SQL Server Compatibility - 12.0.2000.8+
Nov &lt;span style="color:#ae81ff">3&lt;/span> &lt;span style="color:#ae81ff">2021&lt;/span> 09:55:42 +
Copyright &lt;span style="color:#f92672">(&lt;/span>c&lt;span style="color:#f92672">)&lt;/span> Amazon Web Services +
PostgreSQL 13.4 &lt;span style="color:#66d9ef">for&lt;/span> Babelfish OnGres Inc. on x86_64-pc-linux-gnu
&lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span> row&lt;span style="color:#f92672">)&lt;/span>
ms:babelfish@localhost&lt;span style="color:#f92672">=&lt;/span>&amp;gt; create schema sch1;
CREATE SCHEMA
ms:babelfish@localhost&lt;span style="color:#f92672">=&lt;/span>&amp;gt; create table &lt;span style="color:#f92672">[&lt;/span>sch1&lt;span style="color:#f92672">]&lt;/span>.test &lt;span style="color:#f92672">(&lt;/span>
ms:babelfish@localhost&lt;span style="color:#f92672">(&lt;/span>&amp;gt; pk int primary key identity&lt;span style="color:#f92672">(&lt;/span>1,1&lt;span style="color:#f92672">)&lt;/span>,
ms:babelfish@localhost&lt;span style="color:#f92672">(&lt;/span>&amp;gt; text varchar&lt;span style="color:#f92672">(&lt;/span>50&lt;span style="color:#f92672">)&lt;/span>,
ms:babelfish@localhost&lt;span style="color:#f92672">(&lt;/span>&amp;gt; t datetime&lt;span style="color:#f92672">)&lt;/span>;
CREATE TABLE
ms:babelfish@localhost&lt;span style="color:#f92672">=&lt;/span>&amp;gt; insert into &lt;span style="color:#f92672">[&lt;/span>sch1&lt;span style="color:#f92672">]&lt;/span>.test &lt;span style="color:#f92672">(&lt;/span>text, t&lt;span style="color:#f92672">)&lt;/span> values &lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#e6db74">&amp;#39;hi&amp;#39;&lt;/span>, getdate&lt;span style="color:#f92672">())&lt;/span>;
INSERT &lt;span style="color:#ae81ff">1&lt;/span>
ms:babelfish@localhost&lt;span style="color:#f92672">=&lt;/span>&amp;gt; &lt;span style="color:#66d9ef">select&lt;/span> * from &lt;span style="color:#f92672">[&lt;/span>sch1&lt;span style="color:#f92672">]&lt;/span>.test;
pk | text | t
----+------+-------------------------
&lt;span style="color:#ae81ff">1&lt;/span> | hi | 2021-11-14T23:26:05.45Z
&lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span> row&lt;span style="color:#f92672">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Above are shown commands using the T-SQL syntax, and a connection over the TDS protocol, with specific SQL Server data types and functions. But there’s no SQL Server, only Postgres! It would be interesting to see how this is seen by Postgres? Let’s give it a try!&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl -n notmssql exec -it bbf-0 -c postgres-util -- psql babelfish
psql &lt;span style="color:#f92672">(&lt;/span>13.4 OnGres Inc.&lt;span style="color:#f92672">)&lt;/span>
Type &lt;span style="color:#e6db74">&amp;#34;help&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">for&lt;/span> help.
babelfish&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#75715e"># \d master_sch1.test&lt;/span>
Table &lt;span style="color:#e6db74">&amp;#34;master_sch1.test&amp;#34;&lt;/span>
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------------------+----------+------------------------------
pk | integer | | not null | generated always as identity
text | sys.&lt;span style="color:#e6db74">&amp;#34;varchar&amp;#34;&lt;/span>&lt;span style="color:#f92672">(&lt;/span>50&lt;span style="color:#f92672">)&lt;/span> | bbf_unicode_cp1_ci_as | |
t | sys.datetime | | |
Indexes:
&lt;span style="color:#e6db74">&amp;#34;test_pkey&amp;#34;&lt;/span> PRIMARY KEY, btree &lt;span style="color:#f92672">(&lt;/span>pk&lt;span style="color:#f92672">)&lt;/span>
babelfish&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#75715e"># table master_sch1.test;&lt;/span>
pk | text | t
----+------+-------------------------
&lt;span style="color:#ae81ff">1&lt;/span> | hi | 2021-11-14 23:26:05.449
&lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span> row&lt;span style="color:#f92672">)&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>That was interesting! You can see the obvious differences between the different syntax and data types.&lt;/p>
&lt;p>Finally, let’s try to access Babelfish from a GUI tool. Firstly, let’s use port-forward to expose our pod’s port 1433 on our own laptop:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl --namespace notmssql port-forward bbf-0 1433:1433
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now you can use GUI tools to connect as if you had SQL Server on your laptop. Some may not work yet, as Babelfish progresses. Below is a screenshot of how I connected with &lt;a href="https://dbeaver.io/">DBeaver&lt;/a>:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/babelfish_from_dbeaver.png" alt="Connecting to Babelfish with DBeaver, using the SQL Server protocol">&lt;/p>
&lt;p>Just please note to use the default’s &lt;code>master&lt;/code> value for the Database/Schema. Querying the metadata table gave some errors, but general operation works well, and data is perfectly shown. &lt;strong>Enjoy running T-SQL on your Babelfish for PostgreSQL&lt;/strong>.&lt;/p>
&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>Please be aware that this is a beta version of the upcoming &lt;code>1.1.0&lt;/code> release, and as such it is not as polished as a GA release. Even on 1.1.0GA, Babelfish will not be declared &amp;ldquo;production ready&amp;rdquo;. Use it at your own risk.&lt;/p>
&lt;p>However, &lt;strong>it is quite interesting to start exploring Babelfish, given that StackGres makes it so simple to use&lt;/strong>. No need to go over the somehow involved compilation process that the current open source Babelfish release requires. &lt;strong>Just a few commands, and you get a fully working Babelfish version on Kubernetes&lt;/strong>.&lt;/p>
&lt;p>We’re eager to get feedback and ideas from you all. Please join our &lt;a href="https://slack.stackgres.io">Slack&lt;/a> and/or &lt;a href="https://discord.stackgres.io">Discord&lt;/a> channels and let you know what you think about Babelfish, StackGres, and chat about any other topic related to Postgres on Kubernetes, if you want.&lt;/p>
&lt;h2 id="appendix-if-you-dont-have-kubernetes-get-it-in-1-minute">Appendix: If you don’t have Kubernetes, get it in 1 minute&lt;/h2>
&lt;p>Not totally familiar with Kubernetes yet still want to easily try Babelfish? Keep reading, you just need one additional minute.&lt;/p>
&lt;p>Run on your laptop:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ curl -sfL https://get.k3s.io | sh -
&lt;/code>&lt;/pre>&lt;/div>&lt;p>This will get you running with &lt;a href="https://k3s.io/">K3s&lt;/a>, a lightweight, certified Kubernetes distribution by SUSE Rancher. K3s will get started as a service on your system (managed by systemd; you can later stop with &lt;code>sudo systemctl stop k3s&lt;/code> and/or uninstall with &lt;code>/usr/local/bin/k3s-uninstall.sh&lt;/code>). To get access to &lt;code>kubectl&lt;/code>, you can get it via the k3s binary:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ sudo k3s kubectl
$ alias kubectl&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;sudo k3s kubectl&amp;#34;&lt;/span> &lt;span style="color:#75715e"># optional&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>To check that the k3s cluster is running, you can run:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
To further debug and diagnose cluster problems, use &lt;span style="color:#e6db74">&amp;#39;kubectl cluster-info dump&amp;#39;&lt;/span>.
&lt;/code>&lt;/pre>&lt;/div>&lt;p>You are ready to go!&lt;/p></description></item><item><title>StackGres 1.0.0: Open Source Postgres-aaS with 120+ Extensions</title><link>https://stackgres.io/blog/stackgres-1-0-0-open-source-postgres-aas-with-120-extensions/</link><pubDate>Thu, 28 Oct 2021 20:57:02 +0200</pubDate><guid>https://stackgres.io/blog/stackgres-1-0-0-open-source-postgres-aas-with-120-extensions/</guid><description>&lt;h2 id="stackgres-100-open-source-postgres-aas-with-120-extensions">StackGres 1.0.0: Open Source Postgres-aaS with 120+ Extensions&lt;/h2>
&lt;h3 id="tldr">TL;DR&lt;/h3>
&lt;p>We&amp;rsquo;re announcing &lt;strong>StackGres 1.0.0 GA&lt;/strong>. StackGres is an Open Source Postgres-as-a-Service that runs on any Kubernetes
environment. StackGres, today, is &lt;strong>the Postgres platform with the most Postgres extensions available: 120 as of
today&lt;/strong>. Many more to come in the future.&lt;/p>
&lt;h3 id="why-kubernetes">Why Kubernetes?&lt;/h3>
&lt;p>At &lt;a href="https://ongres.com">OnGres&lt;/a> we have been providing Postgres Professional Services for years. We love IaC
(Infrastructure as Code). One of our realizations was that it was next to impossible to create a &amp;ldquo;single IaC package&amp;rdquo;
that would contain Postgres and its Stack of components, that would work on any environment. There are just so many
different compute, storage and networking components, with different APIs.&lt;/p>
&lt;p>So we asked ourselves: is there any &amp;ldquo;abstraction layer&amp;rdquo; for distributed infrastructure? &lt;strong>The answer was Kubernetes&lt;/strong>.
Kubernetes APIs allowed us to create a single deployable Postgres package, that contains Postgres itself and all its
necessary Stack, and run &amp;ndash;almost&amp;ndash; anywhere.&lt;/p>
&lt;h3 id="stackgres-a-feature-rich-postgres-platform">StackGres, a feature-rich Postgres Platform&lt;/h3>
&lt;p>StackGres contains the full Stack of Postgres components needed for production:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>High availability and automated failover, using &lt;a href="https://github.com/zalando/patroni">Patroni&lt;/a>. Managed DNS endpoints
for the primary (rw) and replicas (ro, load balanced) connections.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Built-in, enabled by default connection-pooling.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Configurable automated backups with retention policies.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Prometheus metrics exporter, with auto-binding. Customized Postgres metrics, Grafana dashboards and Postgres alerts.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Expertly tuned default configurations &amp;ndash;which you can optionally override.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3 id="stackgres-innovating-the-postgres-platform">StackGres: innovating the Postgres Platform&lt;/h3>
&lt;p>So far, the features mentioned may be &amp;ldquo;table stakes&amp;rdquo; as of today. We wanted to provide more. &lt;strong>StackGres has introduced
significant innovations&lt;/strong> &amp;ndash;while keeping the same
&lt;a href="https://twitter.com/kelseyhightower/status/1343617588262096896?lang=en">Postgres core boring&lt;/a>&amp;ndash; such as:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Using &lt;strong>Envoy to proxy all Postgres traffic&lt;/strong>. In collaboration with the Envoy Community,
&lt;a href="https://www.cncf.io/blog/2020/08/13/envoy-1-15-introduces-a-new-postgres-extension-with-monitoring-support/">we developed&lt;/a>
the &lt;a href="https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/postgres_proxy_filter">Postgres filter for Envoy&lt;/a>.
StackGres uses it to add additional monitoring (by inspecting the wire protocol) and to terminate SSL!&lt;/p>
&lt;/li>
&lt;li>
&lt;p>A &lt;strong>fully-featured Web Console&lt;/strong>. It supports everything StackGres can do. And yes, it has a dark mode ;)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://stackgres.io/img/blog/SG_blog-StackGres_1-0-0.jpg" alt="Insert benchmark comparison">&lt;/p>
&lt;ul>
&lt;li>
&lt;p>A system to push &lt;strong>all Postgres and Patroni logs from all pods to a central server&lt;/strong>. This central server is a separate,
StackGres-managed Postgres database with &lt;a href="https://www.timescale.com/">Timescale&lt;/a> to support large volume and high
velocity logging. &lt;strong>Query your logs with SQL or from the Web Console&lt;/strong>!&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Fully automated &lt;a href="https://stackgres.io/doc/latest/reference/crd/sgdbops/">&lt;strong>&amp;ldquo;Day 2&amp;rdquo; DBA operations&lt;/strong>&lt;/a>, including: &lt;strong>minor and
major version upgrades, controlled cluster restart, container version upgrades, vacuum, repack and even benchmarks!&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>A system to &lt;strong>dynamically load Postgres extensions&lt;/strong> into the containers. This allows us to ship lighter containers,
while supporting potentially hundreds of extensions &amp;ndash;&lt;a href="https://stackgres.io/extensions/">&lt;strong>120 as of now&lt;/strong>&lt;/a>, with many more
to come in the future.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3 id="easy-of-installation-and-use">Easy of installation and use&lt;/h3>
&lt;p>Production Postgres requires a fair amount of Postgres expertise. One of our goals is to &amp;ldquo;democratize production
Postgres&amp;rdquo;, and make it accessible to almost anyone. StackGres is designed to be easy to operate.&lt;/p>
&lt;p>Visit &lt;a href="https://stackgres.io/install/">StackGres Installation page&lt;/a> for a quick primer on how to install StackGres either
via &lt;code>kubectl&lt;/code> or &lt;code>Helm&lt;/code> (&lt;a href="https://artifacthub.io/packages/helm/stackgres-charts/stackgres-operator?modal=install">Helm Chart also published to
ArtifactHub&lt;/a>, please star it!).
There is more detailed information in the &lt;a href="https://stackgres.io/doc/latest/install/">Production Installation&lt;/a> section of
the documentation.&lt;/p>
&lt;p>For this post we will use Helm installation. Add the StackGres Helm repository:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">helm repo add stackgres-charts https://stackgres.io/downloads/stackgres-k8s/stackgres/helm/
&lt;/code>&lt;/pre>&lt;/div>&lt;p>And install with Helm into a dedicated namespace:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">helm install --namespace stackgres --create-namespace &lt;span style="color:#ae81ff">\
&lt;/span>&lt;span style="color:#ae81ff">&lt;/span> stackgres stackgres-charts/stackgres-operator
&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above command will normally take 0-2 minutes. Now let&amp;rsquo;s create our first cluster. If you prefer to do it all from
the Web Console, skip to the next section. Create a simple YAML file named &lt;code>demo.yaml&lt;/code>with the following content:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">stackgres.io/v1&lt;/span>
&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">SGCluster&lt;/span>
&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">sgdemo&lt;/span>
&lt;span style="color:#f92672">spec&lt;/span>:
&lt;span style="color:#f92672">postgres&lt;/span>:
&lt;span style="color:#f92672">version&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;latest&amp;#39;&lt;/span>
&lt;span style="color:#f92672">instances&lt;/span>: &lt;span style="color:#ae81ff">1&lt;/span>
&lt;span style="color:#f92672">pods&lt;/span>:
&lt;span style="color:#f92672">persistentVolume&lt;/span>:
&lt;span style="color:#f92672">size&lt;/span>: &lt;span style="color:#e6db74">&amp;#39;5Gi&amp;#39;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then &lt;code>kubectl apply&lt;/code> the file:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">kubectl apply -f demo.yaml
&lt;/code>&lt;/pre>&lt;/div>&lt;p>The easiest way to connect is to run &lt;code>psql&lt;/code> within the &lt;code>postgres-util&lt;/code> container, an administration container that is
always started with your StackGres pods:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">kubectl exec -it sgdemo-0 -c postgres-util -- psql
&lt;/code>&lt;/pre>&lt;/div>&lt;p>You may also connect from any other pod within the cluster. Note that the default username is &lt;code>postgres&lt;/code> and the
password is randomly generated and written in a secret named as the cluster, with the key &lt;code>superuser-password&lt;/code>.&lt;/p>
&lt;h3 id="adding-an-extension">Adding an extension!&lt;/h3>
&lt;p>StackGres supports as of today &lt;a href="https://stackgres.io/extensions/">more than 120 extensions&lt;/a>, with many more to come in
the future.&lt;/p>
&lt;p>As mentioned, StackGres &lt;strong>loads extensions dynamiycally&lt;/strong>. This means that save a few that are required for internal
operation, your cluster will contain by default no other extension. You can check by running the &lt;code>select * from pg_available_extensions&lt;/code> query from within &lt;code>psql&lt;/code>. This is good! Containers are lighter and are exposed to fewer
potential security problems.&lt;/p>
&lt;p>But now let&amp;rsquo;s say you want to use your favorite extension, for example &lt;code>citext&lt;/code>. This is a very useful extension to deal
with text in a case insensitive manner. To add this extension to the live container, you just need to edit the
&lt;code>.spec.postgres&lt;/code> section of the &lt;code>SGCluster&lt;/code> as in:&lt;/p>
&lt;pre class="language-yaml">
...
&lt;span class="pink">spec&lt;/span>:
&lt;span class="pink">postgres&lt;/span>:
&lt;span class="pink">version&lt;/span>: &lt;span class="yellow">'latest'&lt;/span>
&lt;b class="highlight">&lt;span class="pink">extensions&lt;/span>:
- &lt;span class="pink">name&lt;/span>: &lt;span class="yellow">'citext'&lt;/span>&lt;/b>
...
&lt;/pre>
&lt;p>(you can either edit the original YAML file and then do &lt;code>kubectl apply -f demo.yaml&lt;/code> or directly via &lt;code>kubectl edit sgcluster demo&lt;/code>)&lt;/p>
&lt;p>&lt;strong>In a few seconds, the extension will be available!&lt;/strong>. You may also do it from the Web Console by editing the
cluster and selecting the extension(s) that you want to lead from the Web Console. Now, to use the extension, you just
need to run in &lt;code>psql&lt;/code>, as with any Postgres extension:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sql" data-lang="sql">&lt;span style="color:#66d9ef">create&lt;/span> extension citext;
&lt;/code>&lt;/pre>&lt;/div>&lt;p>To release the resources, simply run &lt;code>kubectl delete -f demo.yaml&lt;/code>.&lt;/p>
&lt;h3 id="using-the-web-console">Using the Web Console&lt;/h3>
&lt;p>As mentioned, StackGres comes with a fully-featured Web Console. Let&amp;rsquo;s check it out. Let&amp;rsquo;s identify the pod name where
the Web Console is running and do a port-forward to expose it in our laptop:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">WEBC&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>kubectl --namespace stackgres get pods -l &lt;span style="color:#e6db74">&amp;#34;app=stackgres-restapi&amp;#34;&lt;/span> -o jsonpath&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;{.items[0].metadata.name}&amp;#34;&lt;/span>&lt;span style="color:#e6db74">`&lt;/span>
kubectl --namespace stackgres port-forward &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$WEBC&lt;span style="color:#e6db74">&amp;#34;&lt;/span> 8443:9443
&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>For production usage, it is recommended to use a &lt;code>LoadBalancer&lt;/code> as part of the installation Helm parameters or setup an
&lt;code>Ingress&lt;/code> controller. Check the &lt;a href="https://stackgres.io/doc/latest/install/helm/">Installation via Helm&lt;/a> section of
the documentation for more information.&lt;/p>
&lt;/blockquote>
&lt;p>Open in your web browser the address &lt;code>https://localhost:8443/&lt;/code>. You will see a warning (expected,
the certificate is self-signed, you may also bring your own with
&lt;a href="https://stackgres.io/doc/latest/install/cluster/parameters/#certificates-parameters">custom Helm parameters&lt;/a>). The
default username is &lt;code>admin&lt;/code>. The password is generated randomly and can be queried with the following command:&lt;/p>
&lt;div class="highlight">&lt;pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4">&lt;code class="language-sh" data-lang="sh">kubectl -n stackgres get secret stackgres-restapi --template &lt;span style="color:#e6db74">&amp;#39;{{ printf &amp;#34;%s\n&amp;#34; (.data.clearPassword | base64decode) }}&amp;#39;&lt;/span>
&lt;/code>&lt;/pre>&lt;/div>&lt;p>Select a namespace to work on (you may use &lt;code>default&lt;/code>, or create one with &lt;code>kubectl create namespace demo&lt;/code>). On the left
pane hover over &lt;code>StackGres Clusters&lt;/code> and click on the &lt;code>(+)&lt;/code> icon to create a new cluster. You may create a simple
cluster as in the following example:&lt;/p>
&lt;p>&lt;img src="https://stackgres.io/img/blog/stackgres-create_simple_cluster-web_console.png" alt="Web Console: create simple StackGres cluster">&lt;/p>
&lt;p>Once it is creating, you may click on the name to see the details about the cluster. Check the &lt;code>View Connection Info&lt;/code>
link to the top right of the cluster information to see quick commands on how to connect to your new cluster.&lt;/p>
&lt;h3 id="next-steps-tutorial">Next steps: tutorial&lt;/h3>
&lt;p>Want to go deeper? Check our &lt;a href="https://stackgres.io/doc/latest/tutorial/">tutorial&lt;/a>, which explores the main StackGres
features in a little bit more detail.&lt;/p>
&lt;p>Please drop us a note and let us know what you think in our &lt;a href="https://slack.stackgres.io">Slack&lt;/a> and/or
&lt;a href="https://discord.stackgres.io">Discord&lt;/a> channels. Also write us there if you find any bug or want to become a
collaborator.&lt;/p></description></item></channel></rss>