Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: handover #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16
8 changes: 7 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
"version": "0.0.1",
"description": "The goal of the reference architecture is to present",
"main": "index.js",
"engines": {
"node": "16.x"
},
"authors": {
"name": "Paul Baker",
"email": "paul.baker@modusbox.com"
"email": "paul.baker@infitx.com"
},
"contributors": [
"Miguel de Barros <[email protected]>"
],
"repository": "reference-architecture/reference-architecture",
"scripts": {
"dev": "vuepress dev src --no-cache",
Expand Down
15 changes: 14 additions & 1 deletion src/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,20 @@ module.exports = {
'/NodeJS/development/protecting-code',
'/NodeJS/development/secure-development-process',
'/NodeJS/development/testing',
'/NodeJS/development/typescript'
'/NodeJS/development/typescript',
{
title: "NodeJS Tools",
path: '/NodeJS/development/tools/',
children :[
{
title: "Devspace",
path: '/NodeJS/development/tools/',
children :[
'/NodeJS/development/tools/devspace',
'/NodeJS/development/tools/devspace_config',
'/NodeJS/development/tools/devspace_script'
]},
]}
]},
{
title: "Functional Components",
Expand Down
136 changes: 136 additions & 0 deletions src/NodeJS/development/tools/devspace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Example using Devspace for Central-Ledger

[Devspace](https://www.devspace.sh/) will allow you to run and debug code within a live Kubernetes environment.

The method shown below can be applied to any services with some minor tweaks/changes.

## References

1. original version of this document: https://gist.github.com/mdebarros/01ad36506ecc079753acd18d2dd4cabf
2. similar (possibly out-dated) gist that I shared in the past: https://gist.github.com/mdebarros/0b0818189a277679cc7a01049f81b0fa#file-devspace-md

## Install Devspace

Install [Devspace](https://www.devspace.sh/) --> https://www.devspace.sh/docs/getting-started/installation

## Setup

1. Copy [devspace.yaml](./devspace_config.md) to the root folder, making sure to edit the confg to match your environment
- IMAGE / REPLACE_IMAGE vars - make sure it matches the Alpine Nodejs Docker image version as in your `nvmrc` file with format as `node:{{NODE_VERSION}}-alpine` (e.g. `node:18.17.1-alpine`)
- LABEL_NAME var - make sure it matches the sub-prefix name of your desired deployment label for `app.kubernetes.io/name` (refer to /.devspace/deployment.yaml - see below for more info)
- LABEL_INSTANCE var - make sure it matches the name of your deployment label for `app.kubernetes.io/instance` (refer to /.devspace/deployment.yaml - see below for more info)
2. Copy [devspace_start.sh](./devspace_script.md) to the root folder
3. Create a `.devspace` folder
4. Dump desired Central-ledger `deployment.yaml` using the following example into the `.devspace` folder

```bash
kubectl -n moja2 get deployment moja2-centralledger-handler-transfer-fulfil -o yaml > ./.devspace/deployment.yaml
```

## Configure VS Code with the following debug targert

Save the following config in `.vscode/launch.json`

```json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Process @9229",
"type": "node",
"request": "attach",
"port": 9229,
"remoteRoot": "/opt/app/"
}
]
}
```

## Run Devspace

```bash
devspace dev
```

This will deploy a new deployment with the same name as the target deployment, except it will have a `devspace` suffix at the end. E.g. `moja2-centralledger-handler-transfer-fulfil-devspace`.

```bash
❯ kubectl -n moja2 get deployment | grep fulfil
moja2-centralledger-handler-transfer-fulfil 0/0 0 0 51m <-- NOTE: This has been scaled to 0.
moja2-centralledger-handler-transfer-fulfil-devspace 1/1 1 1 17h
```

If you want to revert, then

1. Exit the devspace process in your terminal,
2. Delete the `moja2-centralledger-handler-transfer-fulfil-devspace` deployment, and
3. Scale the `moja2-centralledger-handler-transfer-fulfil` deployment from `0` to `1`

### Running Service

Once the devspace service has fully started and synchronised the filesystem from your local to remote, it will

1. Execute the [devspace_start.sh](src/NodeJS/development/tools/assets/devspace_start.sh) file (which currently installs OS and NPM dependencies)
2. Print out some sample instructions/commands on how to start the Central-Ledger service as found in the [devspace_start.sh](src/NodeJS/development/tools/assets/devspace_start.sh)

You can also refer to the `deployment.yaml` for the container command:

```yaml
spec:
containers:
- command:
- node
- src/handlers/index.js
- handler
- --fulfil
```

You can execute it in your pod terminal like so:

```bash
node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil
```

> Note: `--inspect=0.0.0.0:9229` argument to start the service in debug mode (ensure that you have added the debug port to the `deployment.yaml`.

If you need to attach a debugger on startup, then use `--inspect-brk=0.0.0.0:9229` instead.

If youare missing some stdout statements, you can override the `CSL_LOG_TRANSPORT` (which is generally set to `file`) to `console` - This will ensure that all log statements are printed to your stdout.

```bash
CSL_LOG_TRANSPORT=console node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil
```

You can also override the `LOG_LEVEL`.

```bash
LOG_LEVEL=debug CSL_LOG_TRANSPORT=console node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil
```

## Debugging

Once the service has been started, execute the `Attach to Process @9229` process in VSCode, and you should see your Pod stdout show

```bash
Debugger attached.
```

Overally it should look something like this:

```bash
$ node --inspect=0.0.0.0:9229 src/handlers/index.js handler --fulfil
Debugger listening on ws://0.0.0.0:9229/97ecb806-186a-4448-99c9-5d9b417e2f8d <-- NOTE: Indicates that debugger has started
For help, see: https://nodejs.org/en/docs/inspector
(node:2151) [MONGODB DRIVER] Warning: promiseLibrary is a deprecated option
(Use `node --trace-warnings ...` to show where the warning was created)
http://moja3-cl-handler-bulk-transfer-fulfil-fc84f74fc-w6426-q2hn8:3001
method path description
------ -------- ---------------------------
GET /health
GET /metrics Prometheus metrics endpoint

Debugger attached. <-- NOTE: This indicates that your debugger has attached successfully!
```
167 changes: 167 additions & 0 deletions src/NodeJS/development/tools/devspace_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# File: devspace.yaml

```yaml
## INSTRUCTIONS:
## cmd: devspace dev
##

version: v1beta10

# `vars` specifies variables which may be used as ${VAR_NAME} in devspace.yaml
vars:
- name: IMAGE
value: node:18.17.1-alpine
- name: WORKDIR
value: /opt/app
- name: LABEL_NAME
# value: &LABEL_NAME centralledger-handler-admin-transfer
# value: &LABEL_NAME centralledger-handler-transfer-prepare
value: &LABEL_NAME centralledger-handler-transfer-fulfil
# value: &LABEL_NAME cl-handler-bulk-transfer-fulfil
# value: &LABEL_NAME cl-handler-bulk-transfer-prepare
# value: &LABEL_NAME centralledger-handler-transfer-position
# value: &LABEL_NAME centralledger-handler-timeout
- name: LABEL_INSTANCE
# value: moja1
value: moja2
# value: moja3
# value: dev3
- name: DEPLOYMENT_NAME
value: *LABEL_NAME
- name: CONTAINER_NAME
value: *LABEL_NAME
- name: REPLACE_IMAGE
value: node:18.17.1-alpine

# `deployments` tells DevSpace how to deploy this project
deployments:
- name: ${LABEL_INSTANCE}-${DEPLOYMENT_NAME}
# This deployment uses `kubectl` but you can also define `helm` deployments
kubectl:
manifests:
- .devspace/deployment.yaml

# `dev` only applies when you run `devspace dev`
dev:
# `dev.ports` specifies all ports that should be forwarded while `devspace dev` is running
# Port-forwarding lets you access your application via localhost on your local machine
ports:
- labelSelector:
app.kubernetes.io/name: ${LABEL_NAME}
app.kubernetes.io/instance: ${LABEL_INSTANCE}
# - imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}`
forward:
- port: 3001
- port: 9229
remotePort: 9229

# `dev.open` tells DevSpace to open certain URLs as soon as they return HTTP status 200
# Since we configured port-forwarding, we can use a localhost address here to access our application
# open:
# - url: http://localhost:3007

# `dev.sync` configures a file sync between our Pods in k8s and your local project files
sync:
- labelSelector:
app.kubernetes.io/name: ${LABEL_NAME}
app.kubernetes.io/instance: ${LABEL_INSTANCE}
# - imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}`
disableDownload: true
# waitInitialSync: false
# polling: false
containerPath: ${WORKDIR}
localSubPath: ./
excludePaths:
- .git/
- config/
- secrets/
- test/
# downloadExcludePaths:
# - config/
uploadExcludePaths:
- deploy/
# - config/
- coverage/
- node_modules/
- .dockerignore
- .editorconfig
- .istanbul.yml
- circle.yml
- docker-compose.circle.yml
- docker-compose.dev.yml
- docker-compose.functional.yml
- docker-compose.yml
- Dockerfile
- LICENSE
- sonar-project.properties

# `dev.terminal` tells DevSpace to open a terminal as a last step during `devspace dev`
terminal:
labelSelector:
app.kubernetes.io/name: ${LABEL_NAME}
app.kubernetes.io/instance: ${LABEL_INSTANCE}
# imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}`
# With this optional `command` we can tell DevSpace to run a script when opening the terminal
# This is often useful to display help info for new users or perform initial tasks (e.g. installing dependencies)
# DevSpace has generated an example ./devspace_start.sh file in your local project - Feel free to customize it!
workDir: ${WORKDIR}
command:
- sh
- devspace_start.sh

# Since our Helm charts and manifests deployments are often optimized for production,
# DevSpace let's you swap out Pods dynamically to get a better dev environment
replacePods:
- labelSelector:
app.kubernetes.io/name: ${LABEL_NAME}
app.kubernetes.io/instance: ${LABEL_INSTANCE}
containerName: ${CONTAINER_NAME}
# - imageSelector: ${IMAGE} # Select the Pod that runs our `${IMAGE}`
# Since the `${IMAGE}` used to start our main application pod may be distroless or not have any dev tooling, let's replace it with a dev-optimized image
# DevSpace provides a sample image here but you can use any image for your specific needs
# replaceImage: loftsh/javascript:latest
replaceImage: ${REPLACE_IMAGE}
# Besides replacing the container image, let's also apply some patches to the `spec` of our Pod
# We are overwriting `command` + `args` for the first container in our selected Pod, so it starts with `sleep 9999999`
# Using `sleep infinity` as PID 1 (instead of the regular ENTRYPOINT), allows you to start the application manually
patches:
# Lets replace the container command with `sleep infinity` so that the container does not start the application automatically
- op: replace
path: spec.containers[0].command
value:
- sleep
- op: replace
path: spec.containers[0].args
value:
- infinity
- op: add
path: spec.containers[0].ports
value:
containerPort: 9229
name: debug
protocol: TCP
# Remove securityContext
- op: remove
path: spec.containers[0].securityContext
# Remove Readiness and Liveness probes
- op: remove
path: spec.containers[0].readinessProbe
- op: remove
path: spec.containers[0].livenessProbe
- op: remove
path: spec.containers[1].readinessProbe
- op: remove
path: spec.containers[1].livenessProbe

# `profiles` lets you modify the config above for different environments (e.g. dev vs production)
profiles:
# This profile is called `production` and you can use it for example using: devspace deploy -p production
# We generally recommend to use the base config without any profiles as optimized for development (e.g. image build+push is disabled)
- name: production
# This profile adds our image to the config so that DevSpace will build, tag and push our image before the deployment
merge:
images:
app:
image: ${IMAGE} # Use the value of our `${IMAGE}` variable here (see vars above)
dockerfile: ./Dockerfile
```
Loading