Compare commits

..

11 Commits

Author SHA1 Message Date
git b422a55c02 Updated terraform configurations 2026-04-20 22:23:20 +10:00
beatz174-bit b6d2e4ee62 Merge pull request #45 from beatz174-bit/codex/update-node-red-flow-for-idempotency
Make Grafana Docker Safe Update flow idempotent for repeated alerts
2026-04-15 07:42:34 +10:00
beatz174-bit 438cf57127 Make Grafana docker update flow idempotent after success 2026-04-15 07:42:00 +10:00
beatz174-bit 6ada434618 Merge pull request #44 from beatz174-bit/codex/create-script-to-automate-terraform-configuration-seiyl9
Add script to generate Terraform config from plan and document its usage
2026-04-14 20:19:10 +10:00
beatz174-bit 2a6c905eb8 Merge branch 'main' into codex/create-script-to-automate-terraform-configuration-seiyl9 2026-04-14 20:19:02 +10:00
beatz174-bit 9ad21c5846 Harden generated config temp path creation 2026-04-14 20:18:16 +10:00
beatz174-bit 2bab864d5e Merge pull request #43 from beatz174-bit/codex/create-script-to-automate-terraform-configuration
Add Terraform plan-to-config reconciliation script
2026-04-14 18:20:07 +10:00
beatz174-bit ebae1ed990 Add Terraform plan-to-config reconciliation script 2026-04-14 18:19:51 +10:00
beatz174-bit 5e49b6774b Merge pull request #42 from beatz174-bit/codex/scaffold-terraform-structure-for-homelab
Scaffold Terraform foundations for incremental Docker and Proxmox adoption
2026-04-14 18:09:15 +10:00
beatz174-bit 228413d780 Scaffold incremental Terraform foundations for docker and proxmox 2026-04-14 18:08:56 +10:00
git 7279ade925 new file: infrastructure/.gitignore
new file:   infrastructure/terraform/bootstrap/backend.tf
	new file:   infrastructure/terraform/bootstrap/main.tf
	new file:   infrastructure/terraform/bootstrap/outputs.tf
	new file:   infrastructure/terraform/bootstrap/providers.tf
	new file:   infrastructure/terraform/bootstrap/variables.tf
	new file:   infrastructure/terraform/docker/.terraform.lock.hcl
	new file:   infrastructure/terraform/docker/main.tf
	modified:   monitoring/node-red/data/context/00b02bbd01c91485/flow.json
	modified:   monitoring/node-red/data/update-events.ndjson
