diff --git a/docs/deploy-webapps-via-registry.md b/docs/deploy-webapps-via-registry.md new file mode 100644 index 00000000..142dfc83 --- /dev/null +++ b/docs/deploy-webapps-via-registry.md @@ -0,0 +1,271 @@ +# Deploying WebApps from the Laconic Registry to Kubernetes + +First, ensure you have `laconicd` and the console running via [this tutorial](./laconicd-with-console.md). + +## Setup Kubernetes + +If merely requesting deployment, access to the Laconic registry is sufficient, but to *process* deployment requests, Kubernetes configuration is also necessary. The configuration format is the same as used by `kubectl`, and should be places in `/etc/config/kube.yml` + +## Setup the Deployer + +### Set envs + + +``` +$DEPLOYMENT_DNS_SUFFIX +$DEPLOYMENT_RECORD_NAMESPACE +$IMAGE_REGISTRY +$IMAGE_REGISTRY_CREDS +$IMAGE_REGISTRY_USER + +``` + + +``` +laconic-so --stack webapp-deployer-backend setup-repositories +laconic-so --stack webapp-deployer-backend build-containers +laconic-so --stack webapp-deployer-backend deploy up +``` + +## Setup Your Account + +Writing to the Laconic Registry, in order to create records for applications and deployment requests, requires a user key, and a bond with adequate funds available. + +### Install the registry CLI + +``` +npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/ +npm install -g @cerc-io/laconic-registry-cli +``` + +Alternatively, use the pre-configured container that was setup alongside `laconicd` + +### Get your private key + +``` +exec into laconicd +``` + +### config.yml + +``` +services: + cns: + restEndpoint: http://console.laconic.com:1317 + gqlEndpoint: http://console.laconic.com:9473/api + userKey: 3d4789e88508c6230d973ccea283032d3e3948775dbe02f4f0a80dc6c1f7c8d5 + # bondId: 3c61577f3c6197ced599e2fc21ccf76f43373004fd29c29f2e560c77f7c4bb6d + chainId: laconic_9000-1 + gas: 550000 + fees: 200000aphoton +``` + +### Create a bond + +``` +laconic cns -c config.yml bond create --type aphoton --quantity 1000000000 --gas 200000 --fees 200000aphoton +``` + + + + + +# Creating Deployments + +Deploying an application from the registry requires (and generates) +several records: + +1. An `ApplicationRecord` which describes the application itself, including its name, version, and repository. +2. An `ApplicationDeploymentRequest` which references an`ApplicationRecord`, and provides additional information such as the DNS name and configuration. +3. A `DnsRecord`, which contains the FQDN of the deployment. The ownership of this record will be checked against any future deployment or removal requests. +4. An `ApplicationDeploymentRecord` which records the successful processing of the deployment request. + +Additionally, since names need to be registered, namespace authorities need to be reserved, for example: + +``` +$ laconic -c $LACONIC_CONFIG cns authority reserve my-org-name + +$ laconic -c $LACONIC_CONFIG cns authority bond set my-org-name 0e9176d854bc3c20528b6361aab632f0b252a0f69717bf035fa68d1ef7647ba7 +``` + +## Application Records + +The `ApplicationRecord` should, at a minimum, specify the name of the application (`name`), its version (`app_version`), type (`app_type`), one or more repository URLs (`repository`), and the repository reference (eg, branch, tag, hash, etc.) to use (`repository_ref`). + +``` +$ cat app.yml +record: + type: ApplicationRecord + version: 0.0.4 + name: "@my-org-name/my-test-webapp" + repository: + - "https://github.com/my-org-name/my-test-webapp" + repository_ref: "v0.1.5" + app_version: "0.1.5" + app_type: "webapp" + +$ laconic -c $LACONIC_CONFIG cns record publish -f app.yml +bafyreihwvu6ynmk4nfrxg2vdcx2ep3tqry775ksqyehjitj2i4kphhyuky +``` + +One or more names should be registered for the application, which deployment requests can reference. + +``` +$ laconic -c $LACONIC_CONFIG cns name set "crn://my-org-name/applications/my-test-webapp" bafyreihwvu6ynmk4nfrxg2vdcx2ep3tqry775ksqyehjitj2i4kphhyuky + +$ laconic -c $LACONIC_CONFIG cns name set "crn://my-org-name/applications/my-test-webapp@0.1.5" bafyreihwvu6ynmk4nfrxg2vdcx2ep3tqry775ksqyehjitj2i4kphhyuky + +$ laconic -c $LACONIC_CONFIG cns record get --id bafyreihwvu6ynmk4nfrxg2vdcx2ep3tqry775ksqyehjitj2i4kphhyuky +[ + { + "id": "bafyreihwvu6ynmk4nfrxg2vdcx2ep3tqry775ksqyehjitj2i4kphhyuky", + "names": [ + "crn://my-org-name/applications/my-test-webapp", + "crn://my-org-name/applications/my-test-webapp@0.1.5", + ], + "owners": [ + "2671D38525BDC91A5DF4794EF2059D5771133702" + ], + "bondId": "0e9176d854bc3c20528b6361aab632f0b252a0f69717bf035fa68d1ef7647ba7", + "createTime": "2024-01-12T20:30:33Z", + "expiryTime": "2025-01-11T20:30:33Z", + "attributes": { + "app_type": "webapp", + "app_version": "0.1.5", + "name": "@my-org-name/my-test-webapp", + "repository": [ + "https://github.com/my-org-name/my-test-webapp" + ], + "repository_ref": "v0.1.5", + "type": "ApplicationRecord", + "version": "0.0.4" + } + } +] +``` + +## Application Deployment Requests + +To create the deployment of specific application, and `ApplicationDeploymentRequest` must be published. This request must reference the application to be deployed (`application`) and may optionally provide configuration (`config`) and a DNS name (`dns`). If no DNS name is supplied, one will be generated. A supplied DNS is usually just the short hostname, not the FQDN, since the suffix is supplied by the deployer. + +``` +$ cat req.yml +record: + type: ApplicationDeploymentRequest + version: 1.0.0 + name: "my-org-name/my-test-webapp@0.1.5" + application: "crn://my-org-name/applications/my-test-webapp@0.1.5" + dns: "my-test-app" + config: + env: + CERC_WEBAPP_DEBUG: my_debug_value_here + +$ laconic -c $LACONIC_CONFIG cns record publish -f req.yml +bafyreihtpvwjka5ecjmca46y4dip5gb2h25vvmc7t27d7g4zecngjssvky +``` + +It is not necessary to assign a name to the request. + +## Building and Deploying + +Building and deploying will happen automatically for records published the production registry, but in other environments it can be triggered manually. + +Laconic `stack-orchestrator` is used build and launch the application. It will clone the repository, build the application, upload the container to a registry, and launch the instance in Kubernetes, with +automatic DNS and TLS provisioning. + +``` +$ laconic-so deploy-webapp-from-registry \ + --kube-config $KUBE_CONFIG \ + --image-registry registry.mydeployer.org/app-registry \ + --deployment-parent-dir /opt/deployments \ + --laconic-config $LACONIC_CONFIG \ + --dns-suffix mydeployer.servesthe.world \ + --record-namespace-dns crn://my-deployer-org/dns \ + --record-namespace-deployments crn://my-deployer-org/deployments \ + --request-id bafyreihtpvwjka5ecjmca46y4dip5gb2h25vvmc7t27d7g4zecngjssvky +``` + +When deployment is complete, an `ApplicationDeploymentRecord` will be created: + +``` +$ laconic -c $LACONIC_CONFIG cns name resolve crn://my-deployer-org/deployments/my-test-app.mydeployer.servesthe.world +[ + { + "id": "bafyreiemfmxsue4svzys6tcwsqmhfjeyoo3gp63n7kydi2izbrwuzd4rga", + "names": [ + "crn://my-deployer-org/deployments/my-test-app.laconic.servesthe.world" + ], + "owners": [ + "2671D38525BDC91A5DF4794EF2059D5771133702" + ], + "bondId": "0e9176d854bc3c20528b6361aab632f0b252a0f69717bf035fa68d1ef7647ba7", + "createTime": "2024-01-11T20:45:29Z", + "expiryTime": "2025-01-10T20:45:29Z", + "attributes": { + "application": "bafyreibs6y7jhgjlsoxyqlugvkweanp3bi7ippfmhehk2rslcpoaqic2xi", + "dns": "bafyreicpac7tar5ua5e42zo7d5zwyp5yv7iord23p3gdox7zdfslrarjle", + "meta": { + "config": "da39a3ee5e6b4b0d3255bfef95601890afd80709", + "so": "82a5f9a3e4924cbb92e28be68759a487" + }, + "name": "@cerc-io/my-test-webapp", + "request": "bafyreiex7vmtruiiasra4wvqe7wirl6iuwiso6p3cvb3sjhq55e74zh4ke", + "type": "ApplicationDeploymentRecord", + "url": "https://my-test-app.mydeployer.servesthe.world", + "version": "0.0.1" + } + } +] +``` + +## Checking Status + +The status of the deployment may be checked with `stack-orchestrator`. + +``` +$ laconic-so deployment --dir /opt/deployments/my-test-app.snowball.servesthe.world status +Ingress: + Hostname: my-test-app.mydeployer.servesthe.world + IP: 204.130.133.199 + TLS: notBefore: 2024-01-12T23:11:09Z, notAfter: 2024-04-11T23:11:08Z + +Pods: + default/laconic-9560ffc64512e453-deployment-fb58d756f-l77pm: Running (2024-01-13 00:10:42+00:00) +``` + +# Removing Deployments + +As with deployment, removal involves publishing a request, which is then fulfilled by deployment processor. + +## Application Deployment Removal Requests + +``` +$ cat apprm.yml +record: + type: ApplicationDeploymentRemovalRequest + version: 1.0.0 + deployment: bafyreiemfmxsue4svzys6tcwsqmhfjeyoo3gp63n7kydi2izbrwuzd4rga + +$ laconic -c $LACONIC_CONFIG cns record publish -f apprm.yml +bafyreiejnqhsn5ibc3c6pzlsc26co3mt63djdeuntt3gmfuckcntdmisge +``` + +## Removal + +As with deployment, for records publish to the production service removal should be processed automatically. In other environments, removal can be processed with `stack-orchestrator`. + +``` +$ laconic-so undeploy-webapp-from-registry \ + --deployment-parent-dir /opt/deployments \ + --laconic-config ~/.laconic/local.yml \ + --request-id bafyreiejnqhsn5ibc3c6pzlsc26co3mt63djdeuntt3gmfuckcntdmisge + +Request bafyreiejnqhsn5ibc3c6pzlsc26co3mt63djdeuntt3gmfuckcntdmisge needs to processed. +Found 1 unsatisfied request(s) to process. +Matched deployment ownership: 2671D38525BDC91A5DF4794EF2059D5771133702 +record: + type: ApplicationDeploymentRemovalRecord + deployment: bafyreiemfmxsue4svzys6tcwsqmhfjeyoo3gp63n7kydi2izbrwuzd4rga + request: bafyreiejnqhsn5ibc3c6pzlsc26co3mt63djdeuntt3gmfuckcntdmisge + version: 1.0.0 +```