{"id":16288432,"url":"https://github.com/dekstroza/postgresnaut","last_synced_at":"2025-08-10T10:11:29.318Z","repository":{"id":88779696,"uuid":"304766489","full_name":"dekstroza/postgresnaut","owner":"dekstroza","description":"Micronaut and Graal example service using PostgreSQL as the datastore compiled into statically or dynamically linked native image.","archived":false,"fork":false,"pushed_at":"2020-11-08T21:39:21.000Z","size":4969,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T09:51:00.673Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dekstroza.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-17T00:30:05.000Z","updated_at":"2020-11-08T21:39:23.000Z","dependencies_parsed_at":"2023-06-12T14:15:17.066Z","dependency_job_id":null,"html_url":"https://github.com/dekstroza/postgresnaut","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dekstroza/postgresnaut","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekstroza%2Fpostgresnaut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekstroza%2Fpostgresnaut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekstroza%2Fpostgresnaut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekstroza%2Fpostgresnaut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dekstroza","download_url":"https://codeload.github.com/dekstroza/postgresnaut/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dekstroza%2Fpostgresnaut/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269707716,"owners_count":24462443,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T19:48:18.130Z","updated_at":"2025-08-10T10:11:29.297Z","avatar_url":"https://github.com/dekstroza.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Postgresnaut - Micronaut \u0026 GraalVM example\n![Java CI with Maven](https://github.com/dekstroza/postgresnaut/workflows/Java%20CI%20with%20Maven/badge.svg)\n\n\n## Description\n\nMicronaut and Graal example service using PostgreSQL as the datastore compiled into statically or dynamically linked native image.\nThis is a slightly more comprehensive hello world type of a microservice built with micronaut, using postgresql as its data store. It can be compiled as tradidtional java application and packaged into docker container as runnable jar, or as graalvm compiled native binary (both statically and dynamically linked) and packaged into docker container.\n\n## Features\n\nFeatures demonstrated are: compilation to native image (with static linking) jpa/hibernate data repository, versioned api, jaeger based tracing, prometheus metric and open-api. Helm chart provided will deploy built docker image along with postgresql, prometheus and all-in-one jaeger demonstrating all of the bespoke features. There is also a demo grafana dashboard provided with the helm chart, which will be installed into grafana upon chart deployment.\n\n## Implementations\n\nBeside this implementation which is using hibernate and jpa data repository approach, there is another branch *micronaut-data-repository* with same code and capabilities, just realized with the micronaut's native jdbc data repository. Both branches use same helm charts and offer same functionailty, only difference is the implementation choice for db interaction.\n\n## Requirements\n\n1. Java with Graal, can be install with sdkman (https://sdkman.io)\n2. Maven\n3. Docker\n4. Kubernetes\n5. Helm\n\n**Please be aware that native image compilation is done inside docker container, compilation takes a while and requires resources (CPU,MEM) so adjust your docker resource limits if running on Mac or Windows.**\n\nEasiest way to run this demo is to install sdkman, and using it install java (graal, latest) and micronaut (latest). The instructions assume k8s on Docker for Mac/Windows (k8s installed with docker itself). This makes exposing services through LoadBalancer easy, as they are exposed on localhost.\n\n\n## Building with maven\n\n- Runnable jar build\n  ```\n  ## Skip all graalvm and docker stuff and just build runnable jar\n  ./mvnw clean install -Ddockerfile.skip\n  ```\n- Build docker image with runnable jar\n  ```\n  ## Skip all graalvm and docker stuff and just build runnable jar\n  ./mvnw clean install\n  ```\n- Build docker image with dynamically linked native image\n  ```\n  ## Build dynamically linked native image\n  ./mvnw clean install -Ddynamic\n  ```\n- Build docker image with statically linked native image\n  \n  In order to build statically linked native images, we need extra step first: we need to add support for libmuslc to the oracle's builder image. \n  To do this run:\n  ```\n  cd builder-image\n  ./build.sh\n  ```\n  This will build the helper image, used later when the project is compiled and packaged into its docker container. \n  Alternatively, the helper image will be pulled from my docker repository located here **dekstroza/graalvm-ce:20.2.0-r11-libmuslc**\n  ```\n  ## Now run to create statically linked native image and package it into docker container\n  ./mvnw clean install -Dstatic\n  ```\n\n## Trying out the service\n\nService can be deployed using provided helm charts in k8s directory with\n```\nhelm install --generate-name k8s/postgresnaut\n```\nThis will deploy two instances of the service, postgresql, prometheus, grafana and jaeger-all-in-one (for demo purpose). It\nwill also configure grafana to use prometheus as datasource, and automatically\nadd application dashboard to the grafana.\nService is annotated for prometheus in helm charts, and will automatically be\nscraped by prometheus.\n\nAfter deploying helm chart, follow instructions printed by helm to obtain\ngrafana admin password, and access grafana with browser. Follow the instructions in the Notes printed after helm chart is deployed.\n\nAlternatively after deploying service with helm command above, more instances\ncan be started with \"normal\" jvm for comparision examples, using the following commands:\n```\n# Expose postgresql on loadbalancer\nSERVICE_NAME=$(kubectl get svc | grep 'postgresnaut\\-[0-9]*\\-postgresql ' | awk '{print $1}'); kubectl expose svc $SERVICE_NAME --name $SERVICE_NAME-balanced --type LoadBalancer --port 27017 --target-port 27017\njava -jar target/postgresnaut-1.0.0-SNAPSHOT.jar\n```\nThis can be usefull to compare startup times, and pre and post jvm warmup performance differences.\n\n### Some common commands:\n\nTesting the service from command line using curl:\n\n```bash\n# Save alarm to the database\ncurl -X POST localhost:7777/postgresnaut/alarms -d '{\"name\": \"Second Alarm\", \"severity\": \"MEDIUM\"}' -H 'Content-Type:application/json'\n# Get all alarms\ncurl -v localhost:7777/postgresnaut/alarms\n# Health endpoint\ncurl -v localhost:7777/health\n# Prometheus metric endpoint\ncurl -v localhost:7777/prometheus\n```\nTiming the service responses using curl and command line:\n\n1. Create file curl-format.txt\n2. Test the service with curl command\n\nContent of the curl-format.txt:\n```\n      time_namelookup:  %{time_namelookup}\\n\n         time_connect:  %{time_connect}\\n\n      time_appconnect:  %{time_appconnect}\\n\n     time_pretransfer:  %{time_pretransfer}\\n\n        time_redirect:  %{time_redirect}\\n\n   time_starttransfer:  %{time_starttransfer}\\n\n                    ----------\\n\n            time_total:  %{time_total}\\n\n``` \nCommand to test the latency (get all alarms, or similar for save alarm url):\n```\n# For get all alarms\ncurl -w \"@curl-format.txt\" -o /dev/null -s \"http://localhost:7777/postgresnaut/alarms\"\n# For save alarm\ncurl -w \"@curl-format.txt\" -o /dev/null -s -X POST localhost:7777/postgresnaut/alarms -d '{\"name\": \"Second Alarm\", \"severity\": \"MEDIUM\"}' -H 'Content-Type:application/json'\n# Save several alarms\nfor i in {10..20}; do curl -X POST localhost:7777/postgresnaut/alarms -d \"{\\\"name\\\": \\\"Second Alarm\\\", \\\"severity\\\": \\\"MEDIUM\\\"}\" -H 'Content-Type:application/json'; done\n```\n\n## Exposed endpoints\n```\nGrafana is available on http://localhost:8769/ username is admin and the password can be obtained following instructions printed after deploying helm chart.\n```\n\n```\nDemo dashboard is provided with the Grafana, providing some basic telemetry on cpu, mem and api calls.\n```\n\n```\nJaeger UI is on: localhost:80 and shows some useless (in this example) spans, provided more as illustration how to do it.\n```\n\n```\nOpenapi definition can be accessed at: http://localhost:7777/swagger/micronaut-service-1.0.0.yml\n```\n\n```\nSwagger ui is available at: http://localhost:7777/swagger-ui\n```\n\n```\nRedoc is available at:http://localhost:7777/redoc\n```\n\n```\nRapidoc is available at: http://localhost:7777/rapidoc\n```\n\nIn order to reduce memory consumption of graalvm native images, few netty related arguments are passed to the application binary on startup (see netty documentation for more info)\n\n\nHappy hacking...\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdekstroza%2Fpostgresnaut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdekstroza%2Fpostgresnaut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdekstroza%2Fpostgresnaut/lists"}