Pulsar can run as a single process on your laptop, and it’s surprisingly powerful for local development.

Here’s a Pulsar standalone setup running with a minimal configuration:

# Dockerfile for Pulsar Standalone
FROM apache/pulsar:latest

# Expose Pulsar ports
EXPOSE 6650
EXPOSE 8080

# Set environment variables for standalone mode
ENV PULSAR_STANDALONE_PORT=6650
ENV PULSAR_BROKER_PORT=8080

# Default command to start Pulsar in standalone mode
CMD ["bin/pulsar", "standalone"]

Now, let’s build and run this Docker image:

# Build the Docker image
docker build -t my-pulsar-standalone .

# Run the Docker container
docker run -d \
  --name pulsar-standalone \
  -p 6650:6650 \
  -p 8080:8080 \
  my-pulsar-standalone

This spins up a Pulsar instance where the broker and ZooKeeper are bundled into a single process. You can then interact with it using the Pulsar client libraries or the Pulsar command-line tools. For instance, to create a topic:

docker exec pulsar-standalone bin/pulsar-admin topics create persistent://public/default/my-topic

And to produce a message:

docker exec pulsar-standalone bin/pulsar-client produce persistent://public/default/my-topic \
  --messages "Hello Pulsar Standalone!"

Finally, to consume that message:

docker exec pulsar-standalone bin/pulsar-client consume persistent://public/default/my-topic \
  --num-messages 1 \
  -c

The core problem Pulsar standalone solves is providing a fully functional, albeit single-node, message queuing system without the operational overhead of managing multiple components like ZooKeeper, BookKeeper, and the Pulsar broker separately. This is invaluable for developers who need to test applications that interact with Pulsar without requiring a complex cluster setup. Internally, the pulsar standalone command is a wrapper that orchestrates the startup of ZooKeeper and BookKeeper embedded within the Pulsar process itself. It configures them to use local storage, effectively creating a self-contained environment. The PULSAR_STANDALONE_PORT and PULSAR_BROKER_PORT environment variables, while seemingly simple, are crucial for directing network traffic to the correct internal components when running in this bundled mode.

You control the behavior of this standalone instance primarily through command-line arguments to bin/pulsar standalone or by setting environment variables that override the defaults. For example, you can specify a different ZooKeeper port or configure the broker’s memory allocation. However, for most local development scenarios, the default settings are sufficient. The beauty of this setup is its simplicity; it abstracts away the complexities of distributed coordination and message persistence, allowing you to focus purely on your application’s messaging logic.

When running in standalone mode, Pulsar doesn’t offer any fault tolerance or horizontal scalability, which is by design. It uses the local filesystem for all its data, meaning any data will be lost when the container is removed. The CMD ["bin/pulsar", "standalone"] line in the Dockerfile is the magic that tells Docker to execute the Pulsar script with the standalone subcommand, which internally handles the bootstrapping of all necessary components. This makes it incredibly convenient for rapid iteration and testing of Pulsar-dependent applications.

The next step is understanding how to configure Pulsar for more advanced local testing, such as enabling authentication or persistent storage.

Want structured learning?

Take the full Pulsar course →