Skip to Content
ConfigurationLifecycle & Hooks

Lifecycle & Hooks

Nanokit provides a powerful engine to manage the lifecycle of your services, from the initial provisioning of dependencies to graceful teardown.

Understanding these hooks is essential for managing database migrations, complex build steps, and service discovery updates.


Provisioning Hook (provisioning.install)

The provisioning.install command is designed for one-time initialization of a service. It is specifically optimized for distributed environments where multiple replicas might share the same persistent storage.

How it works

  1. Host-Side Execution: The command runs on the host (or inside a temporary bootstrap container) before the service containers start.
  2. Atomic Locking: Nanokit uses a sentinel file located in the service’s primary volume to track installation status.
  3. Prevention of Race Conditions: If multiple replicas or environments share the same volume, Nanokit ensures only one process performs the installation.
services: api: runtime: node provisioning: # Executed only once if node_modules is missing or sentinel is absent # Can also be defined globally in the 'node' runtime install: "npm install --prefer-offline"

[!TIP] Use provisioning.install for heavy operations like npm install, composer install, or downloading large binary dependencies that should persist across container restarts.


Service Hooks (hooks)

Service hooks are executed relative to the container lifecycle. These are defined under the hooks key in your service configuration.

PhaseContextTypical Use Case
prestartHost/ProviderDatabase migrations (prisma migrate), config generation.
poststartHost/ProviderWarm-up scripts, registration in external service discovery.
prestopContainerGraceful session flushing, unregistering from load balancers.
poststopHost/ProviderCleanup of temporary files, logging teardown events.

Example: Database Migrations

The prestart hook is the recommended place for running database migrations. Nanokit ensures all required databases are up and healthy before triggering the hook.

services: web: runtime: node hooks: prestart: "npx prisma migrate deploy"

Example: Post-Startup Notification

You can use poststart to trigger external webhooks or internal logging once a service is live.

services: worker: runtime: node hooks: poststart: "curl -X POST https://status.internal/v1/event -d '{\"service\": \"worker\", \"status\": \"online\"}'"

Deployment Hooks

While service hooks manage the container lifecycle, deployment hooks manage the orchestration process itself.

deploy.prepare

The prepare command runs on your local machine (or CI runner) immediately after code is synchronized but before the reconciler starts on the remote host. It is ideal for local build steps that need to be synced.

deploy: target: root@my-vps prepare: "npm run build:css && rsync -avz ./dist ./remote:/opt/nanokit/dist"

Environment Variables in Hooks

All hooks have access to standard Nanokit environment variables, allowing you to create context-aware scripts:

  • NANOKIT_SERVICE: Name of the current service.
  • NANOKIT_ENV: Current environment (e.g., stage, prod).
  • NANOKIT_PROJECT: Name of the project.
  • LIFECYCLE_PHASE: The name of the hook being executed.

Best Practices

  1. Idempotency: Ensure hooks can be run multiple times without side effects (especially prestart).
  2. Timeouts: Hooks that run for too long can block deployments. Offload heavy async tasks to background workers if possible.
  3. Error Handling: Non-zero exit codes in prestart or provisioning.install will halt the deployment for that service.