Add GoAccess metrics dashboard with WebSocket support

- Add GoAccess package to Docker container
- Create GoAccess startup script with real-time HTML generation
- Add metrics.ralsina.me server block with authentication
- Configure WebSocket proxy for live metrics updates
- Add password protection with .htpasswd
- Fix WebSocket URL to use proper HTTPS endpoint
- Update all server blocks to listen on 0.0.0.0:8080 for Fly.io compatibility

Co-Authored-By: z.ai LGM 4.5 <noreply@z.ai>
This commit is contained in:
2025-10-03 10:53:26 -03:00
parent 493c5528ce
commit 7b5ce1a5e8
6 changed files with 136 additions and 12 deletions

View File

@@ -0,0 +1,23 @@
{
"permissions": {
"allow": [
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(chmod:*)",
"Bash(openssl:*)",
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(pass:*)",
"Bash(docker build:*)",
"Bash(docker logs:*)",
"Bash(curl:*)",
"Bash(docker exec:*)",
"Bash(docker stop:*)",
"Bash(docker rm:*)",
"Bash(docker run:*)",
"WebSearch"
],
"deny": [],
"ask": []
}
}

1
reverse_proxy/.htpasswd Normal file
View File

@@ -0,0 +1 @@
metrics:$apr1$1xI0fBl5$bE8iEuBk9is7TdcqhuEIn.

View File

@@ -14,7 +14,7 @@ COPY . ./
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:latest FROM alpine:latest
RUN apk update && apk add --no-cache ca-certificates iptables ip6tables nginx RUN apk update && apk add --no-cache ca-certificates iptables ip6tables nginx goaccess
# Copy binary to production image # Copy binary to production image
COPY --from=builder /app/start.sh /app/start.sh COPY --from=builder /app/start.sh /app/start.sh
@@ -23,6 +23,8 @@ COPY --from=tailscale /app/tailscale /app/tailscale
RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale /usr/share/nginx/html RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale /usr/share/nginx/html
COPY nginx.conf /etc/nginx/http.d/nginx.conf COPY nginx.conf /etc/nginx/http.d/nginx.conf
COPY custom_50x.html /usr/share/nginx/html/ COPY custom_50x.html /usr/share/nginx/html/
COPY goaccess.sh /app/goaccess.sh
COPY .htpasswd /etc/nginx/.htpasswd
# Run on container startup. # Run on container startup.
EXPOSE 8080 EXPOSE 8080

49
reverse_proxy/goaccess.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/sh
# GoAccess real-time dashboard script
# Serves metrics dashboard on port 7890 with WebSocket support
echo "Starting GoAccess setup..."
# Wait for nginx to start and create logs
sleep 10
# Create log directory if it doesn't exist
mkdir -p /var/log/nginx
# Create HTML output directory
mkdir -p /usr/share/nginx/html/goaccess
# Create a dummy access log if it doesn't exist
touch /var/log/nginx/access.log
echo "Starting GoAccess..."
# Start GoAccess with real-time WebSocket support
# Remove unsupported options and use valid ones
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--real-time-html \
--ws-url=wss://metrics.ralsina.me/ws \
--daemonize \
--output=/usr/share/nginx/html/goaccess/index.html &
# Get the PID
GOACCESS_PID=$!
echo "GoAccess started with PID: $GOACCESS_PID"
# Wait a moment and check if it's still running
sleep 3
if kill -0 $GOACCESS_PID 2>/dev/null; then
echo "GoAccess is running successfully"
else
echo "GoAccess failed to start, trying static HTML method..."
# Alternative: generate static HTML every 30 seconds
while true; do
goaccess /var/log/nginx/access.log \
--log-format=COMBINED \
--output=/usr/share/nginx/html/goaccess/index.html
echo "Generated static report at $(date)"
sleep 30
done &
fi

View File

@@ -1,3 +1,4 @@
# Map for CORS
map $upstream_http_access_control_allow_origin $allow_origin { map $upstream_http_access_control_allow_origin $allow_origin {
'' "*"; '' "*";
} }
@@ -24,7 +25,7 @@ map $http_user_agent $is_unknown_ua {
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name faaso-prod.ralsina.me; server_name faaso-prod.ralsina.me;
@@ -47,7 +48,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name tocry-demo.ralsina.me; server_name tocry-demo.ralsina.me;
@@ -70,7 +71,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name grafito-demo.ralsina.me; server_name grafito-demo.ralsina.me;
@@ -93,7 +94,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name code.ralsina.me; server_name code.ralsina.me;
@@ -120,7 +121,7 @@ server {
} }
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name home.ralsina.me; server_name home.ralsina.me;
@@ -159,7 +160,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name links.ralsina.me; server_name links.ralsina.me;
@@ -184,7 +185,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name git.ralsina.me; server_name git.ralsina.me;
@@ -209,7 +210,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name gotify.ralsina.me; server_name gotify.ralsina.me;
@@ -253,7 +254,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name faas.ralsina.me; server_name faas.ralsina.me;
@@ -276,7 +277,7 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name snips.ralsina.me; server_name snips.ralsina.me;
@@ -294,7 +295,50 @@ server {
} }
server { server {
listen 8080; listen 0.0.0.0:8080;
listen [::]:8080;
server_name metrics.ralsina.me;
auth_basic "Metrics Dashboard - Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
# Serve static HTML directly
location / {
root /usr/share/nginx/html/goaccess;
try_files /index.html @goaccess;
}
location @goaccess {
proxy_pass http://127.0.0.1:7890;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
# WebSocket endpoint for GoAccess
location /ws {
proxy_pass http://127.0.0.1:7890;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
}
}
server {
listen 0.0.0.0:8080;
listen [::]:8080; listen [::]:8080;
server_name covers.ralsina.me; server_name covers.ralsina.me;

View File

@@ -2,4 +2,9 @@
/app/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock & /app/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tailscale/tailscaled.sock &
/app/tailscale up --authkey=${TAILSCALE_AUTHKEY} --hostname=reverseproxy /app/tailscale up --authkey=${TAILSCALE_AUTHKEY} --hostname=reverseproxy
# Start GoAccess real-time dashboard
/app/goaccess.sh &
# Start nginx
/usr/sbin/nginx -c /etc/nginx/nginx.conf -g 'daemon off;' /usr/sbin/nginx -c /etc/nginx/nginx.conf -g 'daemon off;'