2026-04-14 17:42:30 +10:00
39 changed files with 1306 additions and 24 deletions
+4 -4
View File
@@ -2,7 +2,7 @@ services:
update-test: update-test:
image: nginx:1.28.1 image: nginx:1.28.1
container_name: update-test container_name: update-test
profiles: ["core","all","test"] profiles: ["test"]
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # returns 0 if Nginx is up test: ["CMD", "curl", "-f", "http://localhost"] # returns 0 if Nginx is up
interval: 5s interval: 5s
@@ -11,14 +11,14 @@ services:
start_period: 2s start_period: 2s
docker-update-exporter-test: docker-update-exporter-test:
profiles: ["core","all","test"] profiles: ["test"]
build: build:
context: ${PROJECT_ROOT}/core/test context: ${PROJECT_ROOT}/core/test
container_name: docker-update-exporter-test container_name: docker-update-exporter-test
stdin_open: true stdin_open: true
tty: true tty: true
depends_on: # depends_on:
- docker-socket-proxy # - docker-socket-proxy
environment: environment:
DOCKER_HOST: tcp://docker-socket-proxy:2375 DOCKER_HOST: tcp://docker-socket-proxy:2375
volumes: volumes:
+32
View File
@@ -0,0 +1,32 @@
# Terraform working dir
**/.terraform/*
# Terraform state
*.tfstate
*.tfstate.*
**/terraform.tfstate
**/terraform.tfstate.*
# Crash logs
crash.log
crash.*.log
# Variable files with real values
*.tfvars
*.tfvars.json
# CLI config / overrides
override.tf
override.tf.json
*_override.tf
*_override.tf.json
.terraformrc
terraform.rc
# Plan files
*.tfplan
plan.out
# Local backend/state folders if you make them
state/
artifacts/
+14
View File
@@ -0,0 +1,14 @@
.terraform/
*.tfstate
*.tfstate.*
*.tfvars
*.tfvars.json
crash.log
override.tf
override.tf.json
*_override.tf
*_override.tf.json
*.tfplan
plan.out
state/
artifacts/
+54
View File
@@ -0,0 +1,54 @@
# Terraform foundations
This directory introduces Terraform in a conservative, incremental way for this homelab repo.
## Purpose in this repository
Terraform is used here to **document and gradually adopt management** of existing infrastructure without disrupting running services.
Current intent:
- Start with imported live Docker resources so infrastructure is visible and reproducible in code.
- Add Proxmox inventory/configuration later once provider details and import IDs are confirmed.
- Keep this phase local-state and learning-oriented (no remote backend yet).
## Tool boundaries
- **Docker Compose**: day-to-day application/service runtime definitions already used by this repo.
- **Terraform**: infrastructure state capture and controlled resource management (starting with imports).
- **Ansible**: follow-on host/configuration management after Terraform inventory and targets are stable.
- **NixOS**: host OS/system-level declarative configuration, separate from per-service compose workflows.
## Layout
- `docker/`: Docker provider scaffold and incremental import workflow.
- `proxmox/`: placeholder scaffold for later Proxmox adoption.
- `modules/`: placeholder module directories for future shared patterns.
## Incremental adoption plan
1. Import Docker containers one-by-one into Terraform state.
2. Reconcile and stabilize Docker Terraform configuration until `terraform plan` is clean.
3. Add Proxmox inventory/configuration scaffolding and imports later.
4. Introduce Ansible workflow after Terraform-managed inventory is trustworthy.
## Plan-to-config helper script
Use `scripts/reconcile_from_plan.sh` to automate Terraform configuration generation from `terraform plan` output (via Terraform's `-generate-config-out`).
From a Terraform module directory (for example `infrastructure/terraform/docker`):
```bash
../../scripts/reconcile_from_plan.sh --output-file zz_generated_from_plan.auto.tf
```
Notes:
- Best used with an import-first workflow that already contains `import {}` blocks.
- The script writes generated config into a `.auto.tf` file and runs `terraform fmt` on it.
- Always review generated arguments before apply.
## Safety notes
- State files are intentionally gitignored for safety and portability.
- Do **not** run `terraform apply` until imported resources are fully reconciled and plan output is reviewed as no-op for intended targets.
- No remote backend is configured yet by design.
+24
View File
@@ -0,0 +1,24 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/kreuzwerker/docker" {
version = "3.0.2"
constraints = "3.0.2"
hashes = [
"h1:cT2ccWOtlfKYBUE60/v2/4Q6Stk1KYTNnhxSck+VPlU=",
"zh:15b0a2b2b563d8d40f62f83057d91acb02cd0096f207488d8b4298a59203d64f",
"zh:23d919de139f7cd5ebfd2ff1b94e6d9913f0977fcfc2ca02e1573be53e269f95",
"zh:38081b3fe317c7e9555b2aaad325ad3fa516a886d2dfa8605ae6a809c1072138",
"zh:4a9c5065b178082f79ad8160243369c185214d874ff5048556d48d3edd03c4da",
"zh:5438ef6afe057945f28bce43d76c4401254073de01a774760169ac1058830ac2",
"zh:60b7fadc287166e5c9873dfe53a7976d98244979e0ab66428ea0dea1ebf33e06",
"zh:61c5ec1cb94e4c4a4fb1e4a24576d5f39a955f09afb17dab982de62b70a9bdd1",
"zh:a38fe9016ace5f911ab00c88e64b156ebbbbfb72a51a44da3c13d442cd214710",
"zh:c2c4d2b1fd9ebb291c57f524b3bf9d0994ff3e815c0cd9c9bcb87166dc687005",
"zh:d567bb8ce483ab2cf0602e07eae57027a1a53994aba470fa76095912a505533d",
"zh:e83bf05ab6a19dd8c43547ce9a8a511f8c331a124d11ac64687c764ab9d5a792",
"zh:e90c934b5cd65516fbcc454c89a150bfa726e7cf1fe749790c7480bbeb19d387",
"zh:f05f167d2eaf913045d8e7b88c13757e3cf595dd5cd333057fdafc7c4b7fed62",
"zh:fcc9c1cea5ce85e8bcb593862e699a881bd36dffd29e2e367f82d15368659c3d",
]
}
+48
View File
@@ -0,0 +1,48 @@
# Docker Terraform scaffold
This directory is for **incremental, import-first Terraform adoption** of existing Docker containers.
## What this directory is for
- Document existing live Docker resources in Terraform.
- Import containers one-by-one.
- Reconcile Terraform code with real runtime values until plan is clean.
## Initialize
From this directory:
```bash
terraform init
```
## Safe incremental import workflow
1. Add one `docker_container` resource block in `main.tf` for an already-running container.
2. Import it into state:
```bash
terraform import docker_container.<resource_name> <container_id_or_container_name>
```
3. Inspect imported state:
```bash
terraform state show docker_container.<resource_name>
```
4. Copy required/meaningful arguments from state output into `main.tf`.
5. Run `terraform plan` and refine until there are no unintended changes.
## Reconciliation guidance
- Keep one resource block per imported container.
- Prefer explicit values for arguments that affect recreation.
- Avoid broad changes; reconcile each container independently.
- Do **not** run `terraform apply` until plan output is intentionally clean.
## State and secrets handling
- State files are ignored via `../.gitignore` because they may contain environment-specific metadata.
- Do not commit real `.tfvars` files with machine-specific values.
- Use `terraform.tfvars.example` as a safe starter template.
+26
View File
@@ -0,0 +1,26 @@
# Docker Terraform workflow in this repo:
# 1) Add a minimal resource block for ONE existing container.
# 2) Import that live container into state:
# terraform import docker_container.<name> <container_id_or_name>
# 3) Inspect imported arguments:
# terraform state show docker_container.<name>
# 4) Copy required arguments into this file and refine.
# 5) Repeat until terraform plan shows no unintended changes.
# Example skeleton for future imported containers (intentionally commented):
# resource "docker_container" "example_service" {
# name = "existing-container-name"
# image = "repo/image:tag"
#
# # Add additional arguments based on `terraform state show` output.
# # Keep values aligned with the live container so plan is a no-op.
# }
#resource "docker_container" "searxng-webapp" {
# name = "searxng-webapp"
# image = "searxng/searxng"
#}
#import {
# to = docker_container.searxng-webapp
# id = "5e755fc8478a3d088be12a1bb26df78e2f1990c56e1f7671f0cbf9761330092b"
#}
@@ -0,0 +1,19 @@
output "docker_host_in_use" {
description = "Docker daemon endpoint currently targeted by this workspace."
value = var.docker_host
}
output "managed_container_names" {
description = "Names of containers intentionally tracked in Terraform configuration."
value = var.managed_container_names
}
output "import_reconciliation_steps" {
description = "Short reminder of the safe import-first workflow."
value = [
"Create one docker_container block for an existing container.",
"Run terraform import for that block.",
"Run terraform state show and copy required arguments.",
"Refine config until terraform plan has no unintended changes.",
]
}
@@ -0,0 +1,4 @@
provider "docker" {
# Local Docker socket default for incremental import/documentation workflow.
host = var.docker_host
}
@@ -0,0 +1,54 @@
# -----------------------------------------------------------------------------
# AUTO-GENERATED BY reconcile_from_plan.sh
# Generated: 2026-04-14T10:53:00Z
# Source: terraform plan -generate-config-out
# Review carefully before apply.
# -----------------------------------------------------------------------------
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform from "5e755fc8478a3d088be12a1bb26df78e2f1990c56e1f7671f0cbf9761330092b"
resource "docker_container" "searxng-webapp" {
entrypoint = ["/usr/local/searxng/entrypoint.sh"]
hostname = "searxng.lan.ddnsgeek.com"
image = "sha256:6a9a175cd122c005abe2dc15d7cbfcd5109619e9dcccb511c34be244e10f49bc"
must_run = true
name = "searxng-webapp"
network_mode = "core_traefik"
read_only = true
restart = "always"
tmpfs = {
"/run" = ""
"/tmp" = ""
"/var" = ""
}
wait = false
wait_timeout = 60
working_dir = "/usr/local/searxng"
healthcheck {
interval = "20s"
retries = 8
start_period = "30s"
test = ["CMD-SHELL", "python3 -c \"import urllib.request,sys; r=urllib.request.urlopen('http://127.0.0.1:8080/', timeout=3); sys.exit(0 if 200<=r.status<400 else 1)\""]
timeout = "5s"
}
mounts {
read_only = false
source = "2255bde19ed136d348d29ada3d274eb3dbcb8aede13b246bbc9bac19fa38b37d"
target = "/var/cache/searxng"
type = "volume"
}
mounts {
read_only = false
source = "e7a1475c1265b7d1c15f7c4da10e93461f6f1bcf50fe8030131a6398509e2e48"
target = "/etc/searxng"
type = "volume"
}
lifecycle {
ignore_changes = [
env,
]
}
}
@@ -0,0 +1,9 @@
# Example only. Copy to terraform.tfvars for local use if needed.
# Do not commit host-specific overrides.
# docker_host = "unix:///var/run/docker.sock"
# Optional: list container names intentionally tracked in Terraform outputs.
managed_container_names = [
"example-container-name"
]
@@ -0,0 +1,11 @@
variable "docker_host" {
description = "Docker daemon host for local import workflow."
type = string
default = "unix:///var/run/docker.sock"
}
variable "managed_container_names" {
description = "Human-maintained list of containers intentionally tracked in Terraform docs/outputs."
type = list(string)
default = ["searxng-webapp"]
}
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.6.0"
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
@@ -0,0 +1,6 @@
# docker_container_placeholder module
Placeholder module directory for future shared Docker container patterns.
This is intentionally empty during initial import-first adoption.
Keep per-container resources explicit in `../../docker/main.tf` until stable patterns emerge.
@@ -0,0 +1,6 @@
# proxmox_vm_placeholder module
Placeholder module directory for future shared Proxmox VM patterns.
This is intentionally empty until provider schemas, import ID formats,
and non-destructive reconciliation strategy are validated.
+25
View File
@@ -0,0 +1,25 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/bpg/proxmox" {
version = "0.68.0"
constraints = "0.68.0"
hashes = [
"h1:4Q+bUZoRz7o2ij/oPS3SsAy1D2CDdIMasegk+ll7oho=",
"zh:012f3fce033a7921335576edba0f2d2dad7dcaec2e5ed3b68ced692845131656",
"zh:1853ddbaef049b14e738bf8531a2c8e45d9ac409676a7f7f997d40ae794db783",
"zh:2a284f49f95bfe022f8b5bfed6ae56df5577f590ff26ae12322767f23e3b6c50",
"zh:491a7d5a3cf47fc3016213ca047fcf20288200901f5c0195314c32925fcd36c0",
"zh:4a198ab0b40b02a35955156d9a195c76a22f92d4078195ce94316b793d0d58d4",
"zh:63f0e62c5805b48893f9a106ed11e628f1a3bc3d34360a2bb31a88cfcc2051dd",
"zh:64cdc6a3bdd56e2285a2d65a17d87ee284fcdbbe69246baed4aeaf465a955007",
"zh:6721eaaa4998795c0caed3225aa2bc8ff796a6de86114431194b9770f98e2600",
"zh:79ef8a813d1b3d5ef69f2a00a3160fde9ca65c541db42c998c69db6dea66558f",
"zh:96aa2d4a6cdac17dcccbb76a1ef0afc15052c3f13fa3bb0f3f44b385272405d4",
"zh:9e1e18b04f228d671e1653294828021e672dab6635a309e72b2da4ba3b9f07e9",
"zh:a91b69c6df914f8f0504d0f0d25af6a870b79befe6ae11d39a1bd8b879871084",
"zh:bc618ee4f85b8c5db0e1494d207d2a6170ca08dad5ce9844866550a94dd56bea",
"zh:ea85f7e5dbbe768e2e15e0cafacee1c94e319d04c1835db1984a6ce79674c8e4",
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
]
}
@@ -0,0 +1,36 @@
# Proxmox Terraform scaffold
This directory is a **placeholder scaffold** for future Proxmox Terraform adoption.
## What this directory is for
- Prepare provider/version/variable structure now.
- Delay real Proxmox resource management until import strategy is validated.
## Initialize
From this directory:
```bash
terraform init
```
## Current status
- No live Proxmox resources are defined yet.
- Provider auth variables are placeholders only.
- Import IDs and resource schemas must be verified against provider docs before adding resources.
## Future safe workflow
1. Add one resource block for an existing VM/object.
2. Import it with the provider-specific ID format.
3. Inspect with `terraform state show`.
4. Reconcile `.tf` arguments until `terraform plan` is clean.
5. Repeat incrementally.
## Safety notes
- Do not commit real credentials in `.tf` files or tracked `.tfvars`.
- State files are ignored by the Terraform-level `.gitignore`.
- Do not run `terraform apply` until plan is intentionally no-op for existing resources.
@@ -0,0 +1,76 @@
# proxmox_virtual_environment_vm.docker:
resource "proxmox_virtual_environment_vm" "docker" {
name = "docker"
node_name = "pve"
scsi_hardware = "virtio-scsi-single"
vm_id = 103
agent {
enabled = true
timeout = "15m"
trim = false
}
cpu {
cores = 4
numa = false
sockets = 1
type = "host"
units = 1024
}
disk {
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi0"
iothread = false
path_in_datastore = "vm-103-disk-0"
replicate = true
size = 120
ssd = false
}
disk {
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi1"
iothread = false
path_in_datastore = "vm-103-disk-1"
replicate = true
size = 250
ssd = false
}
memory {
dedicated = 8192
floating = 4096
keep_hugepages = false
shared = 0
}
network_device {
bridge = "vmbr0"
disconnected = false
enabled = true
firewall = true
}
operating_system {
type = "l26"
}
lifecycle {
ignore_changes = [
vga,
keyboard_layout,
tablet_device,
agent,
]
}
}
+51
View File
@@ -0,0 +1,51 @@
# Proxmox import-first workflow
#
# 1) Add one minimal resource block for one existing VM.
# 2) Add an import block for that VM using the provider's required import ID format.
# 3) Run:
# terraform init
# terraform plan
# or:
# ../scripts/reconcile_from_plan.sh -- -var-file=terraform.tfvars
# 4) Review generated config carefully.
# 5) Move only the useful arguments into a hand-maintained .tf file.
# 6) Repeat until `terraform plan` is a no-op.
# IMPORTANT:
# - Start with exactly ONE existing VM.
# - Do not apply until plan is clean.
# - Confirm the provider's exact import ID format before running import/plan.
# - Do not import your whole environment at once.
# Example placeholder for one existing VM
#resource "proxmox_virtual_environment_vm" "server-nixos" {
# name = "server-nixos"
# node_name = "pve"
#}
# Example import block
# REPLACE the id below with the exact import ID format required by your provider.
# This is provider-specific and must be confirmed before use.
#
# Commonly this will involve the Proxmox node name and VM ID in some form.
#
import {
to = proxmox_virtual_environment_vm.nix-cache
id = "pve/105"
}
import {
to = proxmox_virtual_environment_vm.server-nixos
id = "pve/104"
}
import {
to = proxmox_virtual_environment_vm.pihole
id = "pve/108"
}
import {
to = proxmox_virtual_environment_vm.pbs
id = "pve/106"
}
import {
to = proxmox_virtual_environment_vm.docker
id = "pve/103"
}
@@ -0,0 +1,63 @@
# proxmox_virtual_environment_vm.nix-cache:
resource "proxmox_virtual_environment_vm" "nix-cache" {
name = "nix-cache"
node_name = "pve"
scsi_hardware = "virtio-scsi-single"
vm_id = 105
agent {
enabled = true
timeout = "15m"
trim = false
}
cpu {
cores = 2
numa = false
sockets = 1
type = "x86-64-v2-AES"
units = 1024
}
disk {
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi0"
iothread = false
path_in_datastore = "vm-105-disk-0"
replicate = true
size = 100
ssd = false
}
memory {
dedicated = 2048
floating = 0
keep_hugepages = false
shared = 0
}
network_device {
bridge = "vmbr0"
disconnected = false
enabled = true
firewall = true
}
operating_system {
type = "l26"
}
lifecycle {
ignore_changes = [
vga,
keyboard_layout,
tablet_device,
agent,
]
}
}
@@ -0,0 +1,9 @@
output "proxmox_scaffold_ready" {
description = "Indicates this directory is a placeholder scaffold for future Proxmox adoption."
value = true
}
output "proxmox_endpoint_configured" {
description = "Whether a non-empty endpoint has been provided."
value = var.proxmox_endpoint != ""
}
+72
View File
@@ -0,0 +1,72 @@
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform
resource "proxmox_virtual_environment_vm" "pbs" {
name = "pbs"
node_name = "pve"
scsi_hardware = "virtio-scsi-single"
vm_id = 106
agent {
enabled = true
timeout = "15m"
trim = false
}
cpu {
cores = 4
numa = false
sockets = 1
type = "x86-64-v2-AES"
units = 1024
}
disk {
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi0"
iothread = false
path_in_datastore = "vm-106-disk-0"
replicate = true
size = 100
ssd = false
}
disk {
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi1"
iothread = false
path_in_datastore = "vm-106-disk-1"
replicate = true
size = 700
ssd = false
}
memory {
dedicated = 8192
floating = 4096
keep_hugepages = false
shared = 0
}
network_device {
bridge = "vmbr0"
disconnected = false
enabled = true
firewall = true
}
operating_system {
type = "l26"
}
lifecycle {
ignore_changes = [
vga,
keyboard_layout,
tablet_device,
agent,
]
}
}
@@ -0,0 +1,63 @@
# proxmox_virtual_environment_vm.pihole:
resource "proxmox_virtual_environment_vm" "pihole" {
name = "pihole"
node_name = "pve"
scsi_hardware = "virtio-scsi-single"
vm_id = 108
agent {
enabled = true
timeout = "15m"
trim = false
}
cpu {
cores = 2
numa = false
sockets = 1
type = "x86-64-v2-AES"
units = 1024
}
disk {
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "sata0"
iothread = false
path_in_datastore = "vm-108-disk-0"
replicate = true
size = 32
ssd = false
}
memory {
dedicated = 2048
floating = 0
keep_hugepages = false
shared = 0
}
network_device {
bridge = "vmbr0"
disconnected = false
enabled = true
firewall = true
}
operating_system {
type = "l26"
}
lifecycle {
ignore_changes = [
vga,
keyboard_layout,
tablet_device,
agent,
]
}
}
@@ -0,0 +1,11 @@
provider "proxmox" {
# Placeholder-only scaffold.
# Confirm exact provider auth mode and endpoint details before real use.
endpoint = var.proxmox_endpoint
insecure = var.proxmox_insecure
# username = var.proxmox_username
# password = var.proxmox_password
api_token = "${var.proxmox_api_token_id}=${var.proxmox_api_token_secret}"
}
@@ -0,0 +1,88 @@
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform
resource "proxmox_virtual_environment_vm" "server-nixos" {
name = "server-nixos"
node_name = "pve"
scsi_hardware = "virtio-scsi-single"
vm_id = 104
agent {
enabled = true
timeout = "15m"
trim = false
}
cpu {
cores = 4
numa = false
sockets = 1
type = "x86-64-v2-AES"
units = 1024
}
disk {
aio = "io_uring"
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi0"
iothread = false
path_in_datastore = "vm-104-disk-0"
replicate = true
size = 32
ssd = false
}
disk {
aio = "io_uring"
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi1"
iothread = false
path_in_datastore = "vm-104-disk-1"
replicate = true
size = 200
ssd = false
}
disk {
aio = "io_uring"
backup = true
cache = "none"
datastore_id = "local-lvm"
discard = "ignore"
file_format = "raw"
interface = "scsi2"
iothread = false
path_in_datastore = "vm-104-disk-2"
replicate = true
size = 200
ssd = false
}
memory {
dedicated = 4096
floating = 2048
keep_hugepages = false
shared = 0
}
network_device {
bridge = "vmbr0"
disconnected = false
enabled = true
firewall = true
}
operating_system {
type = "l26"
}
lifecycle {
ignore_changes = [
vga,
keyboard_layout,
tablet_device,
agent,
]
}
}
@@ -0,0 +1,9 @@
# Example placeholders only. Do not commit real credentials.
proxmox_endpoint = "https://pve.example.local:8006/api2/json"
proxmox_insecure = false
# Use either username/password or API token based on your chosen auth flow.
proxmox_username = "root@pam"
proxmox_password = "REPLACE_ME"
proxmox_api_token = "REPLACE_ME"
@@ -0,0 +1,37 @@
variable "proxmox_endpoint" {
description = "Proxmox API endpoint URL, for example https://pve.example.local:8006/api2/json"
type = string
default = ""
}
variable "proxmox_insecure" {
description = "Set true only for local testing with self-signed TLS; prefer false in stable environments."
type = bool
default = false
}
#variable "proxmox_username" {
# description = "Username for password-based auth (placeholder; optional if token auth is used)."
# type = string
# default = ""
#}
#variable "proxmox_password" {
# description = "Password for password-based auth (placeholder; optional if token auth is used)."
# type = string
# default = ""
# sensitive = true
#}
variable "proxmox_api_token_id" {
type = string
description = "Proxmox API token ID, e.g. terraform@pve!tf"
sensitive = true
}
variable "proxmox_api_token_secret" {
description = "API token for token-based auth (placeholder; optional if username/password is used)."
type = string
default = ""
sensitive = true
}
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.6.0"
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.68.0"
}
}
}
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE'
Usage:
reconcile_from_plan.sh [--output-file <path>] [--] [terraform plan args...]
Description:
Runs `terraform plan` with `-generate-config-out` and writes the generated
configuration into a tracked Terraform file (default:
`zz_generated_from_plan.auto.tf`).
This is designed for import-first workflows where `import { ... }` blocks are
present and Terraform can generate missing resource arguments from live
infrastructure.
Options:
--output-file <path> Destination .tf/.auto.tf file to receive generated
configuration. Default: zz_generated_from_plan.auto.tf
-h, --help Show this help text.
Examples:
./reconcile_from_plan.sh
./reconcile_from_plan.sh --output-file generated_imports.auto.tf -- -var-file=terraform.tfvars
USAGE
}
output_file="zz_generated_from_plan.auto.tf"
plan_args=()
while (($# > 0)); do
case "$1" in
--output-file)
if (($# < 2)); then
echo "error: --output-file requires a value" >&2
exit 1
fi
output_file="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
--)
shift
plan_args=("$@")
break
;;
*)
plan_args+=("$1")
shift
;;
esac
done
if ! command -v terraform >/dev/null 2>&1; then
echo "error: terraform is not installed or not in PATH" >&2
exit 1
fi
if [[ ! -f "main.tf" ]] && ! compgen -G "*.tf" >/dev/null; then
echo "error: no Terraform configuration (*.tf) found in $(pwd)" >&2
echo "run this script from a Terraform module directory" >&2
exit 1
fi
generated_tmp_dir="$(mktemp -d -t terraform-generated-XXXXXX)"
generated_tmp="$generated_tmp_dir/generated.tf"
# terraform plan -generate-config-out requires a path that does not already exist
trap 'rm -rf "$generated_tmp_dir"' EXIT
echo "Running: terraform plan -generate-config-out=$generated_tmp ${plan_args[*]-}"
set +e
terraform plan -generate-config-out="$generated_tmp" "${plan_args[@]}"
plan_exit=$?
set -e
if [[ $plan_exit -ne 0 && $plan_exit -ne 2 ]]; then
echo "error: terraform plan failed with exit code $plan_exit" >&2
exit "$plan_exit"
fi
if [[ ! -s "$generated_tmp" ]]; then
echo "No generated configuration was produced."
echo "Tip: ensure you have import blocks and resources eligible for config generation."
exit 0
fi
cat > "$output_file" <<EOF2
# -----------------------------------------------------------------------------
# AUTO-GENERATED BY reconcile_from_plan.sh
# Generated: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Source: terraform plan -generate-config-out
# Review carefully before apply.
# -----------------------------------------------------------------------------
EOF2
cat "$generated_tmp" >> "$output_file"
terraform fmt "$output_file" >/dev/null
echo "Generated configuration written to: $output_file"
echo "Next step: review this file and run terraform plan again to confirm intent."
@@ -1,6 +1,6 @@
services: services:
docker-socket-proxy: docker-socket-proxy:
profiles: ["monitoring","all","docker-socket-proxy", "core", "traefik", "prometheus", "test"] profiles: ["monitoring","all","docker-socket-proxy", "core", "traefik", "prometheus"]
image: tecnativa/docker-socket-proxy:latest image: tecnativa/docker-socket-proxy:latest
container_name: docker-socket-proxy container_name: docker-socket-proxy
hostname: docker-socket-proxy hostname: docker-socket-proxy
+6 -6
View File
@@ -355,7 +355,7 @@
"type": "function", "type": "function",
"z": "00b02bbd01c91485", "z": "00b02bbd01c91485",
"name": "Deployment Success", "name": "Deployment Success",
"func": "const attempts = flow.get(\"dockerUpdateAttempts\") || {};\n\nif (msg.updateKey && attempts[msg.updateKey]) {\n delete attempts[msg.updateKey];\n flow.set(\"dockerUpdateAttempts\", attempts);\n}\nnode.log(`Deployment Successful\n Container: ${msg.container}\n Image: ${msg.image}\n Host: ${msg.host}\n`);\n\nreturn msg;", "func": "let attempts = flow.get(\"dockerUpdateAttempts\") || {};\n\nif (msg.updateKey) {\n const existing = attempts[msg.updateKey] || {};\n attempts[msg.updateKey] = {\n ...existing,\n time: existing.time || Date.now(),\n status: \"success\",\n completedAt: Date.now(),\n notified: true\n };\n flow.set(\"dockerUpdateAttempts\", attempts);\n}\n\nnode.log(`Deployment Successful\n Container: ${msg.container}\n Image: ${msg.image}\n Host: ${msg.host}\n`);\n\nreturn msg;",
"outputs": 1, "outputs": 1,
"timeout": "", "timeout": "",
"noerr": 0, "noerr": 0,
@@ -492,8 +492,8 @@
"id": "f4b91e278109e661", "id": "f4b91e278109e661",
"type": "function", "type": "function",
"z": "00b02bbd01c91485", "z": "00b02bbd01c91485",
"name": "Repeat update Suppresed", "name": "Repeat update Suppressed",
"func": "const labels = msg.payload.alerts.labels || {};\n\nnode.warn(\n `${labels.container || \"unknown\"} ` +\n `(${labels.compose_image || labels.running_image || \"unknown image\"})`\n);\nreturn msg;", "func": "const labels = msg.payload.alerts.labels || {};\nconst container = labels.container || \"unknown\";\nconst image = labels.compose_image || labels.running_image || labels.image || \"unknown image\";\nconst status = (msg.attemptInfo && msg.attemptInfo.status) || \"unknown\";\n\nnode.warn(\n `Repeated update suppressed for ${container} (${image}). Prior status: ${status}`\n);\n\nreturn null;",
"outputs": 1, "outputs": 1,
"timeout": "", "timeout": "",
"noerr": 0, "noerr": 0,
@@ -565,7 +565,7 @@
"type": "function", "type": "function",
"z": "00b02bbd01c91485", "z": "00b02bbd01c91485",
"name": "Check Already Attempted", "name": "Check Already Attempted",
"func": "const labels = msg.payload.alerts.labels || {};\n\nconst container = labels.container;\nconst image = labels.compose_image || labels.running_image || labels.image;\nconst project = labels.com_docker_compose_project;\n\nif (!container || !image) {\n node.warn(\"Missing container/image labels; skipping update attempt tracking\");\n return [null, null];\n}\n\n// Load persistent attempt registry\nlet attempts = flow.get(\"dockerUpdateAttempts\") || {};\n\nconst host = project === \"core\" ? \"docker\" : \"raspi\";\n\n// Unique key for this exact update attempt\nconst key = `${container}|${image}|${host}`;\n\n// If we've already tried this image for this container, suppress it\nif (attempts[key]) {\n node.warn(\n `Ignoring repeated update alert for ${container} -> ${image}. ` +\n `Already attempted at ${new Date(attempts[key].time).toISOString()}`\n );\n\n msg.suppressed = true;\n msg.updateKey = key;\n msg.attemptInfo = attempts[key];\n\n return [null, msg];\n}\n\n// First time we've seen this update, record it immediately\nattempts[key] = {\n time: Date.now(),\n status: \"started\"\n};\n\nflow.set(\"dockerUpdateAttempts\", attempts);\n\nmsg.updateKey = key;\n\nnode.log(`First attempt for ${container} -> ${image}`);\n\nreturn [msg, null];", "func": "const SUCCESS_TTL_MS = 36 * 60 * 60 * 1000;\nconst now = Date.now();\n\nconst labels = msg.payload.alerts.labels || {};\n\nconst container = labels.container;\nconst image = labels.compose_image || labels.running_image || labels.image;\nconst project = labels.com_docker_compose_project;\n\nif (!container || !image) {\n node.warn(\"Missing container/image labels; skipping update attempt tracking\");\n return [null, null];\n}\n\n// Load persistent attempt registry\nlet attempts = flow.get(\"dockerUpdateAttempts\") || {};\n\n// Prune old successful records so they don't accumulate forever\nfor (const [k, v] of Object.entries(attempts)) {\n if (v && v.status === \"success\" && v.completedAt && (now - v.completedAt) > SUCCESS_TTL_MS) {\n delete attempts[k];\n }\n}\n\nconst host = project === \"core\" ? \"docker\" : \"raspi\";\n\n// Unique key for this exact update attempt\nconst key = `${container}|${image}|${host}`;\n\n// If we've already tried this image for this container, suppress it\nif (attempts[key]) {\n node.warn(\n `Ignoring repeated update alert for ${container} -> ${image}. ` +\n `Already handled with status '${attempts[key].status}' at ${new Date(attempts[key].time).toISOString()}`\n );\n\n msg.suppressed = true;\n msg.updateKey = key;\n msg.attemptInfo = attempts[key];\n\n flow.set(\"dockerUpdateAttempts\", attempts);\n\n return [null, msg];\n}\n\n// First time we've seen this update, record it immediately\nattempts[key] = {\n time: Date.now(),\n status: \"started\"\n};\n\nflow.set(\"dockerUpdateAttempts\", attempts);\n\nmsg.updateKey = key;\n\nnode.log(`First attempt for ${container} -> ${image}`);\n\nreturn [msg, null];",
"outputs": 2, "outputs": 2,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
@@ -632,7 +632,7 @@
"type": "function", "type": "function",
"z": "00b02bbd01c91485", "z": "00b02bbd01c91485",
"name": "get docker update lockouts", "name": "get docker update lockouts",
"func": "const attempts = flow.get(\"dockerUpdateAttempts\") || {};\n\nconst output = Object.entries(attempts).map(([key, value]) => ({\n key,\n status: value.status,\n firstAttempt: new Date(value.time).toISOString(),\n failedAt: value.failedAt\n ? new Date(value.failedAt).toISOString()\n : null,\n notified: !!value.notified\n}));\n\nmsg.payload = output;\nnode.log(JSON.stringify(msg.payload, null, 2));\nreturn msg;", "func": "const attempts = flow.get(\"dockerUpdateAttempts\") || {};\n\nconst output = Object.entries(attempts).map(([key, value]) => ({\n key,\n status: value.status || null,\n firstAttempt: value.time ? new Date(value.time).toISOString() : null,\n completedAt: value.completedAt ? new Date(value.completedAt).toISOString() : null,\n failedAt: value.failedAt ? new Date(value.failedAt).toISOString() : null,\n notified: !!value.notified\n}));\n\nmsg.payload = output;\nnode.log(JSON.stringify(msg.payload, null, 2));\nreturn msg;",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
@@ -869,7 +869,7 @@
"type": "function", "type": "function",
"z": "c5240b64a962ea54", "z": "c5240b64a962ea54",
"name": "Domain name alerts", "name": "Domain name alerts",
"func": "const name = msg.payload.monitor.name;\nconst hb = msg.payload.heartbeat;\n\nconst isUp = hb.status === 1;\n\nconst icon = isUp ? \"\" : \"🔴\";\nconst state = isUp ? \"UP\" : \"DOWN\";\n\n// Build a short title for the Gotify notification\nconst title = `${icon} ${name} is ${state}`;\nconst time = hb.localDateTime.split(\" \")[1].split(\":\").slice(0, 2).join(\":\");\n// Build a more detailed message\nlet message = `${icon} Monitor: ${name}\\n`;\nmessage += `Status: ${state}\\n`;\nmessage += `Time: ${time}\\n`;\nmessage += `Details: ${hb.msg}`;\n\nif (hb.ping !== undefined) {\n message += `\\nPing: ${hb.ping} ms`;\n}\n\nif (hb.duration !== undefined) {\n message += `\\nCheck Interval: ${hb.duration} sec`;\n}\n\n// Higher priority for down alerts\nmsg.payload = {\n title: title,\n message: message,\n priority: isUp ? 5 : 8\n};\n\nreturn msg;", "func": "const name = msg.payload.monitor.name;\nconst hb = msg.payload.heartbeat;\n\nconst isUp = hb.status === 1;\n\nconst icon = isUp ? \"\u2705\" : \"\ud83d\udd34\";\nconst state = isUp ? \"UP\" : \"DOWN\";\n\n// Build a short title for the Gotify notification\nconst title = `${icon} ${name} is ${state}`;\nconst time = hb.localDateTime.split(\" \")[1].split(\":\").slice(0, 2).join(\":\");\n// Build a more detailed message\nlet message = `${icon} Monitor: ${name}\\n`;\nmessage += `Status: ${state}\\n`;\nmessage += `Time: ${time}\\n`;\nmessage += `Details: ${hb.msg}`;\n\nif (hb.ping !== undefined) {\n message += `\\nPing: ${hb.ping} ms`;\n}\n\nif (hb.duration !== undefined) {\n message += `\\nCheck Interval: ${hb.duration} sec`;\n}\n\n// Higher priority for down alerts\nmsg.payload = {\n title: title,\n message: message,\n priority: isUp ? 5 : 8\n};\n\nreturn msg;",
"outputs": 1, "outputs": 1,
"timeout": 0, "timeout": 0,
"noerr": 0, "noerr": 0,
@@ -137,3 +137,308 @@
{"ts":"2026-04-14T02:30:22.079Z","flow":"docker-updates","event":"completed","container":"update-test","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""} {"ts":"2026-04-14T02:30:22.079Z","flow":"docker-updates","event":"completed","container":"update-test","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T02:31:15.896Z","flow":"docker-updates","event":"completed","container":"telegraf","project":"unknown","host":"docker","status":"failed","success":0,"failed":1,"duration_ms":0,"code":0,"error":""} {"ts":"2026-04-14T02:31:15.896Z","flow":"docker-updates","event":"completed","container":"telegraf","project":"unknown","host":"docker","status":"failed","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T02:31:15.896Z","flow":"docker-updates","event":"completed","container":"telegraf","project":"unknown","host":"docker","status":"locked","success":0,"failed":1,"duration_ms":0,"code":0,"error":""} {"ts":"2026-04-14T02:31:15.896Z","flow":"docker-updates","event":"completed","container":"telegraf","project":"unknown","host":"docker","status":"locked","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:06:16.689Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:06:48.773Z","flow":"docker-updates","event":"completed","container":"nextcloud-redis","project":"unknown","host":"docker","status":"failed","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:06:48.781Z","flow":"docker-updates","event":"completed","container":"nextcloud-redis","project":"unknown","host":"docker","status":"locked","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:07:07.846Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:11:02.306Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:12:00.541Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:16:00.956Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:17:00.656Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:20:55.223Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:21:52.064Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:25:53.292Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:26:50.450Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:30:59.645Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:31:51.975Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:35:51.577Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:36:47.627Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:40:51.544Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T07:41:47.538Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:35:51.628Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:36:47.488Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:40:51.502Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:41:47.413Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:45:51.560Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:46:47.499Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:50:51.537Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:51:47.494Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:55:51.594Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T10:56:47.565Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:01:01.763Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:01:54.859Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:05:51.596Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:06:47.566Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:10:51.565Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:11:47.456Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:15:51.472Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:16:47.879Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:20:51.537Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:21:47.564Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:25:51.637Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:26:47.433Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:30:51.528Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:31:47.465Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:35:51.549Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:36:47.462Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:40:51.546Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:41:47.437Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:45:51.531Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:46:47.390Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:50:51.546Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:51:47.483Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:55:51.592Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T11:56:47.458Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:00:51.525Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:01:47.531Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:05:51.579Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:06:47.427Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:10:51.579Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:11:47.446Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:15:51.528Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:16:47.460Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:20:51.588Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:21:47.536Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:25:51.597Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:26:47.447Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:30:51.560Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:31:47.478Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:35:51.536Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:36:47.454Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:40:51.560Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:41:47.468Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:45:51.807Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:46:47.803Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:50:51.581Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:51:47.529Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:55:51.533Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T12:56:47.461Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:00:51.675Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:01:47.911Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:05:51.526Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:06:47.941Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:10:51.535Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:11:47.450Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:15:51.578Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:16:47.468Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:20:51.736Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:21:47.477Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:25:51.549Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:26:47.487Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:30:51.521Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:31:47.415Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:35:51.564Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:36:47.548Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:40:51.563Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:41:47.448Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:45:51.540Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:46:47.422Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:50:51.591Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:51:47.462Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:55:51.763Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T13:56:47.489Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:00:52.083Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:01:48.283Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:05:52.030Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:06:48.221Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:10:52.039Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:11:48.289Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:15:51.578Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:16:47.446Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:20:51.576Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:21:47.443Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:25:51.507Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:26:47.404Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:30:51.544Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:31:47.472Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:35:51.555Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:36:47.472Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:40:51.548Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:41:47.515Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:45:51.543Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:46:47.468Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:50:51.565Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:51:47.461Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:55:51.618Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T14:56:47.507Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:00:51.615Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:01:47.437Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:05:51.546Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:06:47.501Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:10:51.528Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:11:47.451Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:15:51.983Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:16:47.892Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:20:51.480Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:21:47.345Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:25:51.552Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:26:47.435Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:30:51.674Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:31:47.526Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:35:51.542Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:36:47.422Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:40:51.594Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:41:47.507Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:45:51.542Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:46:47.501Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:50:51.565Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:51:47.441Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:55:51.588Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T15:56:47.427Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:00:51.565Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:01:47.444Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:05:51.675Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:06:47.559Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:10:51.651Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:11:47.492Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:15:51.587Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:16:47.445Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:20:51.604Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:21:47.569Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:25:51.578Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:26:47.487Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:30:51.609Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:31:47.515Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:35:51.507Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:36:47.448Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:40:51.556Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:41:47.487Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:45:51.596Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:46:47.437Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:50:51.592Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:51:47.492Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:55:51.655Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T16:56:47.484Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:00:51.746Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:01:47.778Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:05:51.560Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:06:47.485Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:10:51.600Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:11:47.434Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:15:51.578Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:16:47.416Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:20:51.597Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:21:47.516Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:25:51.910Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:26:47.734Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:30:51.572Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:31:47.432Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:35:51.767Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:36:47.810Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:40:51.588Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:41:47.521Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:45:51.709Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:46:47.854Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:50:51.720Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:51:47.652Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:55:51.596Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T17:56:47.477Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:00:51.613Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:01:47.464Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:05:51.606Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:06:47.526Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:10:51.664Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:11:47.553Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:15:51.534Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:16:47.442Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:20:51.595Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:21:47.447Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:25:51.600Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:26:47.467Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:30:51.608Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:31:47.465Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:35:51.638Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:36:48.003Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:40:51.584Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:41:47.521Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:45:51.585Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:46:47.496Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:50:51.682Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:51:47.651Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:55:51.542Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T18:56:47.476Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:00:51.635Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:01:47.730Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:05:51.556Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:06:47.497Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:10:51.560Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:11:47.470Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:15:51.550Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:16:47.426Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:20:51.554Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:21:47.473Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:25:51.616Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:26:47.998Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:30:51.584Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:31:47.499Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:35:51.591Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:36:47.465Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:40:51.580Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:41:47.419Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:45:51.738Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:46:48.231Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:50:51.585Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:51:47.554Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:55:52.004Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T19:56:47.614Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:00:51.557Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:01:48.036Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:05:51.612Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:06:47.534Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:10:51.558Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:11:47.411Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:15:51.596Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:16:47.542Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:20:51.614Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:21:47.439Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:25:51.557Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:26:47.435Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:30:51.600Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:31:47.526Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:35:51.603Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:36:47.473Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:40:51.554Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:41:47.443Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:45:51.617Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:46:47.507Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:50:51.573Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:51:47.514Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:55:51.611Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T20:56:47.491Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:00:51.692Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:01:47.580Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:05:51.750Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:06:47.974Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:10:51.675Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:11:47.590Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:15:51.666Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:16:47.557Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:20:51.633Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:21:47.522Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:25:51.668Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:26:47.828Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:28:29.097Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:29:24.810Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:29:28.971Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:33:29.156Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:34:25.049Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:38:29.178Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:39:24.976Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:40:29.198Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:41:24.871Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:45:29.318Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:46:25.370Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:50:29.226Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:51:25.260Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:55:29.161Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-14T21:56:25.104Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-15T12:35:22.769Z","flow":"docker-updates","event":"completed","container":"searxng-webapp","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-15T12:36:18.957Z","flow":"docker-updates","event":"completed","container":"prometheus","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-16T07:06:27.862Z","flow":"docker-updates","event":"completed","container":"passbolt-db","project":"unknown","host":"docker","status":"failed","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-16T07:06:27.862Z","flow":"docker-updates","event":"completed","container":"passbolt-db","project":"unknown","host":"docker","status":"locked","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-16T07:06:28.709Z","flow":"docker-updates","event":"completed","container":"nextcloud-db","project":"unknown","host":"docker","status":"failed","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-16T07:06:28.709Z","flow":"docker-updates","event":"completed","container":"nextcloud-db","project":"unknown","host":"docker","status":"locked","success":0,"failed":1,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-16T07:06:40.038Z","flow":"docker-updates","event":"completed","container":"traefik","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
{"ts":"2026-04-17T07:05:12.795Z","flow":"docker-updates","event":"completed","container":"traefik","project":"unknown","host":"raspi","status":"failed","success":0,"failed":1,"duration_ms":0,"code":1,"error":""}
{"ts":"2026-04-17T07:05:12.795Z","flow":"docker-updates","event":"completed","container":"traefik","project":"unknown","host":"raspi","status":"locked","success":0,"failed":1,"duration_ms":0,"code":1,"error":""}
{"ts":"2026-04-17T19:11:29.490Z","flow":"docker-updates","event":"completed","container":"traefik","project":"unknown","host":"docker","status":"success","success":1,"failed":0,"duration_ms":0,"code":0,"error":""}
+5
View File
@@ -109,6 +109,11 @@ scrape_configs:
- kuma.lan.ddnsgeek.com - kuma.lan.ddnsgeek.com
labels: labels:
role: raspberrypi role: raspberrypi
tls_config:
# ca_file: /prometheus/clients-ca.crt
cert_file: /prometheus/office-pc.crt
key_file: /prometheus/office-pc.key
# server_name: kuma.lan.ddnsgeek.com
# ========================= # =========================
# Proxmox Storage Exporters # Proxmox Storage Exporters
+13 -13
View File
@@ -1,13 +1,13 @@
08:07:03 INFO: === Update started: 2026-04-14 08:07:03 === 22:10:52 INFO: === Update started: 2026-04-20 22:10:52 ===
08:07:03 WARNING: Skipping traefik (directory does not exist) 22:10:52 WARNING: Skipping traefik (directory does not exist)
08:07:03 WARNING: Skipping nextcloud (directory does not exist) 22:10:52 WARNING: Skipping nextcloud (directory does not exist)
08:07:03 WARNING: Skipping passbolt (directory does not exist) 22:10:52 WARNING: Skipping passbolt (directory does not exist)
08:07:03 WARNING: Skipping searxng (directory does not exist) 22:10:52 WARNING: Skipping searxng (directory does not exist)
08:07:03 WARNING: Skipping gitea (directory does not exist) 22:10:52 WARNING: Skipping gitea (directory does not exist)
08:07:03 WARNING: Skipping gotify (directory does not exist) 22:10:52 WARNING: Skipping gotify (directory does not exist)
08:07:03 WARNING: Skipping grafana (directory does not exist) 22:10:52 WARNING: Skipping grafana (directory does not exist)
08:07:03 WARNING: Skipping gramps (directory does not exist) 22:10:52 WARNING: Skipping gramps (directory does not exist)
08:07:03 WARNING: Skipping portainer (directory does not exist) 22:10:52 WARNING: Skipping portainer (directory does not exist)
08:07:03 WARNING: Skipping prometheus (directory does not exist) 22:10:52 WARNING: Skipping prometheus (directory does not exist)
08:07:03 WARNING: Skipping uptime-kuma (directory does not exist) 22:10:52 WARNING: Skipping uptime-kuma (directory does not exist)
08:07:03 INFO: Pruning unused containers, images, networks, and volumes... 22:10:52 INFO: Pruning unused containers, images, networks, and volumes...