Traefik, Goaccess, and Systemd
Looking to make use of GoAccess for analytics behind Traefik proxy and have these running via Systemd services. The following snippets of configs etc may be of help.
With the user of Traefik
for the proxy, enable the Access Logs configuration and set the filePath
option.
If you have multiple websites on the server and you want to track them separately (running their own instance of GoAccess) then you can setup a Systemd
service that pipes the access logs to a separate log file for GoAccess
to process for each of the websites.
For example;
/etc/systemd/system/multi-user.target.wants/example-analytics-filter.service
[Unit]
Description=Filter Example Access Logs
[Service]
Type=simple
ExecStart=/bin/sh -c '/usr/bin/tail -f /var/log/traefik/access.log | \
grep -i --line-buffered "\-example\-"'
KillMode=mixed
StandardOutput=file:/opt/goaccess/data/access_example.log
Restart=always
PrivateTmp=false
[Install]
WantedBy=multi-user.target
This service is continuously processing the Traefik
access log file and updating the /opt/goaccess/data/access_example.log
file. We will use this file as the log file for GoAccess
to process.
Now create a GoAccess
service file for each instance;
/etc/systemd/system/multi-user.target.wants/example-analytics.service
[Unit]
Description=Example Live Log Analyzer
After=example-analytics-filter.service
[Service]
Type=simple
ExecStart=/usr/local/bin/goaccess \
--log-file /opt/goaccess/data/access_example.log \
--log-format COMMON \
--html-report-title "Example Statistics" \
--port 7891 \
--ws-url example.com:7890 \
--real-time-html \
--output /home/www/example/analytics/index.html \
--geoip-database /opt/goaccess/geoip/GeoLite2-City.mmdb \
--db-path /opt/goaccess/data/example \
--persist \
--restore
ExecStop=/bin/kill -9 ${MAINPID}
PrivateTmp=false
Restart=always
[Install]
WantedBy=multi-user.target
Seeing that we want to be flexible to have multiple GoAccess
instances running for each site, we set the --port
option to a different value for each instance, in this instance it is --port 7891
, the next instance can be --port 7892
etc. For the --ws-url
option we just need to change the domain name to match each website, but keep the same port number (7890
) for each instance.
Lastly we have have the Traefik
configuration to proxy everything.
In the static configuration file we have the following;
/etc/traefik/traefik.toml
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web-secure]
address = ":443"
[entryPoints.analytics]
address = ":7890"
[providers]
[providers.file]
directory = "/etc/traefik/conf.d"
watch = true
[certificatesResolvers.letsencrypt.acme]
email = "certs@example.com"
storage = "acme.json"
[certificatesResolvers.letsencrypt.acme.httpChallenge]
entryPoint = "web"
[accessLog]
filePath = "/var/log/traefik/access.log"
We have some middlewares we want to make use of;
/etc/traefik/conf.d/middleware.toml
http]
[http.middlewares]
[http.middlewares.https-redirect.redirectScheme]
scheme = "https"
permanent = true
realm = "example.com"
[http.middlewares.ssl-header.headers]
[http.middlewares.ssl-header.headers.customRequestHeaders]
X-Forwarded-Proto = "https"
Then for each website instance we have running;
/etc/traefik/conf.d/example.toml
[http]
[http.routers]
[http.routers.http-example-router]
entryPoints = ["web"]
service = "service-example"
rule = "Host(`example.com`,`www.example.com`)"
middlewares = ["https-redirect"]
[http.routers.analytics-example-router]
entryPoints = ["analytics"]
service = "service-analytics-example"
rule = "Host(`example.com`,`www.example.com`)"
middlewares = ["ssl-header"]
[http.routers.analytics-example-router.tls]
certResolver = "letsencrypt"
[[http.routers.analytics-example-router.tls.domains]]
main = "example.com"
sans = ["www.example.com"]
[http.routers.https-example-router]
entryPoints = ["web-secure"]
service = "service-example"
rule = "Host(`example.com`,`www.example.com`)"
[http.routers.https-example-router.tls]
certResolver = "letsencrypt"
[[http.routers.https-example-router.tls.domains]]
main = "example.com"
sans = ["www.example.com"]
[http.services]
[http.services.service-example]
[http.services.service-example.loadBalancer]
[[http.services.service-example.loadBalancer.servers]]
url = "http://127.0.0.1:3000"
[http.services.service-analytics-example]
[http.services.service-analytics-example.loadBalancer]
[[http.services.service-analytics-example.loadBalancer.servers]]
url = "http://127.0.0.1:7891"
What is not showng in this solution is the service that is running at http://127.0.0.1:3000
that is serving upthe relevant files for the example website.
In the example configurations above it is expected that the service running at http://127.0.0.1:3000
will serve the /home/www/example/analytics/index.html
when prompted with the path /analytics
.