From dbc0aa529f120bc8264616e9120a2fd21a13db0c Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 24 Aug 2026 09:04:51 +0200 Subject: [PATCH] feat(templates): add HashiCorp Vault service template Add Vault Compose configuration and generated service metadata with coverage for deployment settings. --- templates/compose/vault.yaml | 25 ++++++++++++++++ templates/service-templates-latest.json | 17 +++++++++++ templates/service-templates.json | 17 +++++++++++ tests/Unit/VaultServiceTemplateTest.php | 38 +++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 templates/compose/vault.yaml create mode 100644 tests/Unit/VaultServiceTemplateTest.php diff --git a/templates/compose/vault.yaml b/templates/compose/vault.yaml new file mode 100644 index 000000000..c0af9cd51 --- /dev/null +++ b/templates/compose/vault.yaml @@ -0,0 +1,25 @@ +# documentation: https://developer.hashicorp.com/vault/docs/deploy/run-container +# slogan: HashiCorp Vault securely stores and controls access to secrets. +# category: security +# tags: vault,hashicorp,secrets,security,encryption +# port: 8200 + +services: + vault: + image: 'hashicorp/vault:${VAULT_VERSION:-latest}' + command: server + environment: + - SERVICE_URL_VAULT_8200 + - VAULT_ADDR=http://127.0.0.1:8200 + - VAULT_API_ADDR=${SERVICE_URL_VAULT_8200} + - 'VAULT_LOCAL_CONFIG={"ui":true,"disable_mlock":true,"storage":{"file":{"path":"/vault/file"}},"listener":{"tcp":{"address":"0.0.0.0:8200","tls_disable":true}}}' + volumes: + - vault-data:/vault/file + healthcheck: + test: + - CMD-SHELL + - 'wget -qO- "http://127.0.0.1:8200/v1/sys/health?standbyok=true&sealedcode=200&uninitcode=200" >/dev/null || exit 1' + interval: 10s + timeout: 5s + retries: 12 + start_period: 15s diff --git a/templates/service-templates-latest.json b/templates/service-templates-latest.json index f90fa3790..00243fff0 100644 --- a/templates/service-templates-latest.json +++ b/templates/service-templates-latest.json @@ -5457,6 +5457,23 @@ "template_last_updated_at": "2026-04-06T11:35:16-05:00", "port": "3000" }, + "vault": { + "documentation": "https://developer.hashicorp.com/vault/docs/deploy/run-container?utm_source=coolify.io", + "slogan": "HashiCorp Vault securely stores and controls access to secrets.", + "compose": "c2VydmljZXM6CiAgdmF1bHQ6CiAgICBpbWFnZTogJ2hhc2hpY29ycC92YXVsdDoke1ZBVUxUX1ZFUlNJT046LWxhdGVzdH0nCiAgICBjb21tYW5kOiBzZXJ2ZXIKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1ZBVUxUXzgyMDAKICAgICAgLSAnVkFVTFRfQUREUj1odHRwOi8vMTI3LjAuMC4xOjgyMDAnCiAgICAgIC0gJ1ZBVUxUX0FQSV9BRERSPSR7U0VSVklDRV9VUkxfVkFVTFRfODIwMH0nCiAgICAgIC0gJ1ZBVUxUX0xPQ0FMX0NPTkZJRz17InVpIjp0cnVlLCJkaXNhYmxlX21sb2NrIjp0cnVlLCJzdG9yYWdlIjp7ImZpbGUiOnsicGF0aCI6Ii92YXVsdC9maWxlIn19LCJsaXN0ZW5lciI6eyJ0Y3AiOnsiYWRkcmVzcyI6IjAuMC4wLjA6ODIwMCIsInRsc19kaXNhYmxlIjp0cnVlfX19JwogICAgdm9sdW1lczoKICAgICAgLSAndmF1bHQtZGF0YTovdmF1bHQvZmlsZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tICJodHRwOi8vMTI3LjAuMC4xOjgyMDAvdjEvc3lzL2hlYWx0aD9zdGFuZGJ5b2s9dHJ1ZSZzZWFsZWRjb2RlPTIwMCZ1bmluaXRjb2RlPTIwMCIgPi9kZXYvbnVsbCB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTIKICAgICAgc3RhcnRfcGVyaW9kOiAxNXMK", + "tags": [ + "vault", + "hashicorp", + "secrets", + "security", + "encryption" + ], + "category": "security", + "logo": "svgs/default.webp", + "minversion": "0.0.0", + "template_last_updated_at": null, + "port": "8200" + }, "vaultwarden": { "documentation": "https://github.com/dani-garcia/vaultwarden?utm_source=coolify.io", "slogan": "Vaultwarden is a password manager that allows you to securely store and manage your passwords.", diff --git a/templates/service-templates.json b/templates/service-templates.json index 5a4ad35be..c193f0934 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -5457,6 +5457,23 @@ "template_last_updated_at": "2026-04-06T11:35:16-05:00", "port": "3000" }, + "vault": { + "documentation": "https://developer.hashicorp.com/vault/docs/deploy/run-container?utm_source=coolify.io", + "slogan": "HashiCorp Vault securely stores and controls access to secrets.", + "compose": "c2VydmljZXM6CiAgdmF1bHQ6CiAgICBpbWFnZTogJ2hhc2hpY29ycC92YXVsdDoke1ZBVUxUX1ZFUlNJT046LWxhdGVzdH0nCiAgICBjb21tYW5kOiBzZXJ2ZXIKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9WQVVMVF84MjAwCiAgICAgIC0gJ1ZBVUxUX0FERFI9aHR0cDovLzEyNy4wLjAuMTo4MjAwJwogICAgICAtICdWQVVMVF9BUElfQUREUj0ke1NFUlZJQ0VfRlFETl9WQVVMVF84MjAwfScKICAgICAgLSAnVkFVTFRfTE9DQUxfQ09ORklHPXsidWkiOnRydWUsImRpc2FibGVfbWxvY2siOnRydWUsInN0b3JhZ2UiOnsiZmlsZSI6eyJwYXRoIjoiL3ZhdWx0L2ZpbGUifX0sImxpc3RlbmVyIjp7InRjcCI6eyJhZGRyZXNzIjoiMC4wLjAuMDo4MjAwIiwidGxzX2Rpc2FibGUiOnRydWV9fX0nCiAgICB2b2x1bWVzOgogICAgICAtICd2YXVsdC1kYXRhOi92YXVsdC9maWxlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gImh0dHA6Ly8xMjcuMC4wLjE6ODIwMC92MS9zeXMvaGVhbHRoP3N0YW5kYnlvaz10cnVlJnNlYWxlZGNvZGU9MjAwJnVuaW5pdGNvZGU9MjAwIiA+L2Rldi9udWxsIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAxMgogICAgICBzdGFydF9wZXJpb2Q6IDE1cwo=", + "tags": [ + "vault", + "hashicorp", + "secrets", + "security", + "encryption" + ], + "category": "security", + "logo": "svgs/default.webp", + "minversion": "0.0.0", + "template_last_updated_at": null, + "port": "8200" + }, "vaultwarden": { "documentation": "https://github.com/dani-garcia/vaultwarden?utm_source=coolify.io", "slogan": "Vaultwarden is a password manager that allows you to securely store and manage your passwords.", diff --git a/tests/Unit/VaultServiceTemplateTest.php b/tests/Unit/VaultServiceTemplateTest.php new file mode 100644 index 000000000..c758a78e9 --- /dev/null +++ b/tests/Unit/VaultServiceTemplateTest.php @@ -0,0 +1,38 @@ +toBeFile(); + + $compose = file_get_contents($templatePath); + + expect($compose) + ->toContain('hashicorp/vault:${VAULT_VERSION:-latest}') + ->toContain('SERVICE_URL_VAULT_8200') + ->toContain('VAULT_API_ADDR=${SERVICE_URL_VAULT_8200}') + ->toContain('"disable_mlock":true') + ->toContain('"storage":{"file":{"path":"/vault/file"}}') + ->toContain('vault-data:/vault/file') + ->toContain('/v1/sys/health?standbyok=true&sealedcode=200&uninitcode=200'); + + foreach (['service-templates.json', 'service-templates-latest.json'] as $templateFile) { + $templates = json_decode( + file_get_contents(__DIR__."/../../templates/{$templateFile}"), + associative: true, + flags: JSON_THROW_ON_ERROR, + ); + + expect($templates)->toHaveKey('vault'); + expect($templates['vault']['port'] ?? null)->toBe('8200'); + expect($templates['vault']['category'] ?? null)->toBe('security'); + + $generatedCompose = base64_decode($templates['vault']['compose'], strict: true); + + expect($generatedCompose) + ->toContain('hashicorp/vault:${VAULT_VERSION:-latest}') + ->toContain($templateFile === 'service-templates.json' + ? 'VAULT_API_ADDR=${SERVICE_FQDN_VAULT_8200}' + : 'VAULT_API_ADDR=${SERVICE_URL_VAULT_8200}'); + } +});