Run a service locally
Running a service locally is helpful to test and debug. The following sections provide commands for starting and stopping a single service locally.
Prerequisites
In order to run your service locally, you’ll need to have the following prerequisites:
-
Docker 20.10.14 or higher
-
Access to the
gcr.io/kalix-public
container registry
The samples provided with the Kalix SDKs all have |
Starting your service
To start the proxy, run the following command from the directory containing the docker-compose.yml
file:
-
Start the proxy
docker compose up
-
Start the service
npm start
By default this command will start your containers in foreground mode. This means the terminal window will show all output from all containers. To start in "detached" mode, add the |
Invoking your service
After you start the service it will accept invocations on localhost:9000
. You can use cURL to invoke your service. For services developed using a protocol-first SDK, you can also use gRPCurl.
Using cURL
- Linux or macOS
-
curl \ -XPOST \ (1) -H "Content-Type: application/json" \ (2) -d '{"counterId": "foo"}' \ (3) localhost:9000/com.example.CounterService/GetCurrentCounter (4)
- Windows 10+
-
curl ^ -XPOST ^ (1) -H "Content-Type: application/json" ^ (2) -d '{"counterId": "foo"}' ^ (3) localhost:9000/com.example.CounterService/GetCurrentCounter (4)
1 | The XPOST flag indicates cURL will send a POST request |
2 | The content type for this request is set to application/json |
3 | The message payload in JSON format |
4 | The URL with the RPC procedure name which is deduced from the protobuf definition of the component you’re calling. |
Using gRPCurl
For protocol-first SDKs, inspect your services with the gRPC list
and describe
commands:
grpcurl -plaintext localhost:9000 list
grpcurl -plaintext localhost:9000 describe com.example.CounterService
Be sure to use gRPCurl |
Get a current value from the CounterService
:
- Linux or macOS
-
grpcurl \ -d '{"counterId": "foo"}' \ (1) -plaintext localhost:9000 \ (2) com.example.CounterService/GetCurrentCounter (3)
- Windows 10+
-
grpcurl ^ -d '{"counterId": "foo"}' ^ (1) -plaintext localhost:9000 ^ (2) com.example.CounterService/GetCurrentCounter (3)
1 | The message payload in JSON format with -d |
2 | The address of the proxy (using plaintext instead of TLS) |
3 | The RPC procedure name which is deduced from the protobuf definition of the component you’re calling. |
Shut down the proxy
To shut down the proxy, which removes all data kept in memory, run the command below:
docker stop kalix-proxy
To delete the proxy container, run
docker rm kalix-proxy
Running multiple services
You can run multiple services locally at the same time. To do that:
-
Each service will need the user function to run on its own port.
-
Each service will need its own proxy container and each proxy container will need its own port.
See below how to do such configuration.
Run user function on a custom port
When using the defaults, the Kalix proxy connects to the user function on port 8080. However, if you’re looking to have 2 services running at the same time, the second service will need to be run at a different port (e.g. 8081).
export PORT=8081 (1)
npm start
1 | Setting this user function to run on port 8081 . |
Run Kalix Proxy on a custom port
To update the docker compose file to run multiple proxy instances, add the snippet below:
kalix-proxy: (1)
image: gcr.io/kalix-public/kalix-proxy:latest
ports:
- "900x:900x" (2)
JAVA_TOOL_OPTIONS: >
-Dkalix.proxy.http-port=900x (2)
-Dconfig.resource=dev-mode.conf
-Dlogback.configurationFile=logback-dev-mode.xml
environment:
USER_FUNCTION_HOST: ${USER_FUNCTION_HOST:-host.docker.internal}
USER_FUNCTION_PORT: (3)
1 | This name has to be unique in your docker compose file (docker compose uses this name to uniquely identify the running container). |
2 | The host port ("900x") in the port mapping must be unique for each proxy instance. Note that the internal proxy port should also be changed hence the extra -Dkalix.proxy.http-port=900x option. |
3 | The user function port must be unique for each service you start. See the previous section for how to define this. |