Set up your environment
This guide helps you prepare your environment to work with nullplatform. Once your setup is ready, you can move on to creating your custom scopes.
Before you start
Make sure you have the following tools installed:
- Docker
- Access to a Kubernetes cluster (or a distribution such as k3s or minikube).
Get started
-
Install the nullplatform CLI.
curl https://cli.nullplatform.com/install.sh | sh
-
Export your access token.
You can retrieve it using our Chrome extension.
export NP_TOKEN=your_access_token
-
Create an API key and assign the required roles.
- From the platform, navigate to Platform settings > API keys, and click + New API key.
- Select the account resource where the API key's roles will be assigned.
- Select the required roles:
agent
,developer
,ops
,secops
andsecrets-reader
. - Save your API key.
Note: If you prefer, you can create your API key using our CLI or API. See our docs for request examples and details.
-
Export the API key in a new terminal to avoid environment variable conflicts.
export NP_API_KEY=your_api_key_here
-
Export the
NP_ACTION_CONTEXT
as an environment variable.export NP_ACTION_CONTEXT=action_context_variable
JSON example of the environment variable
{
"notification": {
"action": "scope:create",
"id": "a1b2c3d4-e5f6-7a89-b012-3456789abcde",
"name": "create-scope",
"slug": "create-scope",
"status": "pending",
"created_at": "2025-01-14T20:13:12.761Z",
"updated_at": "2025-01-14T20:13:16.557Z",
"parameters": {
"scope_id": 1111
},
"results": {},
"type": "create",
"specification": {
"id": "9876fedc-ba09-4cde-8f01-23456789abcd",
"slug": "publish-message"
},
"service": {
"id": "0a1b2c3d-4e5f-6789-abcd-ef0123456789",
"slug": "pub-sub-service-1",
"attributes": {
"repository": "my-repository/pubsub-module"
},
"specification": {
"id": "123abc45-6789-def0-1234-56789abcdef0",
"slug": "publisher-subscriber"
},
"dimensions": {
"country": "ARG",
"environment": "development"
}
},
"link": null,
"tags": {
"organization_id": "1",
"organization": "my-organization",
"account_id": "2",
"account": "my-account",
"namespace_id": "3",
"namespace": "my-namespace",
"application_id": "4",
"application": "my-application"
},
"entity_nrn": "organization=1:account=2:namespace=3:application=4"
}
}
Set up the nullplatfrom agent
Install and run the nullplatform np-agent
, which connects your environment to the nullplatform backend to execute tasks.
Install it in your machine or in a Docker container.
-
Install the nullplatform agent.
curl https://cli.nullplatform.com/agent/install.sh
-
Or install the agent in a Docker container.
To use the agent in a containerized setup, create a Dockerfile using the configuration below:
FROM alpine
## Agent docker
RUN apk add --no-cache curl ca-certificates bash openssl aws-cli gettext gomplate jq yq
RUN curl https://cli.nullplatform.com/install.sh | sh
RUN curl https://cli.nullplatform.com/agent/install.sh | sh
RUN mkdir -p /root/.np
ADD run_agent.sh /app/run_agent.sh
ENV PATH=$PATH:/root/.local/bin
entrypoint ["/app/run_agent.sh"]Agent startup script
#!/bin/bash
# Variable to store the child process PID
NP_AGENT_PID=""
# Log function
log() {
echo "[$(date -Iseconds)] $1"
}
# Signal handling function
cleanup() {
local signal=$1
log "Received signal: $signal"
if [ -n "$NP_AGENT_PID" ] && kill -0 $NP_AGENT_PID 2>/dev/null; then
log "Sending SIGTERM to np-agent process $NP_AGENT_PID"
kill -15 $NP_AGENT_PID
# Wait for the child process to terminate with a timeout
log "Waiting for np-agent process to terminate..."
# Give the process time to clean up (similar to preStop hook time)
local timeout=25 # Less than the 30s termination grace period
local end_time=$(($(date +%s) + $timeout))
while kill -0 $NP_AGENT_PID 2>/dev/null && [ $(date +%s) -lt $end_time ]; do
log "Process $NP_AGENT_PID still running, waiting..."
sleep 1
done
if kill -0 $NP_AGENT_PID 2>/dev/null; then
log "Process $NP_AGENT_PID did not terminate gracefully within timeout"
log "Sending SIGKILL to process $NP_AGENT_PID"
kill -9 $NP_AGENT_PID
else
log "Process $NP_AGENT_PID terminated gracefully"
fi
else
log "No running np-agent process found"
fi
log "Cleanup complete, exiting with appropriate status"
# Exit with appropriate status
if [ "$signal" = "EXIT" ]; then
exit 0
else
# Exit with signal + 128 which is a common convention
exit $(( 128 + $(kill -l $signal) ))
fi
}
# Trap signals
trap 'cleanup TERM' TERM
trap 'cleanup INT' INT
trap 'cleanup HUP' HUP
trap 'cleanup QUIT' QUIT
trap 'cleanup USR1' USR1
trap 'cleanup USR2' USR2
trap 'cleanup EXIT' EXIT
# Start np-agent process
log "Starting np-agent process..."
/root/.local/bin/np-agent \
--apikey=$NP_API_KEY \
--runtime=host \
--tags=$TAGS \
--command-executor-env=NP_API_KEY="\"$NP_API_KEY\"" \
--command-executor-command-folders /root/.np/services \
--command-executor-debug \
--webserver-enabled &
# Store the PID of np-agent
NP_AGENT_PID=$!
log "np-agent process started with PID: $NP_AGENT_PID"
# Wait for the np-agent process to complete
# Using 'wait' allows the script to receive signals
wait $NP_AGENT_PID
EXIT_STATUS=$?
log "np-agent process exited with status: $EXIT_STATUS"
exit $EXIT_STATUS
What's next?
Now that your environment is ready, you're all set to move on and create your custom scope.