Commit Graph
76 Commits
Author SHA1 Message Date
tiennm99 2de7bb68ab docs: record compose.yml naming convention for new services
New services take the current Compose spec filename. Existing
docker-compose.yml files stay as they are so unrelated changes do not
carry a rename.
2026-09-16 15:06:01 +07:00
tiennm99 41fe522c0d docs: point netdata related-links at sibling services 2026-08-18 16:35:19 +07:00
tiennm99 1c07109f56 docs: list all absorbed services in the services table 2026-08-18 16:22:29 +07:00
tiennm99 85b35e449d docs: give each service its own README
Move the code-server details into code-server/README.md and reduce the
root README to shared conventions plus a table linking to each service.
2026-08-14 09:25:36 +07:00
tiennm99 34591b7e27 refactor(code-server): drop Codex access token
No longer used; removes the CODEX_ACCESS_TOKEN variable from the service
definition and its example env file.
2026-08-14 09:25:24 +07:00
tiennm99 550d1d1741 feat: add code-server service and repo scaffolding
Set up the per-service layout: each service directory holds compose.yml
with a committed .env.example and a gitignored .env.

Add code-server as the first service, plus a README and CLAUDE.md
documenting that these files target Coolify/Dokploy and deliberately
omit ports and restart policies.
2026-08-14 09:13:49 +07:00
tiennm99 0ab29485cb Initial commit 2026-08-14 08:57:46 +07:00
tiennm99 7a63d20424 feat: update 2025-03-25 22:04:48 +07:00
tiennm99 d1b1654cff feat: update 2025-03-15 07:48:27 +07:00
tiennm99 bf621b5315 Update docker-compose.yml 2025-03-15 07:38:20 +07:00
tiennm99 3e58b95b6c feat: update 2025-03-15 07:34:33 +07:00
tiennm99 12529023e1 feat: update 2025-03-15 07:19:10 +07:00
tiennm99 23501a2018 Update docker-compose.yml 2025-03-15 07:16:57 +07:00
tiennm99 247bb46f78 Update docker-compose.yml 2025-03-15 07:16:19 +07:00
tiennm99 fbcfaf47d8 fix: deploy fail 2025-03-15 06:54:24 +07:00
tiennm99 6481a83d2f feat: init 2025-03-15 06:46:20 +07:00
Tien Nguyen Minh 4148e42d36 Initial commit 2025-03-15 06:43:06 +07:00
tiennm99 df94b9f400 Clear and rewrite
Retire the initial setup; history continues from tastyigniter-docker-compose.
2026-08-04 22:51:17 +07:00
Tien Nguyen Minh b840934d09 [Add] sample docker-compose.yml 2024-11-30 11:33:17 +00:00
Tien Nguyen Minh 2079313d70 Initial commit 2024-11-30 18:25:45 +07:00
tiennm99 83e15050e3 Clear and rewrite
Retire the docker-run setup; history continues from traffmonetizer-docker-compose.
2026-08-04 22:42:34 +07:00
tiennm99 44d3d75546 fix: run tea outside git work tree so --login is honored
Invoke-Tea started its job in the caller's directory. When that is a git
work tree, tea infers the target from the local remote, and a remote that
matches no configured login makes it discard --login, fall back to the
first login, and fail with "remote repository required". Pin the job to a
neutral directory so the requested login always resolves.
2026-08-01 20:33:56 +07:00
tiennm99 0134b64cde feat: add gitea mirror maintenance skill
Adds a skill to audit the local Gitea mirror stack for repos whose pull
failed, then clean up only what is safe to delete.

Detection combines four signals, since none is sufficient alone: the Gitea
API (empty repos with no completed initial pull), an upstream reachability
probe, the mirror app database, and the gitea container log. The container
log reflects a retention window rather than history, so it is never the
sole basis for deletion.

