In a previous series of posts, I described how I set up Node.js in a Docker container for development on my macBook. It’s quite a lot of steps!
Well, there is a much simpler way - introducing Appsody.
Setup
Here’s what I did to download Appsody from GitHub and create my first project test1
:
mkdir Appsody
cd Appsody
curl -GL -o appsody-homebrew-0.4.2.tar.gz "https://github.com/appsody/appsody/releases/download/0.4.2/appsody-homebrew-0.4.2.tar.gz"
tar -xvf appsody-homebrew-0.4.2.tar.gz
mkdir test1
cd test1
../appsody init nodejs-express
Not sure why but at the the time of writing, appsody-0.4.2-darwin-amd64.tar
did not include appsody-controller
, so I used the homebrew package instead.
In this example, I used the nodejs-express
template. To get a list of templates, run ../appsody list
. Choose your poison: Spring Boot, Python Flask, Swift, Vert.x, etc.
The output of the init
command is:
Running appsody init...
Downloading nodejs-express template project from https://github.com/appsody/stacks/releases/download/nodejs-express-v0.2.5/incubator.nodejs-express.templates.simple.tar.gz
Download complete. Extracting files from nodejs-express.tar.gz
Setting up the development environment
Running command: docker[pull appsody/nodejs-express:0.2]
Running command: docker[run --rm --entrypoint /bin/bash appsody/nodejs-express:0.2 -c find /project -type f -name .appsody-init.sh]
Successfully initialized Appsody project
You’ll also have to edit the Docker Preferences.. > File Sharing to add your working folder and the .appsody
hidden folder:
Debugging
Now, execute ../appsody debug
(or ../appsody run
if you don’t intend to attach Visual Studio Code as the debugger):
Running debug environment
Running command: docker[pull appsody/nodejs-express:0.2]
Running docker command: docker[run --rm -p 3000:3000 -p 9229:9229 --name t1-dev -v /Users/usr/Work/Appsody/t1/:/project/user-app -v t1-deps:/project/user-app/node_modules -v /Users/usr/.appsody/appsody-controller:/appsody/appsody-controller -t --entrypoint /appsody/appsody-controller appsody/nodejs-express:0.2 --mode=debug]
[Container] Running Install: npm install --prefix user-app && npm audit fix --prefix user-app
[Container] [..................] | rollbackFailedOptional: verb npm-session e295audited 295 packages in 1.677s
[Container] found 0 vulnerabilities
[Container]
[Container] [..................] | rollbackFailedOptional: timing audit body Comup to date in 0.919s
[Container] fixed 0 of 0 vulnerabilities in 295 scanned packages
[Container]
[Container]
[Container] ╭────────────────────────────────────────────────────────────────╮
[Container] │ │
[Container] │ New minor version of npm available! 6.9.0 -> 6.11.3 │
[Container] │ Changelog: https://github.com/npm/cli/releases/tag/v6.11.3 │
[Container] │ Run npm install -g npm to update! │
[Container] │ │
[Container] ╰────────────────────────────────────────────────────────────────╯
[Container]
[Container] Running: npm run debug
[Container]
[Container] > nodejs-express@0.2.5 debug /project
[Container] > node --inspect=0.0.0.0 server.js
[Container]
[Container] Debugger listening on ws://0.0.0.0:9229/54413382-182a-4b5f-b2d1-626b1f5340ae
[Container] For help, see: https://nodejs.org/en/docs/inspector
[Container] [Wed Sep 4 16:36:34 2019] com.ibm.diagnostics.healthcenter.loader INFO: Node Application Metrics 5.0.3.201908230949 (Agent Core 4.0.3)
[Container] [Wed Sep 4 16:36:34 2019] com.ibm.diagnostics.healthcenter.mqtt INFO: Connecting to broker localhost:1883
[Container] App started on PORT 3000
Now, you can check out these routes:
- The app itself, on
http://localhost:3000/
- The health check endpoint,
http://localhost:3000/health
, which returns{"status":"UP","checks":[]}
if all is good. - For Prometheus metrics,
http://localhost:3000/metrics
- And an Application Metrics dashboard during debugging
http://localhost:3000/health
Open Visual Studio Code and drag the entire test1
folder into it. Apsody already has created a hidden .vscode
folder and configured launch.json
for debugging! Just hit Debug > Start Debugging:
Add a breakpoint on app.js
, e.g. on the line res.send("Hello from Appsody!");
and open your browser to http://localhost:3000
- you’ll see the message Hello from Appsody!
const app = require('express')()
app.get('/', (req, res) => {
res.send("Hello from Appsody!");
});
module.exports.app = app;
Make a change to the file, e.g. res.send("Greets from Appsody!");
, save it, re-start debugging, refresh your browser... viola!
Other
BTW, to stop the container, hit Ctrl-C.
And to “connect” to a container and inspect its contents or run commands within:
docker exec -it test1-dev bash
Here’s a screenshot of the Application Metrics dashboard http://localhost:3000/health
including a flame graph during profiling:
Conclusion
Check out my previous post Setting up Node.js in a Docker container. I shared the individual docker
commands to pull an image, then inject files, run interactive commands in the container to do more setup, and commit the new image.
Then, run the container with arguments to mount a Host folder and expose ports for the output and debugging. Ultimately, you’ll notice the docker command that is called during appsody debug
is pretty similar to what I previously used:
docker run -it --rm -v $PWD:/code -p 8080:8080 -p 127.0.0.1:9229:9229 nodemondev bash -c "cd /code && nodemon --inspect=0.0.0.0:9229 hello.js"
And, finally, I previously described the manual steps to setup Visual Studio Code for debugging!
Appsody automates all that automagically and really makes my last post a colossal waste of effort. Life is that bit easier!
BTW Appsody is a piece of the Kabanero.io project, which according to this blog, “brings together open source projects Knative, Istio, and Tekton, with new open projects Codewind, Appsody, and Razee into an end-to-end solution for you to architect, build, deploy, and manage the lifecycle of Kubernetes-based applications.”