feat(deploy): webhook queue+nocache, restart sweep, secrets at rest

- Webhook-triggered deploys now go through the per-service deploy queue
  and default to no_cache builds (dflow convention — prevents stale
  layer surprises on push).
- Boot sweep marks deployments interrupted by restart as failed instead
  of leaving phantom queued/building rows.
- is_secret environment variables are AES-GCM-encrypted at rest
  (enc:v1: prefix); key from SECRETS_KEY or JWT_SECRET fallback.
  Existing plaintext secrets encrypt on boot; deploy/exec paths decrypt
  transparently. Masked-echo writes preserve stored ciphertext.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-10-08 16:27:10 +02:00
1 parent 7839dc48a3
commit 747b714a02
8 files changed
+242 -8

No files matched your search

+4
View File
@@ -2,6 +2,7 @@ package api
import (
"containr/internal/database"
"containr/internal/secrets"
"net/http"
"time"
@@ -160,6 +161,9 @@ func handleUpdateVariables(c *gin.Context) {
value = stored
}
}
if v.IsSecret {
value = secrets.Encrypt(value)
}
varID := uuid.New()
_, err = tx.Exec(
`INSERT INTO environment_variables (id, service_id, key, value, is_secret, created_at, updated_at)