Deletion is gated on a contradiction between Gitea and the mirror app:
a repo that is empty while the app records the pull as finished. Repos the
app is still cloning or has queued look identical by API fields alone
(empty, zero size, no mirror timestamp), so they are excluded to avoid
destroying work in progress. Repos that still hold content are reported
for retry and never deleted, so a transient fetch error cannot cost a
mirror.

Deleting a broken repo also resets its mirror-app row to pending;
without that the app never re-pulls it and the mirror is lost instead of
restored. Cleanup is dry-run by default and warns on a stale plan.
2026-07-26 19:43:50 +07:00
tiennm99 2a3c5ad89f chore: always pull latest gitea-mirror image 2026-07-25 23:51:02 +07:00
tiennm99 21de313dec docs: add README and sample environment values
Document the compose services, published ports, volumes, and first-run
setup. Fill .env.example with sample values and note that compose.yml
does not yet consume them.
2026-07-25 18:45:18 +07:00
tiennm99 25aba88d0c chore: add gitea mirror docker compose setup
Compose stack for Gitea with Postgres and gitea-mirror, plus an
environment template listing the required configuration keys.
2026-07-25 18:08:56 +07:00
tiennm99 872d9ba5ea fix: bump alloy to v1.16.1 and align CI validator image 2026-05-31 10:41:57 +07:00
tiennm99 bad7082ac3 docs(readme): add customization section and related cluster links 2026-05-11 21:45:31 +07:00
tiennm99 2752b8fb5a docs: expand README — features table, GPU notes, smoke test 2026-05-11 20:44:53 +07:00
tiennm99 28cf2bd1f9 docs: flesh out README 2026-05-11 20:15:20 +07:00
tiennm99 6e79c6851d docs: add README 2026-05-11 17:04:17 +07:00
tiennm99 40d7b0e3fc fix: ship cadvisor working_set/rss metrics so memory panels reflect real usage
container_memory_usage_bytes counts page cache attributed to the cgroup,
which makes disk-heavy containers (e.g. gitea) appear to use ~all host RAM.
Add container_memory_working_set_bytes (the metric Grafana's Docker
integration dashboard expects), plus container_memory_rss,
container_memory_cache, and container_spec_memory_limit_bytes for
breakdown and limit-percentage panels.
2026-04-29 09:59:19 +07:00
tiennm99 2a24eaf10b fix: drop explicit journal path and bump alloy to v1.16.0
`loki.source.journal "default"` no longer pins `path = "/var/log/journal"`.
Upstream omits the field, which lets Alloy default to BOTH
`/var/log/journal` (persistent) and `/run/log/journal` (volatile). The
explicit path silently dropped journal logs on hosts with volatile-only
storage. Matches the canonical Linux Node integration template.

Also bumps the image six minor versions to current stable. Doc records
the 2026-04-26 re-audit.
2026-04-26 10:15:29 +07:00
tiennm99 9399a8b115 feat: keep-list verbatim from each integration's Metrics section
Copies the exact 157-metric list from the Linux Node integration's
Metrics anchor as the cadvisor keep-list already does for Docker
(16 metrics). Replaces the earlier `drop node_scrape_collector_.+`
rule, which was the integration page's alternate snippet but didn't
ship the explicit allowlist users see in the docs.

`instance:node_num_cpu:sum` from the Metrics section is intentionally
omitted — it's a recording-rule output computed server-side by
Grafana Cloud's ruler, not produced by the agent.

Doc + README updated to point at the Metrics anchors directly so the
source of truth is unambiguous.
2026-04-26 09:54:43 +07:00
tiennm99 c1db79a359 docs: codify upstream-sources-only rule for config decisions
Adds docs/upstream-sources-of-truth.md as the binding policy for what
this repo follows when deciding metrics, labels, log pipelines, and
dashboards to ship.

