{"id":28250929,"url":"https://github.com/onify/citizen-infra","last_synced_at":"2026-04-24T20:34:56.394Z","repository":{"id":293483214,"uuid":"974283783","full_name":"onify/citizen-infra","owner":"onify","description":"Citizen Hub infrastructure","archived":false,"fork":false,"pushed_at":"2025-12-11T08:01:22.000Z","size":108,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-16T23:39:00.487Z","etag":null,"topics":["infrastructure","infrastructure-as-code","kubernetes","onify"],"latest_commit_sha":null,"homepage":"https://onify.co","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-28T14:33:47.000Z","updated_at":"2025-12-11T08:01:26.000Z","dependencies_parsed_at":"2025-05-15T15:46:45.828Z","dependency_job_id":"7fb68871-3d50-47f0-9970-772b20e664fb","html_url":"https://github.com/onify/citizen-infra","commit_stats":null,"previous_names":["onify/citizen-infra"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/onify/citizen-infra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fcitizen-infra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fcitizen-infra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fcitizen-infra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fcitizen-infra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onify","download_url":"https://codeload.github.com/onify/citizen-infra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onify%2Fcitizen-infra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32239948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["infrastructure","infrastructure-as-code","kubernetes","onify"],"created_at":"2025-05-19T14:19:13.859Z","updated_at":"2026-04-24T20:34:56.388Z","avatar_url":"https://github.com/onify.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Citizen Hub Infrastructure\n\nThe script generates Kubernetes manifests from templates.\nIt has some parameters documented below. It will create a namespace and all resources needed to run Onify Citizen Hub in that namespace.\n\n\u003e For more information about requirements, see [requirements](https://support.onify.co/docs/requirements).\n\n\u003e For more informatoon about installation, see [installation](https://github.com/onify/install). \n\n## Prerequisites\n\n* Client code\n* Instance code\n* License\n* Access to images (gcr/ghcr)\n\n## Container images\n\nThe following container images are used by Citizen Hub. Image versions may vary depending on your deployment requirements:\n\n* `eu.gcr.io/onify-images/hub/api:*`\n* `eu.gcr.io/onify-images/hub/app:*`\n* `eu.gcr.io/onify-images/hub/agent-server:*` (optional, used if Onify Agent is enabled)\n* `eu.gcr.io/onify-images/citizen/app:*`\n* `eu.gcr.io/onify-images/citizen/functions:*`\n* `docker.elastic.co/elasticsearch/elasticsearch:*`\n\n## Parameters\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| `--namespace` | Kubernetes namespace where resources will be created | `onify-citizen` |\n| `--clientInstance` | Instance identifier for the client | `test` |\n| `--clientCode` | Code identifier for the client | `acme` |\n| `--initialLicense` | Initial license key for the installation | `SOMELICENSE` |\n| `--adminPassword` | Password for the admin user. Needs to be a complext password with capital and lowercase letters, numbers and special characters  | `P@33w0rd543On1f7` |\n| `--registryCredentials` | Path to the container registry credentials file | `registryCredentials.json` |\n| `--domain` | Domain name for the ingress | `onify.net` |\n| `--output` | Directory where YAML files will be generated | `.` (current directory) |\n\nThe script will automatically generate:\n- `clientSecret`: (ONIFY_client_secret) A random 45-character string for client authentication\n- `appSecret`: (ONIFY_apiTokens_app_secret) A random 50-character string for application authentication\n\n## Examples\n\nThe manifests in `examples/acme` were created by running the script with the following parameters:\n\n```bash\n./onify-citizen.sh --namespace=onify-citizen-test --clientInstance=test --clientCode=acme --adminPassword='Sup3rS3cretP@ssw#rd' --registryCredentials=registryCredentials.json --output=./examples/acme --domain=acme.org\n```\n\n## Provisioning\n\nOnify Citizen Hub is based on several (micro)services; `api`, `worker`, `app`, `helix`, `functions` and `elasticsearch`. \nHere is how you can create Kubernetes manifest for these services;\n\n\u003e NOTE: For provisioning Onify Helix (helix), please see section below for more details.\n\n1. Run the script to template manifests by running:\n\n```bash\n./onify-citizen.sh --namespace=onify-citizen-prod --clientInstance=prod --clientCode=ace --adminPassword='Sup3rS3cretP@ssw#rd' --registryCredentials=registryCredentials.json --output=./prod --domain=acme.com\n```\n\n2. Start with creating the namespace by running:\n\n```bash\nkubectl apply -f prod/namespace.yaml\n```\n\n3. Apply the rest of the resources with:\n\n```bash\nkubectl apply -f prod/\n```\n\n### Delete\n\nTo delete and start over, run:\n\n```bash\nkubectl delete -f examples/acme\n```\n\n### Container registry\n\nTo download images, a secret is created containing the contents of the file specified by --registryCredentials.\n\nThe credential is basically built on this structure:\n`registryCredentials.json` is an example.\n\n```json\n{\n  \"auths\": {\n    \"eu.gcr.io\": {\n      \"auth\": \"BASE64 ENCODED GCR.IO KEYFILE\"\n    },\n    \"ghcr.io\": {\n      \"auth\": \"BASE64 ENCODED \u003e githubuser:PAT\"\n    }\n  }\n}\n```\n\n\u003e Please checkout `generate-registry-credentials.sh` how to generate `registryCredentials.json`.\n\n### Access / Ingress\n\n#### APP (and Helix)\n\nThe script will create an ingress manifest for onify-citizen with the following address:\n\n```\nhttps://$namespace.$domain\n```\n\n*Routes*\n\n* `/helix` \u003e `helix`\n* `/` \u003e `hub-app`\n\n#### API\n\nAn ingress for the API is also created with the address:\n\n```\nhttps://$namespace-api.$domain\n```\n\n\u003e NOTE: Do not route API to `/api`! This is proxied by the APP.\n \n## Cert and TLS\n\n### Let's Encrypt\n\nWe recommend certmanager for automating TLS certificates from letsencrypt.\nWhen certmanager is installed (using helm or similar). These manifests needs to be applied:\n\n```yaml\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-prod\nspec:\n  acme:\n    #change to your email\n    email: hello@onify.io\n    server: https://acme-v02.api.letsencrypt.org/directory\n    privateKeySecretRef:\n      name: letsencrypt-prod\n    solvers:\n    - http01:\n        ingress:\n          ingressClassName: nginx\n---\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-staging\nspec:\n  acme:\n    #change to your email\n    email: hello@onify.io\n    server: https://acme-staging-v02.api.letsencrypt.org/directory\n    privateKeySecretRef:\n      name: letsencrypt-staging\n    solvers:\n    - http01:\n        ingress:\n          ingressClassName: nginx\n}\n```\n\n\nThis script does not create annotations for certificates. Here´s an annotation xample if certmanager is used in you cluster.\n\n```yaml\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  annotations:\n    cert-manager.io/cluster-issuer: letsencrypt-prod  ## -\u003c this is the annotation for certmanager\n  name: onify-citizen-ingress\n  namespace: onify-citizen-test\nspec:\n  ingressClassName: nginx\n  rules:\n    - host: onify-citizen-test.acme.org\n      http:\n        paths:\n          - backend:\n              service:\n                name: onify-app\n                port:\n                  number: 3000\n            path: /\n            pathType: Prefix\n          - backend:\n              service:\n                name: onify-helix\n                port:\n                  number: 4000\n            path: /helix\n            pathType: Prefix\n\n  tls:\n    - hosts:\n        - onify-citizen-test.acme.org\n      secretName: tls-secret-app-prod\n```\n\n### Custom certificate\n\nCreate a secret with your custom certificate. Here's an example:\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: custom-tls-secret\n  namespace: onify-citizen\ntype: kubernetes.io/tls\ndata:\n  # The base64 encoded certificate\n  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZhekNDQTFPZ0F3SUJBZ0lVZXhhbXBsZWNlcnRpZmljYXRlYmFzZTY0ZGF0YQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t\n  # The base64 encoded private key\n  tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRd0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Mwd2dna3BBZ0VBQW9JQ0FRQzlYWkFBCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=\n```\n\nAnd here's an example of an Ingress using the custom certificate:\n\n```yaml\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: onify-citizen-ingress\n  namespace: onify-citizen\nspec:\n  ingressClassName: nginx\n  rules:\n    - host: onify-citizen.acme.org\n      http:\n        paths:\n          - backend:\n              service:\n                name: onify-app\n                port:\n                  number: 3000\n            path: /\n            pathType: Prefix\n          - backend:\n              service:\n                name: onify-helix\n                port:\n                  number: 4000\n            path: /helix\n            pathType: Prefix\n  tls:\n    - hosts:\n        - onify-citizen.acme.org\n      secretName: custom-tls-secret\n\n```\n\nNote: The certificate and key in the example above are just placeholders. Replace them with your actual base64 encoded certificate and private key.\n\n## Onify agent\n\nOnify agent is not provisioned default by using this script. To get the script so create those manifests aswell uncomment this line:\n\n```\n#onify_agent\n```\n\nRemember to add this environmental variables to api and worker if you need agent:\n\n```\nONIFY_websockets_agent_url = ws://onify-agent:8080/hub\n```\n\n## Elasticsearch\n\n### Persistent disk and backup\n\nThis script does not create any PVC or persistent disk so if that needed you need to create a PVC and change the manifests by your own. \nIt also does not create backup manifests.\n\nIn the `examples/elasticsearch/pvc_and_backup_example.yaml` theres a example of a PVC and a statefulset using PVC and also an additional volume dedicated for backups.\nTo then enable backups this needs to be run against the elastic cluster:\n\n```bash\ncurl -s \\\n -X PUT \\\n \"http://elasticsearch.namespace.svc.cluster.local:9200/_snapshot/backup_repo\" \\\n -H \"Content-Type: application/json\" -d '{\n    \"type\": \"fs\",\n    \"settings\": {\n      \"location\": \"/usr/share/elasticsearch/backup\"\n    }\n  }'\n```\n\nThis could be executed from the elastic pod.\n\n## Onify Helix\n\nOnify Helix is a custom image unlike the rest of the other services (api, app, functions, elasticsearch). This requires it´s own Git repo, container registry and CI/CD pipeline.\nWe recommend using GitHub. We have ready made GitHub Action Workflows for Onify Helix. But you can also run your own...\n\nHere is an example how to build latest in GitHub and use GitHub as container registry:\n\n```yaml\nname: Build latest\n\non:\n  push:\n    branches: [main]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      #CHECKOUT ACTION CLONES THE REPOSITORY\n      - uses: actions/checkout@v3\n\n      #SETUP VARIABLES\n      - name: Setup variables\n        id: variables\n        run: |-\n          echo \"repo=${{ github.repository }}\" | tr '[:upper:]' '[:lower:]' \u003e\u003e $GITHUB_OUTPUT\n\n      #LOGIN TO GHCR REGISTRY SO WE CAN PUSH THE IMAGE. USES THE DEFAULT GITHUB_TOKEN VARIABLE THAT WORKFLOW ALWAYS HAVE ACCESS TO\n      - name: Log in to the Container registry\n        uses: docker/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      #BUILD AND PUSH THE LATEST IMAGE\n      - name: Build and push latest\n        uses: docker/build-push-action@v5\n        with:\n          context: .\n          push: true\n          tags: |\n            ghcr.io/${{ steps.variables.outputs.repo }}:latest\n          build-args: ONIFY_GITHUB_ACCESS_TOKEN=${{ secrets.ONIFY_GITHUB_ACCESS_TOKEN }}\n```\n\n\u003e NOTE: The `ONIFY_GITHUB_ACCESS_TOKEN` is something you will get from Onify.\n\nYou need to replace the image (eg. `ghcr.io/onify/helix-app-lab:latest`) in `helix.yaml` with your own image and make sure you have access to that. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonify%2Fcitizen-infra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonify%2Fcitizen-infra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonify%2Fcitizen-infra/lists"}