Update configs (gcloud)
This commit is contained in:
parent
63d9363ca9
commit
10a7103c4a
20
.env.example
20
.env.example
|
|
@ -1,20 +0,0 @@
|
||||||
# ---- Port Bindings ----
|
|
||||||
PROMETHEUS_PORT=9390
|
|
||||||
ALERTMANAGER_PORT=9043
|
|
||||||
LOKI_PORT=4100
|
|
||||||
NODE_EXPORTER_PORT=9112
|
|
||||||
DOCKER_EXPORTER_PORT=9487
|
|
||||||
PIHOLE_WEB_PORT=8040
|
|
||||||
PIHOLE_DNS_PORT=53
|
|
||||||
PIHOLE_HTTPS_PORT=443
|
|
||||||
|
|
||||||
# ---- Pihole Config ----
|
|
||||||
PIHOLE_PASSWORD=
|
|
||||||
TZ=America/Toronto
|
|
||||||
WEBPASSWORD=
|
|
||||||
|
|
||||||
# ---- Alertmanager ----
|
|
||||||
DISCORD_WEBHOOK=
|
|
||||||
|
|
||||||
# ---- Metadata ----
|
|
||||||
HOSTNAME=
|
|
||||||
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
.env
|
|
||||||
node_modules
|
|
||||||
124
README.md
124
README.md
|
|
@ -1,124 +0,0 @@
|
||||||
# 🧠 Infrastructure Usage Guide
|
|
||||||
|
|
||||||
This guide explains how to use the new Docker-based infrastructure stack deployed on **Unraid**, **Raspberry Pi**, and **Ubuntu**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Starting the Monitoring Stack
|
|
||||||
|
|
||||||
Each machine has a `start.sh` wrapper script that:
|
|
||||||
- Runs `docker compose up -d`
|
|
||||||
- Waits a few seconds for container readiness
|
|
||||||
- Logs container IPs, ports, and web URLs
|
|
||||||
|
|
||||||
To start:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x start.sh
|
|
||||||
./start.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📜 Service Overview
|
|
||||||
|
|
||||||
The following services are deployed (excluding Pi-hole on Ubuntu):
|
|
||||||
|
|
||||||
| Service | Unraid | Pi | Ubuntu |
|
|
||||||
|------------------|--------|----|-------|
|
|
||||||
| Grafana | ✅ | ❌ | ❌ |
|
|
||||||
| Prometheus | ✅ | ✅ | ✅ |
|
|
||||||
| Loki | ✅ | ✅ | ✅ |
|
|
||||||
| Promtail | ✅ | ✅ | ✅ |
|
|
||||||
| Alertmanager | ✅ | ✅ | ✅ |
|
|
||||||
| Node Exporter | ✅ | ✅ | ✅ |
|
|
||||||
| Docker Exporter | ✅ | ✅ | ✅ |
|
|
||||||
| NGINX | ✅ | ❌ | ❌ |
|
|
||||||
| Pi-hole | ❌ | ✅ | ❌ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 Defining IPs in Pi-hole
|
|
||||||
|
|
||||||
Pi-hole is used for internal DNS routing of your infrastructure services.
|
|
||||||
|
|
||||||
1. Open the **Pi-hole Admin Panel**
|
|
||||||
2. Go to **Local DNS > DNS Records**
|
|
||||||
3. Add A records like:
|
|
||||||
|
|
||||||
```
|
|
||||||
grafana.wyvern.bray.io -> 192.168.2.16
|
|
||||||
prometheus.unraid.bray.io -> 192.168.2.28
|
|
||||||
```
|
|
||||||
|
|
||||||
> 💡 You can verify entries with `dig grafana.wyvern.bray.io`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 Defining IPs in NGINX
|
|
||||||
|
|
||||||
NGINX is used to expose internal services via friendly URLs (e.g. `https://grafana.wyvern.bray.io`).
|
|
||||||
|
|
||||||
1. Go to: `configs/nginx/conf.d/`
|
|
||||||
2. Create or modify `.conf` files like:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
server_name grafana.wyvern.bray.io;
|
|
||||||
|
|
||||||
ssl_certificate /etc/nginx/ssl/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://192.168.2.16:3000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Reload NGINX (or restart the container):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker restart nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Adding New Services
|
|
||||||
|
|
||||||
1. Add a new service to `docker-compose.yml`
|
|
||||||
2. Assign a static IP if needed
|
|
||||||
3. Add a DNS record in Pi-hole
|
|
||||||
4. Add a reverse proxy entry in NGINX
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧼 Resetting the Stack
|
|
||||||
|
|
||||||
You can bring down and rebuild everything:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose down
|
|
||||||
docker compose up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
This will recreate containers with preserved volumes. If you wipe volumes, services will reset.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Final Tip: Keep a Network Sheet
|
|
||||||
|
|
||||||
Keep a `infra-ip-map.md` or spreadsheet like:
|
|
||||||
|
|
||||||
| Container | Host | Static IP | Port | Domain |
|
|
||||||
|----------------|---------|----------------|------|-----------------------------------|
|
|
||||||
| Grafana | Unraid | 192.168.2.16 | 3000 | grafana.wyvern.bray.io |
|
|
||||||
| Prometheus | Pi | 192.168.2.28 | 9090 | prometheus.pi.bray.io |
|
|
||||||
| Loki | Ubuntu | 192.168.2.26 | 3100 | loki.ubuntu.bray.io |
|
|
||||||
| ... | ... | ... | ... | ... |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Happy hacking 🛠️
|
|
||||||
124
docs.md
124
docs.md
|
|
@ -1,124 +0,0 @@
|
||||||
# 🧠 Infrastructure Usage Guide
|
|
||||||
|
|
||||||
This guide explains how to use the new Docker-based infrastructure stack deployed on **Unraid**, **Raspberry Pi**, and **Ubuntu**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Starting the Monitoring Stack
|
|
||||||
|
|
||||||
Each machine has a `start.sh` wrapper script that:
|
|
||||||
- Runs `docker compose up -d`
|
|
||||||
- Waits a few seconds for container readiness
|
|
||||||
- Logs container IPs, ports, and web URLs
|
|
||||||
|
|
||||||
To start:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x start.sh
|
|
||||||
./start.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📜 Service Overview
|
|
||||||
|
|
||||||
The following services are deployed (excluding Pi-hole on Ubuntu):
|
|
||||||
|
|
||||||
| Service | Unraid | Pi | Ubuntu |
|
|
||||||
|------------------|--------|----|-------|
|
|
||||||
| Grafana | ✅ | ❌ | ❌ |
|
|
||||||
| Prometheus | ✅ | ✅ | ✅ |
|
|
||||||
| Loki | ✅ | ✅ | ✅ |
|
|
||||||
| Promtail | ✅ | ✅ | ✅ |
|
|
||||||
| Alertmanager | ✅ | ✅ | ✅ |
|
|
||||||
| Node Exporter | ✅ | ✅ | ✅ |
|
|
||||||
| Docker Exporter | ✅ | ✅ | ✅ |
|
|
||||||
| NGINX | ✅ | ❌ | ❌ |
|
|
||||||
| Pi-hole | ❌ | ✅ | ❌ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 Defining IPs in Pi-hole
|
|
||||||
|
|
||||||
Pi-hole is used for internal DNS routing of your infrastructure services.
|
|
||||||
|
|
||||||
1. Open the **Pi-hole Admin Panel**
|
|
||||||
2. Go to **Local DNS > DNS Records**
|
|
||||||
3. Add A records like:
|
|
||||||
|
|
||||||
```
|
|
||||||
grafana.wyvern.bray.io -> 192.168.2.16
|
|
||||||
prometheus.unraid.bray.io -> 192.168.2.28
|
|
||||||
```
|
|
||||||
|
|
||||||
> 💡 You can verify entries with `dig grafana.wyvern.bray.io`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🌐 Defining IPs in NGINX
|
|
||||||
|
|
||||||
NGINX is used to expose internal services via friendly URLs (e.g. `https://grafana.wyvern.bray.io`).
|
|
||||||
|
|
||||||
1. Go to: `configs/nginx/conf.d/`
|
|
||||||
2. Create or modify `.conf` files like:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
server_name grafana.wyvern.bray.io;
|
|
||||||
|
|
||||||
ssl_certificate /etc/nginx/ssl/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://192.168.2.16:3000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Reload NGINX (or restart the container):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker restart nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Adding New Services
|
|
||||||
|
|
||||||
1. Add a new service to `docker-compose.yml`
|
|
||||||
2. Assign a static IP if needed
|
|
||||||
3. Add a DNS record in Pi-hole
|
|
||||||
4. Add a reverse proxy entry in NGINX
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧼 Resetting the Stack
|
|
||||||
|
|
||||||
You can bring down and rebuild everything:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose down
|
|
||||||
docker compose up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
This will recreate containers with preserved volumes. If you wipe volumes, services will reset.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Final Tip: Keep a Network Sheet
|
|
||||||
|
|
||||||
Keep a `infra-ip-map.md` or spreadsheet like:
|
|
||||||
|
|
||||||
| Container | Host | Static IP | Port | Domain |
|
|
||||||
|----------------|---------|----------------|------|-----------------------------------|
|
|
||||||
| Grafana | Unraid | 192.168.2.16 | 3000 | grafana.wyvern.bray.io |
|
|
||||||
| Prometheus | Pi | 192.168.2.28 | 9090 | prometheus.pi.bray.io |
|
|
||||||
| Loki | Ubuntu | 192.168.2.26 | 3100 | loki.ubuntu.bray.io |
|
|
||||||
| ... | ... | ... | ... | ... |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Happy hacking 🛠️
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
FROM node:18-alpine
|
|
||||||
WORKDIR /app
|
|
||||||
COPY . .
|
|
||||||
RUN npm install
|
|
||||||
CMD ["node", "server.js"]
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
infra-api:
|
|
||||||
image: node:18
|
|
||||||
container_name: infra-api
|
|
||||||
working_dir: /app
|
|
||||||
volumes:
|
|
||||||
- ./:/app
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
command: >
|
|
||||||
sh -c "npm install && node server.js"
|
|
||||||
ports:
|
|
||||||
- "8686:8686"
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=production
|
|
||||||
network_mode: ${USE_HOST_NETWORK}
|
|
||||||
1444
infra-api/package-lock.json
generated
1444
infra-api/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"dockerode": "^4.0.6",
|
|
||||||
"express": "^5.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const { getContainerData } = require('../utils/dockerInspector');
|
|
||||||
const os = require('os');
|
|
||||||
|
|
||||||
router.get('/', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const containers = await getContainerData();
|
|
||||||
const hostInterfaces = os.networkInterfaces();
|
|
||||||
const ip =
|
|
||||||
hostInterfaces.en0?.find(i => i.family === 'IPv4')?.address ||
|
|
||||||
hostInterfaces.eth0?.find(i => i.family === 'IPv4')?.address ||
|
|
||||||
'127.0.0.1';
|
|
||||||
|
|
||||||
const rows = containers
|
|
||||||
.map(c => {
|
|
||||||
const [host, container] = c.name.split('-', 2);
|
|
||||||
if (!host || !container) return null;
|
|
||||||
|
|
||||||
const safeContainer = container.replace(/_/g, '');
|
|
||||||
const safeHost = host.replace(/_/g, '');
|
|
||||||
const hasPorts = c.ports && c.ports.length > 0;
|
|
||||||
const url = hasPorts ? `${ip}:${c.ports[0]}` : null;
|
|
||||||
const domain = `${safeContainer}.${safeHost}.bray.io`;
|
|
||||||
|
|
||||||
if (!url) return null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: safeContainer,
|
|
||||||
url,
|
|
||||||
domain,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
// Create a pretty text table
|
|
||||||
const header = `NAME | URL | DOMAIN`;
|
|
||||||
const divider = `--------------------|------------------------|-----------------------------`;
|
|
||||||
const lines = rows.map(row =>
|
|
||||||
`${row.name.padEnd(20)}| ${row.url.padEnd(24)}| ${row.domain}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const output = [header, divider, ...lines].join('\n');
|
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'text/plain');
|
|
||||||
res.send(output);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error building domain list:', err);
|
|
||||||
res.status(500).send('Failed to generate domain mappings');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
const express = require('express');
|
|
||||||
const os = require('os');
|
|
||||||
const { getContainerData } = require('./utils/dockerInspector');
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
const PORT = process.env.PORT || 8686;
|
|
||||||
const hostname = os.hostname().toLowerCase(); // used in domain mapping
|
|
||||||
|
|
||||||
// Endpoint to list all containers and their info
|
|
||||||
app.get('/containers', async (req, res) => {
|
|
||||||
try {
|
|
||||||
const containers = await getContainerData();
|
|
||||||
res.setHeader('Content-Type', 'application/json');
|
|
||||||
res.send(JSON.stringify(containers, null, 2)); // Pretty print JSON
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error fetching containers:', err);
|
|
||||||
res.status(500).send('Internal Server Error');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const domainRoutes = require('./routes/domains');
|
|
||||||
app.use('/domains', domainRoutes);
|
|
||||||
|
|
||||||
// Start server
|
|
||||||
app.listen(8686, '0.0.0.0', () => {
|
|
||||||
console.log('Infra API listening at http://localhost:8686');
|
|
||||||
});
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
const Docker = require('dockerode');
|
|
||||||
const os = require('os');
|
|
||||||
|
|
||||||
const docker = new Docker();
|
|
||||||
|
|
||||||
// Helper to detect the host IP (e.g. 192.168.x.x)
|
|
||||||
function getHostIP() {
|
|
||||||
const interfaces = os.networkInterfaces();
|
|
||||||
for (const iface of Object.values(interfaces)) {
|
|
||||||
for (const net of iface) {
|
|
||||||
if (net.family === 'IPv4' && !net.internal && net.address.startsWith('192.')) {
|
|
||||||
return net.address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 'localhost'; // Fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getContainerData() {
|
|
||||||
const containers = await docker.listContainers({ all: true });
|
|
||||||
const hostname = os.hostname();
|
|
||||||
const hostIp = getHostIP();
|
|
||||||
|
|
||||||
const output = [];
|
|
||||||
|
|
||||||
for (const containerInfo of containers) {
|
|
||||||
const container = docker.getContainer(containerInfo.Id);
|
|
||||||
const inspect = await container.inspect();
|
|
||||||
|
|
||||||
const rawName = inspect.Name || containerInfo.Names?.[0] || '';
|
|
||||||
const name = rawName.replace(/^\//, '');
|
|
||||||
|
|
||||||
const networks = inspect.NetworkSettings.Networks || {};
|
|
||||||
let staticIP = null;
|
|
||||||
|
|
||||||
// Try to find a meaningful internal Docker-assigned static IP
|
|
||||||
for (const netName in networks) {
|
|
||||||
const ip = networks[netName].IPAddress;
|
|
||||||
if (ip && (ip.startsWith('192.') || ip.startsWith('10.'))) {
|
|
||||||
staticIP = ip;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rawPorts = Object.values(inspect.NetworkSettings.Ports || {})
|
|
||||||
.flat()
|
|
||||||
.filter(Boolean);
|
|
||||||
const ports = rawPorts.map(p => p.HostPort);
|
|
||||||
|
|
||||||
// Prefer static IP if available, fallback to host IP
|
|
||||||
let url = '(none)';
|
|
||||||
if (ports.length > 0) {
|
|
||||||
const accessIP = staticIP || hostIp;
|
|
||||||
url = `http://${accessIP}:${ports[0]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
output.push({
|
|
||||||
name,
|
|
||||||
ip: staticIP || 'N/A',
|
|
||||||
ports,
|
|
||||||
hostname,
|
|
||||||
url,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { getContainerData };
|
|
||||||
26
monitoring/docker-compose.yml
Normal file
26
monitoring/docker-compose.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
services:
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:latest
|
||||||
|
container_name: prometheus
|
||||||
|
volumes:
|
||||||
|
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
|
- prometheus_data:/prometheus
|
||||||
|
command:
|
||||||
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||||
|
- '--storage.tsdb.path=/prometheus'
|
||||||
|
ports:
|
||||||
|
- "9090:9090"
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:latest
|
||||||
|
container_name: grafana
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- grafana_data:/var/lib/grafana
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
prometheus_data:
|
||||||
|
grafana_data:
|
||||||
30
monitoring/prometheus/prometheus.yml
Normal file
30
monitoring/prometheus/prometheus.yml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
evaluation_interval: 15s
|
||||||
|
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'mystic-infrastructure'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['100.109.59.41:9100']
|
||||||
|
labels:
|
||||||
|
instance: 'mystic-database'
|
||||||
|
role: 'database'
|
||||||
|
env: 'prod'
|
||||||
|
|
||||||
|
- targets: ['100.120.171.124:9100']
|
||||||
|
labels:
|
||||||
|
instance: 'mystic-passwords'
|
||||||
|
role: 'vault'
|
||||||
|
env: 'prod'
|
||||||
|
|
||||||
|
- targets: ['100.98.158.31:9100']
|
||||||
|
labels:
|
||||||
|
instance: 'mystic-git'
|
||||||
|
role: 'git'
|
||||||
|
env: 'prod'
|
||||||
|
|
||||||
|
- targets: ['100.80.179.128:9100']
|
||||||
|
labels:
|
||||||
|
instance: 'mystic-cloud'
|
||||||
|
role: 'monitoring'
|
||||||
|
env: 'prod'
|
||||||
16
nodes/docker-compose.node.yml
Normal file
16
nodes/docker-compose.node.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
services:
|
||||||
|
node-exporter:
|
||||||
|
image: prom/node-exporter:latest
|
||||||
|
container_name: node-exporter
|
||||||
|
volumes:
|
||||||
|
- /proc:/host/proc:ro
|
||||||
|
- /sys:/host/sys:ro
|
||||||
|
- /:/rootfs:ro
|
||||||
|
command:
|
||||||
|
- '--path.procfs=/host/proc'
|
||||||
|
- '--path.rootfs=/rootfs'
|
||||||
|
- '--path.sysfs=/host/sys'
|
||||||
|
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
|
||||||
|
ports:
|
||||||
|
- "9100:9100"
|
||||||
|
restart: unless-stopped
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Stage 1: Pull original Alertmanager binary
|
|
||||||
FROM prom/alertmanager:latest as upstream
|
|
||||||
|
|
||||||
# Stage 2: Alpine + envsubst
|
|
||||||
FROM alpine:latest
|
|
||||||
|
|
||||||
# Install envsubst and ca-certificates
|
|
||||||
RUN apk add --no-cache gettext ca-certificates
|
|
||||||
|
|
||||||
# Create directories
|
|
||||||
RUN mkdir -p /etc/alertmanager /alertmanager
|
|
||||||
|
|
||||||
# Copy Alertmanager binary from upstream
|
|
||||||
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
|
||||||
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
|
||||||
|
|
||||||
# Default config will be overwritten by volume mount
|
|
||||||
ENTRYPOINT ["/bin/sh", "-c"]
|
|
||||||
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
auth_enabled: false
|
|
||||||
|
|
||||||
server:
|
|
||||||
http_listen_port: 3100
|
|
||||||
grpc_listen_port: 9095
|
|
||||||
|
|
||||||
ingester:
|
|
||||||
lifecycler:
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
replication_factor: 1
|
|
||||||
chunk_idle_period: 5m
|
|
||||||
chunk_retain_period: 30s
|
|
||||||
wal:
|
|
||||||
dir: /loki/wal
|
|
||||||
|
|
||||||
limits_config:
|
|
||||||
reject_old_samples: true
|
|
||||||
reject_old_samples_max_age: 168h
|
|
||||||
allow_structured_metadata: false
|
|
||||||
|
|
||||||
schema_config:
|
|
||||||
configs:
|
|
||||||
- from: 2024-01-01
|
|
||||||
store: boltdb-shipper
|
|
||||||
object_store: filesystem
|
|
||||||
schema: v12
|
|
||||||
index:
|
|
||||||
prefix: index_
|
|
||||||
period: 24h
|
|
||||||
|
|
||||||
storage_config:
|
|
||||||
boltdb_shipper:
|
|
||||||
active_index_directory: /loki/index
|
|
||||||
cache_location: /loki/cache
|
|
||||||
filesystem:
|
|
||||||
directory: /loki/chunks
|
|
||||||
|
|
||||||
ruler:
|
|
||||||
storage:
|
|
||||||
type: local
|
|
||||||
local:
|
|
||||||
directory: /loki/rules
|
|
||||||
rule_path: /loki/rules-temp
|
|
||||||
alertmanager_url: http://localhost:9093
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
enable_api: true
|
|
||||||
|
|
||||||
compactor:
|
|
||||||
working_directory: /loki/compactor
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
- job_name: 'node_exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9100']
|
|
||||||
|
|
||||||
- job_name: 'docker_exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9487']
|
|
||||||
|
|
||||||
- job_name: 'pi_services'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:3100', 'localhost:9093']
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
positions:
|
|
||||||
/var/log/acroUpdaterTools.log: "16567"
|
|
||||||
/var/log/alf.log: "0"
|
|
||||||
/var/log/fsck_apfs.log: "23880"
|
|
||||||
/var/log/fsck_apfs_error.log: "676"
|
|
||||||
/var/log/fsck_hfs.log: "4044"
|
|
||||||
/var/log/install.log: "3856377"
|
|
||||||
/var/log/shutdown_monitor.log: "1971"
|
|
||||||
/var/log/system.log: "6579"
|
|
||||||
/var/log/wifi.log: "1164834"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
server:
|
|
||||||
http_listen_port: 9080
|
|
||||||
grpc_listen_port: 0
|
|
||||||
|
|
||||||
positions:
|
|
||||||
filename: /etc/promtail/positions.yaml
|
|
||||||
|
|
||||||
clients:
|
|
||||||
- url: http://loki:3100/loki/api/v1/push
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: system
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- localhost
|
|
||||||
labels:
|
|
||||||
job: varlogs
|
|
||||||
__path__: /var/log/*.log
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
services:
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:latest
|
|
||||||
container_name: ${HOSTNAME}-prometheus
|
|
||||||
ports:
|
|
||||||
- "${PROMETHEUS_PORT}:9090"
|
|
||||||
volumes:
|
|
||||||
- ./configs/prometheus:/etc/prometheus
|
|
||||||
- prometheus-data:/prometheus
|
|
||||||
command:
|
|
||||||
- --config.file=/etc/prometheus/prometheus.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
alertmanager:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.alertmanager
|
|
||||||
container_name: ${HOSTNAME}-alertmanager
|
|
||||||
ports:
|
|
||||||
- "${ALERTMANAGER_PORT}:9093"
|
|
||||||
volumes:
|
|
||||||
- ./configs/alertmanager:/etc/alertmanager
|
|
||||||
environment:
|
|
||||||
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
loki:
|
|
||||||
image: grafana/loki:latest
|
|
||||||
container_name: ${HOSTNAME}-loki
|
|
||||||
ports:
|
|
||||||
- "${LOKI_PORT}:3100"
|
|
||||||
volumes:
|
|
||||||
- ./configs/loki:/etc/loki
|
|
||||||
- loki-data:/loki
|
|
||||||
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
promtail:
|
|
||||||
image: grafana/promtail:latest
|
|
||||||
container_name: ${HOSTNAME}-promtail
|
|
||||||
volumes:
|
|
||||||
- /var/log:/var/log:ro
|
|
||||||
- ./configs/promtail:/etc/promtail
|
|
||||||
command: -config.file=/etc/promtail/promtail.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
node_exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: ${HOSTNAME}-node_exporter
|
|
||||||
ports:
|
|
||||||
- "${NODE_EXPORTER_PORT}:9100"
|
|
||||||
command:
|
|
||||||
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
docker_exporter:
|
|
||||||
image: prometheusnet/docker_exporter
|
|
||||||
container_name: ${HOSTNAME}-docker_exporter
|
|
||||||
ports:
|
|
||||||
- "${DOCKER_EXPORTER_PORT}:9487"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
pihole:
|
|
||||||
image: pihole/pihole:latest
|
|
||||||
container_name: ${HOSTNAME}-pihole
|
|
||||||
hostname: ${HOSTNAME}
|
|
||||||
ports:
|
|
||||||
- "${PIHOLE_WEB_PORT}:80"
|
|
||||||
- "${PIHOLE_HTTPS_PORT}:443"
|
|
||||||
- "${PIHOLE_DNS_PORT}:53/udp"
|
|
||||||
environment:
|
|
||||||
TZ: ${TZ}
|
|
||||||
WEBPASSWORD: ${WEBPASSWORD}
|
|
||||||
volumes:
|
|
||||||
- pihole-config:/etc/pihole
|
|
||||||
- dnsmasq-config:/etc/dnsmasq.d
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prometheus-data:
|
|
||||||
loki-data:
|
|
||||||
pihole-config:
|
|
||||||
dnsmasq-config:
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Optional base hostname (e.g., monitor.local)
|
|
||||||
BASE_HOST="${NGINX_HOST:-localhost}"
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
|
||||||
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
for container in $(docker ps --format '{{.Names}}'); do
|
|
||||||
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
|
||||||
|
|
||||||
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
|
||||||
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
|
||||||
|
|
||||||
if [ -z "$ports" ]; then
|
|
||||||
ports="(none)"
|
|
||||||
url="(none)"
|
|
||||||
else
|
|
||||||
# Just use the first port for URL
|
|
||||||
first_port=$(echo "$ports" | cut -d',' -f1)
|
|
||||||
scheme="http"
|
|
||||||
[ "$first_port" = "443" ] && scheme="https"
|
|
||||||
url="$scheme://$BASE_HOST:$first_port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
|
||||||
done
|
|
||||||
16
pi/start.sh
16
pi/start.sh
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🚀 Starting monitoring stack..."
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Failed to start containers. Check docker-compose logs."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🔍 Gathering service info:"
|
|
||||||
./stack-status.sh
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Stage 1: Pull original Alertmanager binary
|
|
||||||
FROM prom/alertmanager:latest as upstream
|
|
||||||
|
|
||||||
# Stage 2: Alpine + envsubst
|
|
||||||
FROM alpine:latest
|
|
||||||
|
|
||||||
# Install envsubst and ca-certificates
|
|
||||||
RUN apk add --no-cache gettext ca-certificates
|
|
||||||
|
|
||||||
# Create directories
|
|
||||||
RUN mkdir -p /etc/alertmanager /alertmanager
|
|
||||||
|
|
||||||
# Copy Alertmanager binary from upstream
|
|
||||||
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
|
||||||
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
|
||||||
|
|
||||||
# Default config will be overwritten by volume mount
|
|
||||||
ENTRYPOINT ["/bin/sh", "-c"]
|
|
||||||
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
auth_enabled: false
|
|
||||||
|
|
||||||
server:
|
|
||||||
http_listen_port: 3100
|
|
||||||
grpc_listen_port: 9095
|
|
||||||
|
|
||||||
ingester:
|
|
||||||
lifecycler:
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
replication_factor: 1
|
|
||||||
chunk_idle_period: 5m
|
|
||||||
chunk_retain_period: 30s
|
|
||||||
wal:
|
|
||||||
dir: /loki/wal
|
|
||||||
|
|
||||||
limits_config:
|
|
||||||
reject_old_samples: true
|
|
||||||
reject_old_samples_max_age: 168h
|
|
||||||
allow_structured_metadata: false
|
|
||||||
|
|
||||||
schema_config:
|
|
||||||
configs:
|
|
||||||
- from: 2024-01-01
|
|
||||||
store: boltdb-shipper
|
|
||||||
object_store: filesystem
|
|
||||||
schema: v12
|
|
||||||
index:
|
|
||||||
prefix: index_
|
|
||||||
period: 24h
|
|
||||||
|
|
||||||
storage_config:
|
|
||||||
boltdb_shipper:
|
|
||||||
active_index_directory: /loki/index
|
|
||||||
cache_location: /loki/cache
|
|
||||||
filesystem:
|
|
||||||
directory: /loki/chunks
|
|
||||||
|
|
||||||
ruler:
|
|
||||||
storage:
|
|
||||||
type: local
|
|
||||||
local:
|
|
||||||
directory: /loki/rules
|
|
||||||
rule_path: /loki/rules-temp
|
|
||||||
alertmanager_url: http://localhost:9093
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
enable_api: true
|
|
||||||
|
|
||||||
compactor:
|
|
||||||
working_directory: /loki/compactor
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
- job_name: 'node_exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9100']
|
|
||||||
|
|
||||||
- job_name: 'docker_exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9487']
|
|
||||||
|
|
||||||
- job_name: 'pi_services'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:3100', 'localhost:9093']
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
positions:
|
|
||||||
/var/log/acroUpdaterTools.log: "16567"
|
|
||||||
/var/log/alf.log: "0"
|
|
||||||
/var/log/fsck_apfs.log: "23880"
|
|
||||||
/var/log/fsck_apfs_error.log: "676"
|
|
||||||
/var/log/fsck_hfs.log: "4044"
|
|
||||||
/var/log/install.log: "3856377"
|
|
||||||
/var/log/shutdown_monitor.log: "1971"
|
|
||||||
/var/log/system.log: "6579"
|
|
||||||
/var/log/wifi.log: "1164834"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
server:
|
|
||||||
http_listen_port: 9080
|
|
||||||
grpc_listen_port: 0
|
|
||||||
|
|
||||||
positions:
|
|
||||||
filename: /etc/promtail/positions.yaml
|
|
||||||
|
|
||||||
clients:
|
|
||||||
- url: http://loki:3100/loki/api/v1/push
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: system
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- localhost
|
|
||||||
labels:
|
|
||||||
job: varlogs
|
|
||||||
__path__: /var/log/*.log
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
services:
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:latest
|
|
||||||
container_name: ${HOSTNAME}-prometheus
|
|
||||||
ports:
|
|
||||||
- "${PROMETHEUS_PORT}:9090"
|
|
||||||
volumes:
|
|
||||||
- ./configs/prometheus:/etc/prometheus
|
|
||||||
- prometheus-data:/prometheus
|
|
||||||
command:
|
|
||||||
- --config.file=/etc/prometheus/prometheus.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
alertmanager:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.alertmanager
|
|
||||||
container_name: ${HOSTNAME}-alertmanager
|
|
||||||
ports:
|
|
||||||
- "${ALERTMANAGER_PORT}:9093"
|
|
||||||
volumes:
|
|
||||||
- ./configs/alertmanager:/etc/alertmanager
|
|
||||||
environment:
|
|
||||||
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
loki:
|
|
||||||
image: grafana/loki:latest
|
|
||||||
container_name: ${HOSTNAME}-loki
|
|
||||||
ports:
|
|
||||||
- "${LOKI_PORT}:3100"
|
|
||||||
volumes:
|
|
||||||
- ./configs/loki:/etc/loki
|
|
||||||
- loki-data:/loki
|
|
||||||
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
promtail:
|
|
||||||
image: grafana/promtail:latest
|
|
||||||
container_name: ${HOSTNAME}-promtail
|
|
||||||
volumes:
|
|
||||||
- /var/log:/var/log:ro
|
|
||||||
- ./configs/promtail:/etc/promtail
|
|
||||||
command: -config.file=/etc/promtail/promtail.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
node_exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: ${HOSTNAME}-node_exporter
|
|
||||||
ports:
|
|
||||||
- "${NODE_EXPORTER_PORT}:9100"
|
|
||||||
command:
|
|
||||||
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
docker_exporter:
|
|
||||||
image: prometheusnet/docker_exporter
|
|
||||||
container_name: ${HOSTNAME}-docker_exporter
|
|
||||||
ports:
|
|
||||||
- "${DOCKER_EXPORTER_PORT}:9487"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prometheus-data:
|
|
||||||
loki-data:
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Optional base hostname (e.g., monitor.local)
|
|
||||||
BASE_HOST="${NGINX_HOST:-localhost}"
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
|
||||||
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
for container in $(docker ps --format '{{.Names}}'); do
|
|
||||||
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
|
||||||
|
|
||||||
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
|
||||||
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
|
||||||
|
|
||||||
if [ -z "$ports" ]; then
|
|
||||||
ports="(none)"
|
|
||||||
url="(none)"
|
|
||||||
else
|
|
||||||
# Just use the first port for URL
|
|
||||||
first_port=$(echo "$ports" | cut -d',' -f1)
|
|
||||||
scheme="http"
|
|
||||||
[ "$first_port" = "443" ] && scheme="https"
|
|
||||||
url="$scheme://$BASE_HOST:$first_port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
|
||||||
done
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🚀 Starting monitoring stack..."
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Failed to start containers. Check docker-compose logs."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🔍 Gathering service info:"
|
|
||||||
./stack-status.sh
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Stage 1: Pull original Alertmanager binary
|
|
||||||
FROM prom/alertmanager:latest as upstream
|
|
||||||
|
|
||||||
# Stage 2: Alpine + envsubst
|
|
||||||
FROM alpine:latest
|
|
||||||
|
|
||||||
# Install envsubst and ca-certificates
|
|
||||||
RUN apk add --no-cache gettext ca-certificates
|
|
||||||
|
|
||||||
# Create directories
|
|
||||||
RUN mkdir -p /etc/alertmanager /alertmanager
|
|
||||||
|
|
||||||
# Copy Alertmanager binary from upstream
|
|
||||||
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
|
||||||
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
|
||||||
|
|
||||||
# Default config will be overwritten by volume mount
|
|
||||||
ENTRYPOINT ["/bin/sh", "-c"]
|
|
||||||
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
auth_enabled: false
|
|
||||||
|
|
||||||
server:
|
|
||||||
http_listen_port: 3100
|
|
||||||
grpc_listen_port: 9095
|
|
||||||
|
|
||||||
ingester:
|
|
||||||
lifecycler:
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
replication_factor: 1
|
|
||||||
chunk_idle_period: 5m
|
|
||||||
chunk_retain_period: 30s
|
|
||||||
wal:
|
|
||||||
dir: /loki/wal
|
|
||||||
|
|
||||||
limits_config:
|
|
||||||
reject_old_samples: true
|
|
||||||
reject_old_samples_max_age: 168h
|
|
||||||
allow_structured_metadata: false
|
|
||||||
|
|
||||||
schema_config:
|
|
||||||
configs:
|
|
||||||
- from: 2024-01-01
|
|
||||||
store: boltdb-shipper
|
|
||||||
object_store: filesystem
|
|
||||||
schema: v12
|
|
||||||
index:
|
|
||||||
prefix: index_
|
|
||||||
period: 24h
|
|
||||||
|
|
||||||
storage_config:
|
|
||||||
boltdb_shipper:
|
|
||||||
active_index_directory: /loki/index
|
|
||||||
cache_location: /loki/cache
|
|
||||||
filesystem:
|
|
||||||
directory: /loki/chunks
|
|
||||||
|
|
||||||
ruler:
|
|
||||||
storage:
|
|
||||||
type: local
|
|
||||||
local:
|
|
||||||
directory: /loki/rules
|
|
||||||
rule_path: /loki/rules-temp
|
|
||||||
alertmanager_url: http://localhost:9093
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
enable_api: true
|
|
||||||
|
|
||||||
compactor:
|
|
||||||
working_directory: /loki/compactor
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
global:
|
|
||||||
scrape_interval: 15s
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: 'prometheus'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9090']
|
|
||||||
|
|
||||||
- job_name: 'node_exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9100']
|
|
||||||
|
|
||||||
- job_name: 'docker_exporter'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:9487']
|
|
||||||
|
|
||||||
- job_name: 'pi_services'
|
|
||||||
static_configs:
|
|
||||||
- targets: ['localhost:3100', 'localhost:9093']
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
positions:
|
|
||||||
/var/log/alf.log: "0"
|
|
||||||
/var/log/fsck_apfs.log: "23880"
|
|
||||||
/var/log/fsck_apfs_error.log: "676"
|
|
||||||
/var/log/fsck_hfs.log: "4044"
|
|
||||||
/var/log/install.log: "3800109"
|
|
||||||
/var/log/shutdown_monitor.log: "1971"
|
|
||||||
/var/log/system.log: "6069"
|
|
||||||
/var/log/wifi.log: "1107090"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
server:
|
|
||||||
http_listen_port: 9080
|
|
||||||
grpc_listen_port: 0
|
|
||||||
|
|
||||||
positions:
|
|
||||||
filename: /etc/promtail/positions.yaml
|
|
||||||
|
|
||||||
clients:
|
|
||||||
- url: http://loki:3100/loki/api/v1/push
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: system
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- localhost
|
|
||||||
labels:
|
|
||||||
job: varlogs
|
|
||||||
__path__: /var/log/*.log
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
services:
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:latest
|
|
||||||
container_name: ${HOSTNAME}-prometheus
|
|
||||||
ports:
|
|
||||||
- "${PROMETHEUS_PORT}:9090"
|
|
||||||
volumes:
|
|
||||||
- ./configs/prometheus:/etc/prometheus
|
|
||||||
- prometheus-data:/prometheus
|
|
||||||
command:
|
|
||||||
- --config.file=/etc/prometheus/prometheus.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
alertmanager:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.alertmanager
|
|
||||||
container_name: ${HOSTNAME}-alertmanager
|
|
||||||
ports:
|
|
||||||
- "${ALERTMANAGER_PORT}:9093"
|
|
||||||
volumes:
|
|
||||||
- ./configs/alertmanager:/etc/alertmanager
|
|
||||||
environment:
|
|
||||||
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
loki:
|
|
||||||
image: grafana/loki:latest
|
|
||||||
container_name: ${HOSTNAME}-loki
|
|
||||||
ports:
|
|
||||||
- "${LOKI_PORT}:3100"
|
|
||||||
volumes:
|
|
||||||
- ./configs/loki:/etc/loki
|
|
||||||
- loki-data:/loki
|
|
||||||
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
promtail:
|
|
||||||
image: grafana/promtail:latest
|
|
||||||
container_name: ${HOSTNAME}-promtail
|
|
||||||
volumes:
|
|
||||||
- /var/log:/var/log:ro
|
|
||||||
- ./configs/promtail:/etc/promtail
|
|
||||||
command: -config.file=/etc/promtail/promtail.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
node_exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: ${HOSTNAME}-node_exporter
|
|
||||||
ports:
|
|
||||||
- "${NODE_EXPORTER_PORT}:9100"
|
|
||||||
command:
|
|
||||||
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
docker_exporter:
|
|
||||||
image: prometheusnet/docker_exporter
|
|
||||||
container_name: ${HOSTNAME}-docker_exporter
|
|
||||||
ports:
|
|
||||||
- "${DOCKER_EXPORTER_PORT}:9487"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
prometheus-data:
|
|
||||||
loki-data:
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Optional base hostname (e.g., monitor.local)
|
|
||||||
BASE_HOST="${NGINX_HOST:-localhost}"
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
|
||||||
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
for container in $(docker ps --format '{{.Names}}'); do
|
|
||||||
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
|
||||||
|
|
||||||
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
|
||||||
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
|
||||||
|
|
||||||
if [ -z "$ports" ]; then
|
|
||||||
ports="(none)"
|
|
||||||
url="(none)"
|
|
||||||
else
|
|
||||||
# Just use the first port for URL
|
|
||||||
first_port=$(echo "$ports" | cut -d',' -f1)
|
|
||||||
scheme="http"
|
|
||||||
[ "$first_port" = "443" ] && scheme="https"
|
|
||||||
url="$scheme://$BASE_HOST:$first_port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
|
||||||
done
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🚀 Starting monitoring stack..."
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Failed to start containers. Check docker-compose logs."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🔍 Gathering service info:"
|
|
||||||
./stack-status.sh
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Stage 1: Pull original Alertmanager binary
|
|
||||||
FROM prom/alertmanager:latest as upstream
|
|
||||||
|
|
||||||
# Stage 2: Alpine + envsubst
|
|
||||||
FROM alpine:latest
|
|
||||||
|
|
||||||
# Install envsubst and ca-certificates
|
|
||||||
RUN apk add --no-cache gettext ca-certificates
|
|
||||||
|
|
||||||
# Create directories
|
|
||||||
RUN mkdir -p /etc/alertmanager /alertmanager
|
|
||||||
|
|
||||||
# Copy Alertmanager binary from upstream
|
|
||||||
COPY --from=upstream /bin/alertmanager /bin/alertmanager
|
|
||||||
COPY --from=upstream /etc/alertmanager /etc/alertmanager
|
|
||||||
|
|
||||||
# Default config will be overwritten by volume mount
|
|
||||||
ENTRYPOINT ["/bin/sh", "-c"]
|
|
||||||
CMD ["envsubst < /etc/alertmanager/alertmanager.template.yml > /etc/alertmanager/alertmanager.yml && /bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml"]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: '${DISCORD_ALERT_WEBHOOK}'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
|
|
||||||
route:
|
|
||||||
receiver: 'discord'
|
|
||||||
group_wait: 10s
|
|
||||||
group_interval: 30s
|
|
||||||
repeat_interval: 1h
|
|
||||||
|
|
||||||
receivers:
|
|
||||||
- name: 'discord'
|
|
||||||
webhook_configs:
|
|
||||||
- url: 'https://discord.com/api/webhooks/1367657026280226907/vRMRq22mikrAAJerUBAcxWPbRgZeY5fF3YE_3u0fZnGCEzNIPot36fBLP7yZ4i55IMSz'
|
|
||||||
send_resolved: true
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
auth_enabled: false
|
|
||||||
|
|
||||||
server:
|
|
||||||
http_listen_port: 3100
|
|
||||||
grpc_listen_port: 9095
|
|
||||||
|
|
||||||
ingester:
|
|
||||||
lifecycler:
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
replication_factor: 1
|
|
||||||
chunk_idle_period: 5m
|
|
||||||
chunk_retain_period: 30s
|
|
||||||
wal:
|
|
||||||
dir: /loki/wal
|
|
||||||
|
|
||||||
limits_config:
|
|
||||||
reject_old_samples: true
|
|
||||||
reject_old_samples_max_age: 168h
|
|
||||||
allow_structured_metadata: false
|
|
||||||
|
|
||||||
schema_config:
|
|
||||||
configs:
|
|
||||||
- from: 2024-01-01
|
|
||||||
store: boltdb-shipper
|
|
||||||
object_store: filesystem
|
|
||||||
schema: v12
|
|
||||||
index:
|
|
||||||
prefix: index_
|
|
||||||
period: 24h
|
|
||||||
|
|
||||||
storage_config:
|
|
||||||
boltdb_shipper:
|
|
||||||
active_index_directory: /loki/index
|
|
||||||
cache_location: /loki/cache
|
|
||||||
filesystem:
|
|
||||||
directory: /loki/chunks
|
|
||||||
|
|
||||||
ruler:
|
|
||||||
storage:
|
|
||||||
type: local
|
|
||||||
local:
|
|
||||||
directory: /loki/rules
|
|
||||||
rule_path: /loki/rules-temp
|
|
||||||
alertmanager_url: http://localhost:9093
|
|
||||||
ring:
|
|
||||||
kvstore:
|
|
||||||
store: inmemory
|
|
||||||
enable_api: true
|
|
||||||
|
|
||||||
compactor:
|
|
||||||
working_directory: /loki/compactor
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
server:
|
|
||||||
http_listen_port: 9080
|
|
||||||
grpc_listen_port: 0
|
|
||||||
|
|
||||||
positions:
|
|
||||||
filename: /tmp/positions.yaml
|
|
||||||
|
|
||||||
clients:
|
|
||||||
- url: http://loki:3100/loki/api/v1/push
|
|
||||||
|
|
||||||
scrape_configs:
|
|
||||||
- job_name: system
|
|
||||||
static_configs:
|
|
||||||
- targets:
|
|
||||||
- localhost
|
|
||||||
labels:
|
|
||||||
job: varlogs
|
|
||||||
__path__: /var/log/*.log
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
version: "3.8"
|
|
||||||
|
|
||||||
services:
|
|
||||||
alertmanager:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.alertmanager
|
|
||||||
container_name: ${HOSTNAME}-alertmanager
|
|
||||||
ports:
|
|
||||||
- "9093:9093"
|
|
||||||
volumes:
|
|
||||||
- ./configs/alertmanager:/etc/alertmanager
|
|
||||||
environment:
|
|
||||||
- DISCORD_ALERT_WEBHOOK=${DISCORD_ALERT_WEBHOOK}
|
|
||||||
restart: unless-stopped
|
|
||||||
grafana:
|
|
||||||
image: grafana/grafana:latest
|
|
||||||
container_name: ${HOSTNAME}-grafana
|
|
||||||
ports:
|
|
||||||
- "${GRAFANA_PORT}:3000"
|
|
||||||
environment:
|
|
||||||
- GF_SECURITY_ADMIN_USER=${GRAFANA_USER}
|
|
||||||
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASS}
|
|
||||||
volumes:
|
|
||||||
- ./configs/grafana:/etc/grafana
|
|
||||||
- grafana-data:/var/lib/grafana
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
prometheus:
|
|
||||||
image: prom/prometheus:latest
|
|
||||||
container_name: ${HOSTNAME}-prometheus
|
|
||||||
ports:
|
|
||||||
- "${PROMETHEUS_PORT}:9090"
|
|
||||||
volumes:
|
|
||||||
- ./configs/prometheus:/etc/prometheus
|
|
||||||
- prometheus-data:/prometheus
|
|
||||||
command:
|
|
||||||
- --config.file=/etc/prometheus/prometheus.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
loki:
|
|
||||||
image: grafana/loki:latest
|
|
||||||
container_name: ${HOSTNAME}-loki
|
|
||||||
ports:
|
|
||||||
- "${LOKI_PORT}:3100"
|
|
||||||
volumes:
|
|
||||||
- ./configs/loki:/etc/loki
|
|
||||||
- loki-data:/loki
|
|
||||||
command: ["-config.file=/etc/loki/loki-config.yml", "-config.expand-env=true"]
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
promtail:
|
|
||||||
image: grafana/promtail:latest
|
|
||||||
container_name: ${HOSTNAME}-promtail
|
|
||||||
volumes:
|
|
||||||
- /var/log:/var/log:ro
|
|
||||||
- ./configs/promtail:/etc/promtail
|
|
||||||
command: -config.file=/etc/promtail/promtail.yml
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
docker_exporter:
|
|
||||||
image: prometheusnet/docker_exporter
|
|
||||||
container_name: ${HOSTNAME}-docker_exporter
|
|
||||||
ports:
|
|
||||||
- "${DOCKER_EXPORTER_PORT}:9487"
|
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
node_exporter:
|
|
||||||
image: prom/node-exporter:latest
|
|
||||||
container_name: ${HOSTNAME}-node_exporter
|
|
||||||
ports:
|
|
||||||
- "${NODE_EXPORTER_PORT}:9100"
|
|
||||||
command:
|
|
||||||
- --web.listen-address=:${NODE_EXPORTER_PORT}
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
nginx:
|
|
||||||
image: nginx:latest
|
|
||||||
container_name: ${HOSTNAME}-nginx
|
|
||||||
ports:
|
|
||||||
- "${NGINX_HTTP_PORT}:80"
|
|
||||||
- "${NGINX_HTTPS_PORT}:443"
|
|
||||||
volumes:
|
|
||||||
- ./configs/nginx:/etc/nginx/conf.d
|
|
||||||
- ./configs/nginx/ssl:/etc/nginx/ssl
|
|
||||||
- ./configs/nginx/html:/usr/share/nginx/html
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
grafana-data:
|
|
||||||
prometheus-data:
|
|
||||||
loki-data:
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Optional base hostname (e.g., monitor.local)
|
|
||||||
BASE_HOST="${NGINX_HOST:-localhost}"
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "Service" "IP Address" "Port Bindings" "URL"
|
|
||||||
printf "%s\n" "---------------------------------------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
for container in $(docker ps --format '{{.Names}}'); do
|
|
||||||
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container")
|
|
||||||
|
|
||||||
ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{if $conf}}{{$conf | json}}{{end}}{{end}}' "$container" \
|
|
||||||
| jq -r '.[] | "\(.HostPort)"' 2>/dev/null | paste -sd "," -)
|
|
||||||
|
|
||||||
if [ -z "$ports" ]; then
|
|
||||||
ports="(none)"
|
|
||||||
url="(none)"
|
|
||||||
else
|
|
||||||
# Just use the first port for URL
|
|
||||||
first_port=$(echo "$ports" | cut -d',' -f1)
|
|
||||||
scheme="http"
|
|
||||||
[ "$first_port" = "443" ] && scheme="https"
|
|
||||||
url="$scheme://$BASE_HOST:$first_port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf "%-20s | %-15s | %-25s | %-40s\n" "$container" "$ip" "$ports" "$url"
|
|
||||||
done
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "🚀 Starting monitoring stack..."
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Failed to start containers. Check docker-compose logs."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Containers started. Waiting a few seconds for services to boot..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "🔍 Gathering service info:"
|
|
||||||
./stack-status.sh
|
|
||||||
Loading…
Reference in a new issue