paicku
v0.3.1
Published
A CLI for containerizing applications with buildpacks
Readme
Paicku
Paicku is a Node.js library and command-line application for containerizing applications with buildpacks. It is a wrapper around Cloud Native Buildpacks' pack CLI.
Why?
- Zero setup. Automatically downloads the official
packbinary on the first run. - Zero configuration. Automatically detects your running container daemon (Docker or Podman) based on the OS and configures it.
- End-to-End Testing. Allows you to build and run containers with Node.js, to write robust integration tests.
- TypeScript Ready. First-class TypeScript support with native type definitions included out of the box.
- Choose runtime. Allows you to specify which container runtime would like to use, just by specifying the corresponding argument.
Installation
You can install Paicku globally through npm, yarn, or pnpm. Alternatively, drop the global flag (global/-g) to use it in your Node.js project.
# npm
npm install -g paicku
# yarn
yarn global add paicku
# pnpm
pnpm add -g paickuUsage
We officially support two interfaces for Paicku:
- Command-line application
- Node.js library - For general use in Node.js.
Command-line Usage
Containerizing an application
paicku build --path ./appNode.js library
To use Paicku, ensure you've installed the dependency, then import the createPaicku function.
Here's a minimal example
import {createPaicku} from 'paicku'
const paicku = createPaicku()
console.log('Containerizing app...')
const image = await paicku.build({path: './app'})
console.log('Starting container')
const container = await image.run({exposedPorts: 8080})
const response = await fetch(container.getUrl())
console.log('Response status:', response.status)
console.log('Stopping and removing container...')
await container.stop()Note: See paicku examples for complete scripts.
Command Topics
paicku build- Build an imagepaicku builder- Display suggested builders for the given applicationpaicku help- Display help for paicku.paicku inspect- Show information about a built app imagepaicku sbom- Interact with SBoM
Node.js and CLI Examples
Writing tests with Mocha and Chai
import {expect} from 'chai'
import {after, before, describe, it} from 'mocha'
import {createPaicku} from 'paicku'
const appPath = './app'
const appPort = 8080
describe('Mocha, Chai and Paicku', function () {
this.timeout(600_000) // Give some time for the build to complete
const paicku = createPaicku()
let containerImage
let container
before(async () => {
containerImage = await paicku.build({
builder: 'docker.io/paketobuildpacks/builder-ubi8-base',
path: appPath,
})
})
after(async () => {
if (container) {
await container.stop()
}
})
it('should successfully build and run an app', async () => {
container = await containerImage.run({exposedPorts: appPort})
const response = await fetch(container.getUrl())
expect(response.status).to.equal(200)
})
})Important: Always pass exposedPorts when you need a URL, as there is no default port mapping.
Configuring default behaviour of paicku
You can optionally define a custom working directory or provide a local path to the pack executable if you prefer not to download the default one.
const paicku = createPaicku({
cwd: process.cwd(), // Optional: working directory for Paicku
executablePath: '/path/to/pack', // Optional: skips automatic download
})Selecting container runtime
You can choose which container runtime you prefer [podman or docker]:
CLI:
paicku build my-app --container-runtime dockerNode.js:
const paicku = createPaicku()
const result = await paicku.build({
imageName: 'my-app',
path: './app',
'container-runtime': 'docker',
})Build with a specific builder and environment variables
CLI:
paicku build nodejs-noble-container-image \
--builder docker.io/paketobuildpacks/ubuntu-noble-builder \
--run-image docker.io/paketobuildpacks/ubuntu-noble-run-tiny \
--env BP_LAUNCH_WITH_TINI=trueNode.js:
const paicku = createPaicku()
const result = await paicku.build({
imageName: 'nodejs-noble-container-image',
builder: 'docker.io/paketobuildpacks/ubuntu-noble-builder',
'run-image': 'docker.io/paketobuildpacks/ubuntu-noble-run-tiny',
env: ['BP_LAUNCH_WITH_TINI=true'],
path: './app',
})Note: The builder must include a registry prefix (docker.io/, ghcr.io/, …).
Build from a remote Git repository
Append :<subdirectory> to the Git URL when the app is not at the repository root.
CLI:
paicku build backend-image --path https://github.com/nodeshift/mern-workshop:backendNode.js:
const paicku = createPaicku()
const result = await paicku.build({
imageName: 'backend-image',
path: 'https://github.com/nodeshift/mern-workshop:backend',
})Inspect a container image
Inspect your application by using the inspect command
CLI:
paicku inspect my-containerized-app:latest --output jsonNode.js:
const paicku = createPaicku()
const result = await paicku.inspect('my-containerized-app:latest', {
output: 'json',
})
console.log(result.parsedStdout)Suggest a builder
CLI:
paicku builder suggestNode.js:
const paicku = createPaicku()
const result = await paicku.builder.suggest()
console.log(result.stdout)Download the SBOM
CLI:
paicku sbom download my-containerized-app:latest --output-dir ./sbomNode.js:
const paicku = createPaicku()
await paicku.sbom.download('my-containerized-app:latest', {
'output-dir': './sbom',
})Contributing
Contributions are welcome, feel free to open an issue or a pull request.
Development
npm installRun the CLI against source:
./bin/dev.js build test/integration/testdata/nodejs_simple_app --container-runtime podmanProduction mode needs a build first:
npm run build
./bin/run.jsRebuild after changing source.
Testing
npm run testIntegration tests (require Docker or Podman):
npm run integration:test:podman
npm run integration:test:dockerDebug unit tests (--timeout 0, useful with .only):
npm run unit:test:debugCoverage:
npm run test:report