Self-Host Speakeasy
Self-host vs Speakeasy Cloud: Self-hosting Speakeasy means managing the service yourself and take care of upgrades, scaling, security etc. If you are less technical or looking for a hands-off experience, we recommend Speakeasy Cloud.
Overview
Getting a production environment of Speakeasy up and running is probably one of the first things you want to do! This section goes through the different options available depending on where you'll be hosting Speakeasy, and includes guides on several of the most popular services.
Currently the self-hosting guides are manual deployment procedures. We plan on having a terraform module very soon to support deploying Speakeasy with IaC.
Prerequisites
- Helm 3.0
- kubectl
- A PostgreSQL database
- We strongly recommend a long-term installation of Speakeasy uses an externally managed database (eg. Google CloudSQL, AWS RDS). Tying the storage of your data to the lifecycle of persistent volumes may result in data-loss. For testing purposes however, this chart allows the user to enable Postgres on K8s.
Usage
Helm must be installed to use the charts. Please refer to Helm's documentation to get started.
Once Helm has been set up correctly, add the repo as follows:
helm repo add speakeasy https://speakeasy-api.github.io/helm-charts
If you had already added this repo earlier, run helm repo update
to retrieve
the latest versions of the packages. You can then run helm search repo
speakeasy
to see the charts.
For specific instructions regarding installation of speakeasy-k8s, please refer to the Installation section below.
Configuration
Configure the SDK
The SDK provides a way to redirect the requests it captures to a self-hosted deployment of the Speakeasy Platform. This is done through the use of environment variables listed below. These are to be set in the environment of your services that have integrated the SDK:
SPEAKEASY_SERVER_URL
- The url of the on-premise Speakeasy Platform's GRPC Endpoint. By default this isgrpc.prod.speakeasyapi.dev:443
.SPEAKEASY_SERVER_SECURE
- Whether or not to use TLS for the on-premise Speakeasy Platform. By default this istrue
set toSPEAKEASY_SERVER_SECURE="false"
if you are using an insecure connection.
Configure Infrastructure
Provide an overlay for the changes needed to values.yaml
by following the sections below.
Auth
Speakeasy uses Github OAuth to provide authentication for your org. Under settings for the Github Organization you'd like to
authenticate, click "Developer Settings" > "Oauth Apps" > "New Oauth App". Fill in the fields (example in screenshot below). Please ensure the "Authorization callback URL" has a value in the form of https://<DOMAIN>/v1/auth/callback/github
, where <DOMAIN>
is replaced by the domain name of the A record (added in the Ingress Section below).
You will also need to specify values for auth.SignInURL
, auth.GithubClientId
, auth.GithubClientSecret
, and auth.GithubCallbackURL
in your overlay to be equivalent to the above populated values. auth.SignInURL
should just be https://<DOMAIN>
(see example overlay).
Ingress
If provisioning ingress resources from our chart, set the value for registry.ingress.enabled
to true
.
Also, set the values for registry.ingress.apiHostnames
, registry.ingress.webHostnames
,
and registry.ingress.grpcHostnames
to your specified domain names for Speakeasy's registry API, web, and gRPC services.
Ambassador
If using Ambassador mappings, ensure registry.ingress.enabled
and cert-manager.enabled
are both false
.
See the Ambassador Installation section below for the steps required to use Ambassador for your Speakeasy
deployment.
Postgres
To enable Postgres on K8s (not recommended), set the value for postgresql.enabled
to true
. If using an externally
managed Postgres (recommended), set postgresql.enabled
to false
and the value for the POSTGRES_DSN
environment variable.
Bigquery
To enable Bigquery for request/response storage, set values for BIGQUERY_PROJECT
and BIGQUERY_DATASET
under the
registry.envVars
block. They should be equivalent to the GCP project ID and Bigquery dataset ID, respectively, under which bounded_requests
and unbounded_requests
tables must exist with the following schema:
bounded_requests
unbounded_requests
Currently, the Speakeasy application assumes these tables with the above schemas exist under the specified BIGQUERY_PROJECT
and BIGQUERY_DATASET
. If they do not exist execute the following steps:
- Follow the docs to install the
bq
command line tool: https://cloud.google.com/bigquery/docs/bq-command-line-tool#enter-bq-commands-shell - Run the following commands, replacing
<DATASET_ID>
with your dataset:
bq mk -t <DATASET_ID>.bounded_requests request_id:STRING,workspace_id:STRING,api_id:STRING,version_id:STRING,api_endpoint_id:STRING,api_endpoint_path:STRING,method:STRING,path:STRING,status:INTEGER,request_start_time:TIMESTAMP,response_finish_time:TIMESTAMP,created_at:TIMESTAMP,customer_id:STRING,latency:INTEGER
bq mk -t <DATASET_ID>.unbounded_requests request_id:STRING,workspace_id:STRING,har:STRING,har_size_bytes:INTEGER,created_at:TIMESTAMP
We will soon add support for automating the creation of these tables in your GCP project and dataset if they do not exist.
Enable HTTPS
If registry.ingress.enabled
is true
, set the value for cert-manager.enabled
to true
(and notificationEmail
to receive updates about cert expiry)
for LetsEncrypt to provide SSL certificates to enable HTTPS.
If following the Ambassador Installation, ensure cert-manager.enabled
is false
. Some manual steps will be required to ensure certificates can successfully provision
with Ambassador mappings.
Speakeasy Version
Set values for registry.image.tag
with the version of Speakeasy you'd like to install.
The following is a sample overlay file for a configuration requiring ingress to be spun up by this chart and connecting to an externally managed Postgres:
registry:
image:
tag: 1.0.0
envVars:
- name: POSTGRES_DSN
value: postgres://postgres:postgres@34.149.47.53:5432/postgres?sslmode=disable
ingress:
enabled: true
apiHostnames:
- api.selfhostspeakeasy.com
webHostnames:
- www.selfhostspeakeasy.com
- selfhostspeakeasy.com
grpcHostnames:
- grpc.selfhostspeakeasy.com
auth:
SignInURL: https://speakeasyplatform.com
GithubClientId: b0234253z345c
GithubClientSecret: *****************
GithubCallbackURL: https://speakeasyplatform.com/v1/auth/callback/github
postgresql:
enabled: false
cert-manager:
enabled: true
Installation
The process to install Speakeasy will differ depending on whether ingress, Ambassador, or neither are enabled.
Without Ingress
If not enabling ingress or Ambassador, execute the following command:
helm install speakeasy speakeasy/speakeasy-k8s -f <OVERLAY> -n <NAMESPACE> --debug
If postgresql.enabled
is true
, you will also need to edit the Speakeasy deployment to modify the IP in POSTGRES_DSN
with the external IP of the LoadBalancer
service. First, get the IP via:
kubectl get svc -n <NAMESPACE> postgres-postgresql -o "go-template={{range .status.loadBalancer.ingress}}{{or .ip .hostname}}{{end}}"
Then, modify the Speakeasy deployment via:
kubectl edit deploy -n <NAMESPACE> speakeasy-k8s-service
Swap out the 127.0.0.1
under the value
for POSTGRES_DSN
with the IP obtained from the previous command.
With Ingress
In your overlay, set postgresql.enabled
to false
, even if using Postgres on K8s.
If using K8s Postgres, follow necessary instructions to install the postgresql
helm chart.
The following is a sample command using an already existing PV and PVC:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install -n <NAMESPACE> postgres bitnami/postgresql --set persistence.existingClaim=postgres-pvc --set auth.postgresPassword=postgres \
--set volumePermissions.enabled=true --set primary.service.type=LoadBalancer
For K8s Postgres, get the external IP of the LoadBalancer
via:
kubectl get svc -n <NAMESPACE> postgres-postgresql -o "go-template={{range .status.loadBalancer.ingress}}{{or .ip .hostname}}{{end}}"
Otherwise, simply get the appropriate IP from your externally managed Postgres.
In your overlay, modify POSTGRES_DSN
value to use the IP obtained in the above instructions, and continue to follow the below instructions
for your ingress controller type.
ingress-nginx
If enabling cert-manager
, there are strict requirements regarding the ordering of resources. See
Resource Ordering Constraints for an explanation. As a result, please execute the following steps:
- First, install
ingress-nginx
:helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install -n <NAMESPACE> ingress ingress-nginx/ingress-nginx --set controller.config.use-forwarded-headers=true \
--set controller.config.use-http2=true --set fullnameOverride=speakeasy-ingress-nginx - Get the external IP of the
LoadBalancer
via:Then, create an A record on your DNS to point your desired domain for Speakeasy to this IP. For example domain names, refer to the sample overlay in the end of the Configuration section above.kubectl get svc speakeasy-ingress-nginx-controller -o "go-template={{range .status.loadBalancer.ingress}}{{or .ip .hostname}}{{end}}"
emissary-ingress
To use Ambassador's emissary-ingress
controller, please ensure the following values are set to false
:
registry.ingress.enabled
cert-manager.enabled
Execute the following steps:
First, add CRDs for
emissary-ingress
:helm repo add datawire https://app.getambassador.io
helm repo update
kubectl apply -f https://app.getambassador.io/yaml/emissary/3.1.0/emissary-crds.yamlInstall
emissary-ingress
:helm install -n <NAMESPACE> emissary-ingress datawire/emissary-ingress && kubectl wait --for condition=available --timeout=90s deploy \
-lapp.kubernetes.io/instance=emissary-ingressGet the external IP of the
LoadBalancer
via:kubectl get svc -n <NAMESPACE> emissary-ingress -o "go-template={{range .status.loadBalancer.ingress}}{{or .ip .hostname}}{{end}}"
Then, create an A record on your DNS to point your desired domain for Speakeasy to this IP. For example domain names, refer to the sample overlay in the end of the Configuration section above.
Install
cert-manager
with the following overlay:installCRDs: true
podDnsPolicy: None
podDnsConfig:
nameservers:
- 8.8.8.8
- 1.1.1.1
- 208.67.222.222Execute the following:
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install -n <NAMESPACE> cert-manager jetstack/cert-manager -f <OVERLAY>cert-manager
must issue an HTTP-01 challenge to verify domain ownership. We will need to apply CRDs from bothcert-manager
andemissary-ingress
to enable this. Replace the "$YOUR_EMAIL_HERE$" in./ambassador/cert-manager-ambassador-crds.yaml
to the email updates to manage the LetsEncrypt certificate (90 day expiration) will be sent.
Then, apply the file:kubectl apply -f <path/to/ambassador/cert-manager-ambassador-crds.yaml> --namespace=<NAMESPACE>
Now, we have to provision the certificate for our Speakeasy domain.
In
ambassador/ambassador-web-cert.yaml
, ensure the "$" wrapped value inspec.dnsNames
is replaced with the corresponding domain name for the A record you issued above.Then deploy the certificate:
kubectl apply -f speakeasy-k8s/ambassador/ambassador-web-cert.yaml --namespace <NAMESPACE>
You may monitor the status of the certificate by issuing the following command and watching the "READY" column:
kubectl get certificates -n <NAMESPACE> --watch
The certificate from the previous step should now be ready. In
./ambassador/ambassador-mappings-and-hosts.yaml
, replace all the "$" wrapped values forspec.hostname
, and ensure they're equivalent to the domain name for the A record you issued above.
Then, apply the file:kubectl apply -f <path/to/ambassador/ambassador-mappings-and-hosts.yaml> --namespace=<NAMESPACE>
Finally, execute the following install for speakeasy-k8s
:
helm install speakeasy speakeasy/speakeasy-k8s -f <OVERLAY> -n <NAMESPACE> --timeout 5m --wait --wait-for-jobs --debug \
--set fullnameOverride=speakeasy
After waiting a couple minutes, Speakeasy should now be running successfully in your environment. You should
now be able to access the HTTPS endpoint for your web or root web hostname.
To uninstall the charts:
helm delete speakeasy -n <NAMESPACE>
helm delete ingress -n <NAMESPACE> # if using ingress-nginx controller
helm delete postgres -n <NAMESPACE>
helm delete emissary-ingress -n <NAMESPACE> # if using emissary-ingress controller
Resource Ordering Constraints
cert-manager
installs CRDs to enable certificate provisioning via LetsEncrypt. One such CRD is the ClusterIssuer
which
must be installed last, otherwise the CRD will not be present in the K8s API server. However, the CertificateRequest
will
issue a status check to the ClusterIssuer
. When this status check fails, we found the CertificateRequest
status would hang
and prevent a successful installation. Since this status check proceeds directly upon installation of Speakeasy, we need to ensure
the POSTGRES_DSN
is pointing to an already existing Postgres service and A records are created for the ingress-nginx
controller
beforehand for a successful Speakeasy installation.