Hard rule: only tier 1-4 official sources (Grafana Cloud integration
docs, github.com/grafana/*, github.com/prometheus/*, the user's own
authenticated Grafana Cloud API). No third-party Terraform exports,
community gists, blog posts, or AI summaries — even when names match.

Records a tier-1+2 audit confirming the current cadvisor allowlist
matches both the Docker integration page and grafana/jsonnet-libs
docker-mixin/docker.json. Notes that tier-4 verification against the
live stack's full integration dashboard set was not performed and is
the only known gap.
2026-04-26 09:50:20 +07:00
tiennm99 54ab1fed27 feat: align metric/log collection with upstream Grafana Cloud integrations
Linux-Node integration:
- replace curated keep-list of ~140 node_* metrics with the upstream
  drop rule (drops only node_scrape_collector_*); ships the full
  ~130+ metric set the integration dashboards expect.
- add loki.source.file for /var/log/{syslog,messages,*.log} alongside
  the existing journal scrape, matching the upstream config.
- broaden the /var/log mount to cover both pipelines (was journal only).

Docker integration:
- drop container_memory_working_set_bytes from the cadvisor allowlist;
  not part of the documented metric set.

README: refresh "What it collects" + "Mounts" tables, document the
syslog-vs-journald duplication caveat for rsyslog hosts.
2026-04-26 09:24:44 +07:00
tiennm99 fd8cf058b2 docs: add Coolify SSH session spam runbook
Document a Coolify-specific noise pattern observed in the journal
pipeline: ~300 root sessions/hour from the Coolify host's connection
checks. Verified against coollabsio/coolify v4.x source (Kernel.php,
ServerManagerJob, ServerCheckJob, SshMultiplexingHelper).

Includes:
- exact call flow and skip conditions per Coolify source
- triage commands and key-fingerprint matcher
- two mitigations: drop at Alloy (loki.process stage.drop) or enable
  Sentinel server-side to bypass the SSH polling entirely
- framing: Coolify-only, base setup unchanged
2026-04-26 09:21:11 +07:00
tiennm99 513f688ea0 ci: bind alloy smoke test to real port (clustering needs non-zero) 2026-04-25 19:13:22 +07:00
tiennm99 b1911c0538 ci: make alloy smoke-test robust to runtime errors
Previous step failed in CI because the bare alloy container had no
/var/log/journal, no docker.sock, etc., so loki.source.journal +
discovery.docker exited the process — and --rm wiped the container
before logs could be inspected.

Now: drop --rm, mount the same host paths the prod compose uses, plus
an empty /var/log/journal stand-in. Capture logs unconditionally and
fail only on config-level patterns ('unknown component',
'undefined reference', 'syntax error', etc.). Runtime/component
failures against dummy endpoints are tolerated.
2026-04-25 19:12:05 +07:00
tiennm99 8a7f156487 fix: address review findings (network ns, journal path, CI semantics)
- network_mode: host so prometheus.exporter.unix reports real host
  interfaces (eth0...) rather than the alloy container's veth pair.
- loki.source.journal: set path = "/var/log/journal" explicitly so it
  doesn't silently fall through to /run/log/journal on volatile-journal
  hosts.
- cadvisor keep-list: add container_memory_working_set_bytes (drives
  several panels on the standard Docker dashboard).
- Drop /dev/kmsg device + extra_hosts:host.docker.internal — neither is
  needed by the current keep-lists, and host-network mode makes the
  extra_hosts entry meaningless.
- CI: extend Alloy validation beyond `fmt` (syntax-only) by booting
  alloy with the embedded config and asserting it stays running, which
  catches bad component refs / wrong arg names that fmt accepts.
- README: refresh Mounts table + Security note to match.
2026-04-25 19:09:49 +07:00
tiennm99 fed5d6f8c7 fix: point node_exporter at host bind mounts; drop pid:host
prometheus.exporter.unix now reads /rootproc and /rootfs (the existing
host bind mounts) instead of the container's own namespace, so the
filesystem + process metrics actually describe the host. This makes
pid:host unnecessary, so remove it — privileged is enough and pid:host
exposes every host process inside the container.
2026-04-25 11:20:03 +07:00
tiennm99 a63d142b53 feat: update cadvisor keep-list and add pid:host + machine-id mount
cadvisor regex: drop fs_inodes/fs_limit/network_tcp_usage; add fs_reads
+ fs_writes + network_(receive|transmit)_(errors|packets_dropped)_total
to match the standard Grafana Cloud docker integration dashboard.

Compose:
- pid: host so prometheus.exporter.unix sees host /proc (cpu, mem,
  load, processes) instead of the container's namespace.
- mount /etc/machine-id so loki.source.journal has a stable host id.
2026-04-25 11:16:13 +07:00
tiennm99 ac4c785053 ci: add REMOTECFG_* dummy vars so compose config passes
The compose file gained three new :?required guards
(REMOTECFG_URL/ID/USER) that the validate workflow was not exporting.
2026-04-25 10:51:16 +07:00
tiennm99 94c63452eb feat: merge linux+docker alloy configs and source creds from env
Embed unified config.alloy via compose configs, combining node_exporter
+ journal (linux) and cadvisor + docker logs (docker) collectors into one
container. Add remotecfg block for grafana fleet-management. Replace
hardcoded credentials with sys.env() reads of nine shell variables
(ALLOY_HOSTNAME, REMOTECFG_*, PROM_*, LOKI_*, GRAFANA_TOKEN).
2026-04-25 10:49:07 +07:00
tiennm99 f009b37ca0 fix: pass /dev/kmsg via devices: so cgroup allows the read
bind-mounting /dev/kmsg under volumes: creates the node but leaves the
device-cgroup controller blocking the read (EPERM). cap_drop=[ALL]
clears the default device allow-list, so even with CAP_SYSLOG the
kernel refuses. moving it under devices: adds the cgroup allow rule
alongside the bind-mount, which is what cadvisor actually needs.
2026-04-24 14:35:40 +07:00
tiennm99 9ca8c2a65b fix: mount /dev/kmsg and /run/udev/data for cadvisor + diskstats
clears two startup warnings:
 - cadvisor "Could not configure a source for OOM detection" — needs
   /dev/kmsg bind-mount and CAP_SYSLOG (kernel.dmesg_restrict=1 default)
 - node-exporter "Failed to open /run/udev/data" — diskstats collector
   enriches node_disk_* with model/serial/WWN labels from udev

both mounted read-only. CAP_SYSLOG added alongside DAC_OVERRIDE.
2026-04-24 14:24:00 +07:00
tiennm99 01261b18b0 fix: drop docker logs older than 6d before sending to loki
grafana cloud loki rejects entries older than 7 days with HTTP 400.
loki.source.docker has no "tail since" option, so on first start it
replays logs from each container's start time — long-running
containers (coolify-proxy, traffmonetizer) produced weeks of backlog
that loki refused to ingest.

insert a loki.process drop stage (older_than=144h) between the docker
source and loki.write.gc so stale entries are filtered before egress.
journal source already bounded by max_age=12h — no filter needed there.
2026-04-24 14:20:50 +07:00
tiennm99 59bf58a412 fix: grant DAC_OVERRIDE so alloy can write its data dir
container runs as root (0:0) but cap_drop=[ALL] stripped DAC_OVERRIDE,
so mkdir on /var/lib/alloy/data (alloy-owned in the image) failed with
permission denied. add it back (only DAC_OVERRIDE, nothing else) and
mount /etc/machine-id ro for a stable journal host id. annotate every
volume with the component that uses it.
2026-04-24 13:56:37 +07:00
tiennm99 fe7e48bf19 chore: switch license from mit to apache 2.0
fetched via gh api /licenses/apache-2.0 (github-official template).
2026-04-24 09:59:09 +07:00
tiennm99 1a894935d1 fix: expand one-line rule blocks (river requires newline-separated attrs)
caught by new ci — alloy fmt rejected `rule { a = b c = d }` on one line.
river/flow config language requires each attribute on its own line.
2026-04-24 09:55:15 +07:00