Following up on my previous post about deploying Appwrite with K3s, I will now guide you through configuring K3s to support Appwrite Functions.
Prepartion
Install Ngrok
Since I am running Appwrite in my HomeLab, I need to utilize ngrok to enable external network access (such as GitHub) to our internal network. After signing up, install ngrok via Chocolatey:
choco install ngrok
ngrok config add-authtoken xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ngrok http http://appwrite.local/
Take note of the host; in my case, it is d7e9-42-60-49-2.ngrok-free.app.
Register GitHub App
After logging in to your GitHub account, navigate to your avatar on the top right, and select Settings. Then, click on Developer settings and select New GitHub App at the top right corner.
Following the Appwrite Functions Docs, fill in the details sequentially.
First, enter the GitHub App name (e.g. sh-hello-world) and homepage URL (e.g. https://seehiong.github.io/).
For the callback URL, click Add Callback URL and enter the following two URLs:
https://d7e9-42-60-49-2.ngrok-free.app/v1/vcs/github/callback
https://d7e9-42-60-49-2.ngrok-free.app/v1/account/sessions/oauth2/callback/github/console
Enable the checkbox for requesting user authorization (OAuth) during installation, and also for redirect on update.
In the Webhook section, provide the Webhook URL and its secret (e.g. webhook-secret):
https://d7e9-42-60-49-2.ngrok-free.app/v1/vcs/github/events
Follow the settings outlined in the official documentation for Repository permissions, Account permissions, and Subscribe to events sections.
Under Where can this GitHub App be installed?, select the Any account option to allow for multiple Appwrite projects.
Finally, click on the generate a private key link and then the Generate a private key button, followed by generating a new client secret.
Appwrite Setup
After opening the private key file (e.g. sh-hello-world.xxx.pem), add a “\n” to the end of each line and remove the “carriage return” so that it becomes a single-line string:
"-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA5f58x/UROPmLo60dSmTqE3hDO4THacvj0nUy9gnGJ5tf6vS4\n[...]-----END RSA PRIVATE KEY-----"
Appwrite-deployment.yaml
Update the relevant values:
- name: _APP_VCS_GITHUB_APP_NAME
value: sh-hello-world
- name: _APP_VCS_GITHUB_PRIVATE_KEY
value: "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA5f58x/UROPmLo60dSmTqE3hDO4THacvj0nUy9gnGJ5tf6vS4\n[...]-----END RSA PRIVATE KEY-----"
- name: _APP_VCS_GITHUB_APP_ID
value: "850000"
- name: _APP_VCS_GITHUB_WEBHOOK_SECRET
value: webhook-secret
- name: _APP_VCS_GITHUB_CLIENT_SECRET
value: "aeb0000000000000000000000000000000000000"
- name: _APP_VCS_GITHUB_CLIENT_ID
value: "Iv1.0000000000000000"
Also, update the ngrok-related values:
- name: _APP_DOMAIN
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_TARGET
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_FUNCTIONS
value: d7e9-42-60-49-2.ngrok-free.app
As we migrated to using K3s, modify the _APP_EXECUTOR_HOST as follows:
- name: _APP_EXECUTOR_HOST
value: http://openruntimes-executor-svc.appwrite.svc/v1
Appwrite-worker-builds-deployment.yaml
To support functions, update these values:
- name: _APP_EXECUTOR_HOST
value: http://openruntimes-executor-svc.appwrite.svc/v1
- name: _APP_VCS_GITHUB_APP_NAME
value: sh-hello-world
- name: _APP_VCS_GITHUB_PRIVATE_KEY
value: "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA5f58x/UROPmLo60dSmTqE3hDO4THacvj0nUy9gnGJ5tf6vS4\n[...]-----END RSA PRIVATE KEY-----"
- name: _APP_VCS_GITHUB_APP_ID
value: "850000"
- name: _APP_DOMAIN
value: d7e9-42-60-49-2.ngrok-free.app
Appwrite-worker-certificates-deployment.yaml
Update the ngrok-related values:
- name: _APP_DOMAIN
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_TARGET
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_FUNCTIONS
value: d7e9-42-60-49-2.ngrok-free.app
Appwrite-worker-functions-deployment.yaml
To support functions, update these values:
- name: _APP_EXECUTOR_HOST
value: http://openruntimes-executor-svc.appwrite.svc/v1
Appwrite-worker-migrations-deployment.yaml
Update the ngrok-related values:
- name: _APP_DOMAIN
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_TARGET
value: d7e9-42-60-49-2.ngrok-free.app
Appwrite-maintenance-deployment.yaml
Update the ngrok-related values:
- name: _APP_DOMAIN
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_TARGET
value: d7e9-42-60-49-2.ngrok-free.app
- name: _APP_DOMAIN_FUNCTIONS
value: d7e9-42-60-49-2.ngrok-free.app
Openruntimes-executor-deployment.yaml
To allow executors to have access to Docker, set the pod to run as root (not advisable in production environments):
spec:
securityContext:
runAsUser: 0
containers:
- env:
- name: OPR_EXECUTOR_NETWORK
value:
...
Alternatively, identify the node that runs the pod, and issue the command to create the runtimes network:
docker network create runtimes
docker network ls
Appwrite-realtime-svc.yaml
For proper Traefik routing, update the appwrite-realtime-svc.yaml file as follows:
apiVersion: v1
kind: Service
metadata:
name: appwrite-realtime-svc
namespace: appwrite
spec:
selector:
io.kompose.service: appwrite-realtime
ports:
- name: appwrite-realtime
protocol: TCP
port: 80
targetPort: 80
Appwrite-ing.yaml
To support Traefik routing, modify as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: appwrite-ingress
namespace: appwrite
spec:
defaultBackend:
service:
name: appwrite-svc
port:
number: 80
rules:
- host: "d7e9-42-60-49-2.ngrok-free.app"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: appwrite-svc
port:
number: 80
- pathType: Prefix
path: "/v1/realtime"
backend:
service:
name: appwrite-realtime-svc
port:
number: 80
Install GitHub App
Once all K8s files are redeployed, proceed with the setup. Click on Install & Authorize button from GitHub.
Upon successful installation, you should see the GitHub repository under Git configuration in Appwrite.
Create Appwrite Function
Next, proceed to create a function.
Start with the Node.js template:
Upon completion, click on generate API key:
Create a new repo in GitHub:
Enter the new repo name and set it as private:
Appwrite Function Deployments
With the function codes generated in GitHub, navigate from Appwrite to Functions and the newly created Starter function Node. You should see that the deployment is active as shown:
For reference, here are some screenshots of my K3s Appwrite HomeLab:
That concludes the setup, and your functions should now be deployed successfully!
Troubleshooting
Function execution failed
The function failed to be executed, with the openruntimes-executor pod logging these errors:
[Error] Type: Exception
[Error] Message: An internal curl error has occurred within the executor! Error Msg: Could not resolve host: 66069922a8ab3
[Error] File: /usr/local/app/http.php
[Error] Line: 1027
Warning: Swoole\Table::set(): key[executor-755b4586d7-5bmp8-660002098ba892717675-6600395e2b19005c2ddd] is too long in /usr/local/app/http.php on line 1283
Wanted to run ngrok with custom subdomain, but this is only a feature off the paid plans:
ERROR: failed to start tunnel: Custom subdomains are a feature on ngrok's paid plans.
ERROR: Failed to bind the custom subdomain 'ngrok-free.app' for the account 'xxxxxx'.