Podinfo-rs is an example microservice written in pure Rust. It is supposed to document my (opinionated) best practices for writing microservices in Rust. This repository will also contain Kubernetes manifests and helm charts to document my best practices of building for and deploying to Kubernetes. If you have ideas, critique, or other ways of solving things, please feel free to open issues or create pull requests.
Podinfo-rs is inspired by podinfo.
To run the service locally from your dev environment you need Rust and cargo
installed. Then run:
cargo run
To test the service run:
curl -v http://localhost:20000/_z/healthz
The call should return a 200 OK
:
HTTP/1.1 200 OK
content-length: 0
date: Sat, 08 Jan 2022 15:52:39 GMT
The service can be configured via environment variables, exclusively.
Variable | Description | Default |
---|---|---|
RUST_LOG | Configure logging level of components. Compatible with env_logger | info |
PODINFORS_BIND_IP | IP address to bind the service to. Currently only IPV4 supported. | 127.0.0.1 |
PODINFORS_BIND_PORT | The port the service should listen on. | 20000 |
Request | Description |
---|---|
GET /_z/healthz |
Returns 200 OK when the REST API is up. |
GET /_z/readyz |
Returns 200 OK when the service is functioning (ready state set to ready) or 503 Service Unavailable when ready state is set to not ready. The ready state is ready by default. |
POST /_z/readyz/enable |
Sets the ready state to ready. |
POST /_z/readyz/disable |
Sets the ready state to not ready |
GET /_z/buildz |
Return build information generated by build_info. |
GET /_z/infoz |
Return some runtime information such as hostname, capabilities, PID, uptime and system time. |
POST /echo |
Echoes the POST ed body and it's Content-Type if specified. If no Content-Type ist given, it will echo the body with a Content-Type of application/octet-stream . |
The project uses GitHub Actions for the build and release process:
- The build.yml pipeline is run on every push and merge request. It checks formatting, uses
cargo clippy
for linting and builds and tests the project and then tries to build the container. The container is build in--release
mode, and tests are run again. - The release.yml pipeline is run on version tags (semantic versioning compatible) and performs all steps of the build pipeline, but finally pushes the docker image into the GitHub Container Registry.
- The main branch is protected, thus all changes have to be merged into the
main
branch via pull requests. A pull request requires to pass the build pipeline. We also require merge request to be based on an up-to-datemain
with a linea history.
- It's unclear whether the container build should run tests again.
- The release pipeline should ideally produce a GitHub release in addition to the docker image.
- Untagged builds on main could also produce snapshot images for easier testing.
- How to handle pre-releases?
We use git-cliff to generate the CHANGELOG from commits following the Conventional Commits standard. The configuration for git-cliff
is available in cliff.toml
.
Releases are performed following a number of manual steps. We use cargo-next
for managing the version number.
The steps are:
- Check the current version and whether it is the version you want to release (specifically check for breaking changes). You can use
cargo next --get
to get the current version number. - If required, update the version accordingly, e.g., with something like
cargo next --patch/--minor/--major
. - Update the
CHANGELOG
withgit cliff --tag <release version>
. - Commit everything to a release branch (
release-<version>
). - When the branch is merged, tag the commit on
main
withgit tag -a -m 'Release <release version>'
. - Push the tag to trigger the release.
- Bump the version to the next patch version (
cargo next --patch
).
The project uses Renovate to automatically update dependencies using pull requests. We use a fairly standard setup, please have a lokk at renovate.json
. Modifications so far:
- Added
:semanticCommits
for semantic commit messages that can be used to automatically generate a CHANGELOG withgit-chglog
(or other tools).
Currently we have trivy and anchore enabled, however, this topic has to be investigated further.