Skip to content

Commit

Permalink
add grafana, graphite-api, go-carbon, collectd-docker
Browse files Browse the repository at this point in the history
a bunch of metric related services. All running on a new 'metrics'
network to facilitate easy linking between each other
  • Loading branch information
joemiller committed Mar 20, 2017
1 parent ec1383e commit 3f4d308
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 32 deletions.
167 changes: 137 additions & 30 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,51 @@
# 4. implement build_CONTAINER and create_CONTAINER tasks

# config
SABNZBD_IMAGE = joemiller/sabnzbd
SONARR_IMAGE = joemiller/sonarr
DELUGE_IMAGE = joemiller/deluge
PLEX_IMAGE = joemiller/plex
PLEXPY_IMAGE = linuxserver/plexpy
COUCHPOTATO_IMAGE = linuxserver/couchpotato
TIMECAPSULE_IMAGE = joemiller/timecapsule
MUXIMUX_IMAGE = linuxserver/muximux

CONTAINERS = sabnzbd sonarr deluge plex plexpy couchpotato timecapsule muximux
SABNZBD_IMAGE = joemiller/sabnzbd
SONARR_IMAGE = joemiller/sonarr
DELUGE_IMAGE = joemiller/deluge
PLEX_IMAGE = joemiller/plex
PLEXPY_IMAGE = linuxserver/plexpy
TIMECAPSULE_IMAGE = joemiller/timecapsule
MUXIMUX_IMAGE = linuxserver/muximux
GO_CARBON_IMAGE = joemiller/go-carbon
GRAPHITE_API_IMAGE = brutasse/graphite-api
GRAFANA_IMAGE = grafana/grafana
COLLECTD_DOCKER_IMAGE = bobrik/collectd-docker

CONTAINERS = sabnzbd sonarr deluge plex plexpy timecapsule muximux go-carbon graphite-api grafana collectd-docker

## network definitions
## TODO: refactor this into something a little cleaner

# A docker network will be created for containers (such as 'timecapsule') that require
# their own IP address on the local network (similar to a VM in bridge networking mode).
NETWORK_NAME=localnet-v6only
NETWORK_IFACE=br0
# NOTE: --subnet=2001::0/64 is a "dummy" network. This is required for docker 1.12.4+ which requires a
# --subnet if --ipv6 is specified. Your network should use IPv6 SLAAC so that the container will
# automatically acquire an ipv6 address from the real local subnet.
NETWORK_CREATE_CMD=docker network create -d macvlan --ipv6 --subnet=2001::0/64 -o parent=$(NETWORK_IFACE) $(NETWORK_NAME)
NETWORK_NAME=localnet-v6only
NETWORK_IFACE=br0
NETWORK_CREATE_CMD=docker network create --driver=macvlan \
--ipv6 --subnet=2001::0/64 \
-o parent=$(NETWORK_IFACE) \
$(NETWORK_NAME)

# a user-defined bridge network to connect metrics containers (go-carbon, graphite-api, grafana)
# together since --link is deprecated.
METRICS_NETWORK_NAME=metrics
METRICS_NETWORK_CREATE_CMD=docker network create --driver=bridge \
--subnet=192.168.1.0/24 --gateway=192.168.1.1 \
$(METRICS_NETWORK_NAME)

#TODO: setup go-carbon image, setup graphite-api image, setup grafana image
#TODO: move metrics to /virt or leave in /etc/go-carbon/data?

# helper tasks
_configure_network:
_configure_networks:
@docker network inspect $(NETWORK_NAME) >/dev/null 2>&1 || $(NETWORK_CREATE_CMD)
@docker network inspect $(METRICS_NETWORK_NAME) >/dev/null 2>&1 || $(METRICS_NETWORK_CREATE_CMD)

_remove_network:
_remove_networks:
docker network rm $(NETWORK_NAME)

# aggregate tasks
Expand All @@ -51,17 +71,23 @@ build_sabnzbd: ## build the sabnzbd container

create_sabnzbd: ## create and start the sabnzbd container
docker run -d --name sabnzbd --restart=always \
-l collectd_docker_app=sabnzbd \
-l collectd_docker_task=sabnzbd \
-p 8085:8085 \
-v /files:/files \
-v /etc/sabnzbd:/config \
$(SABNZBD_IMAGE)

# TODO: implement upgrade_sabnzbd

# sonarr
build_sonarr: ## build the sonarr container
docker build -t $(SONARR_IMAGE) --pull=true --no-cache=true sonarr

create_sonarr: ## create and start the sonarr container
docker run -d --name sonarr --restart=always \
-l collectd_docker_app=sonarr \
-l collectd_docker_task=sonarr \
-e XDG_CONFIG_HOME=/config \
-p 8989:8989 \
-v /files:/files \
Expand All @@ -79,13 +105,20 @@ build_deluge: ## build the deluge container

create_deluge: ## create and start the deluge container
docker run -d --name deluge --restart=always \
-l collectd_docker_app=deluge \
-l collectd_docker_task=deluge \
-p 8083:8083 \
-p 53160:53160 \
--net=host \
-v /files:/files \
-v /etc/deluge:/config \
$(DELUGE_IMAGE)

upgrade_deluge: ## upgrade and launch a new deluge container
$(MAKE) build_deluge && \
(docker inspect deluge >/dev/null && { docker stop deluge && docker rm deluge; } || true) \
&& $(MAKE) create_deluge

# plex
build_plex: ## build the plex container
./plex/plexupdate.sh -r | tail -1 | tee ./plex/download_url
Expand All @@ -95,10 +128,13 @@ build_plex: ## build the plex container
create_plex: ## create the plex container
@echo "NOTE: make sure you have run 'chown -R nobody:nobody /etc/plex' before creating the plex container."
docker run -d --name plex --restart=always \
-l collectd_docker_app=plex \
-l collectd_docker_task=plex \
-p 32400:32400 \
--net=host \
-v /files:/files \
-v /etc/plex:/config \
-v /dev/dri:/dev/dri \
$(PLEX_IMAGE)

upgrade_plex: ## upgrade and launch a new plex container
Expand All @@ -112,6 +148,8 @@ build_plexpy: ## build the plexpy container

create_plexpy: ## create the plexpy container
docker run -d --name plexpy --restart=always \
-l collectd_docker_app=plexpy \
-l collectd_docker_task=plexpy \
-e PUID=65534 -e PGID=65534 \
-p 8181:8181 \
-v /etc/plexpy:/config \
Expand All @@ -122,26 +160,14 @@ upgrade_plexpy: ## upgrade and restart the plexpy container
# we use the linuxserver/plexpy image which auto-upgrades on restart
docker restart plexpy

# couchpotato
build_couchpotato: ## build the couchpotato container
docker pull $(COUCHPOTATO_IMAGE)

create_couchpotato: ## create the couchpotato container
docker run -d --name couchpotato --restart=always \
-e PUID=65534 -e PGID=65534 \
-p 5050:5050 \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/couchpotato:/config \
-v /files/usenet/downloads:/downloads \
-v /files/movies:/movies \
$(COUCHPOTATO_IMAGE)

# timecapsule (samba)
build_timecapsule: ## build the timecapsule (samba) container
docker build -t $(TIMECAPSULE_IMAGE) --pull=true timecapsule

create_timecapsule: _configure_network ## create and start the timecapsule (samba) container
create_timecapsule: _configure_networks ## create and start the timecapsule (samba) container
docker run -d --name timecapsule --restart=always \
-l collectd_docker_app=timecapsule \
-l collectd_docker_task=timecapsule \
--hostname=timecapsule \
--net=$(NETWORK_NAME) \
-v /files/timemachine:/timemachine \
Expand All @@ -161,6 +187,8 @@ build_muximux: ## build the muximux container

create_muximux: ## create the muximux container
docker run -d --name muximux --restart=always \
-l collectd_docker_app=muximux \
-l collectd_docker_task=muximux \
-e PUID=65534 -e PGID=65534 \
-p 8000:80 \
-v /etc/muximux:/config \
Expand All @@ -171,6 +199,85 @@ upgrade_muximux: ## upgrade and restart the muximux container
# we use the linuxserver/muximux image which auto-upgrades on restart
docker restart muximux

# go-carbon
build_go-carbon: ## build the go-carbon container
docker build -t $(GO_CARBON_IMAGE) --pull=true --no-cache=true go-carbon

create_go-carbon: _configure_networks ## create and start the go-carbon container
docker run -d --name go-carbon --restart=always \
-l collectd_docker_app=go-carbon \
-l collectd_docker_task=go-carbon \
-p 2003:2003 \
-p 2003:2003/udp \
-p 2004:2004 \
-p 7002:7002 \
-p 8080:8080 \
--network=metrics \
-v /etc/go-carbon/data:/data \
-v /etc/go-carbon/config:/config \
$(GO_CARBON_IMAGE)

upgrade_go-carbon: ## upgrade and launch a new go-carbon container
$(MAKE) build_go-carbon && \
(docker inspect go-carbon >/dev/null && { docker stop go-carbon && docker rm go-carbon; } || true) \
&& $(MAKE) create_go-carbon

# graphite-api
build_graphite-api: ## build the graphite-api container
docker pull $(GRAPHITE_API_IMAGE)

create_graphite-api: _configure_networks ## create and start the graphite-api container
docker run -d --name graphite-api --restart=always \
-l collectd_docker_app=graphite-api \
-l collectd_docker_task=graphite-api \
--network=metrics \
-v /etc/graphite-api/graphite-api.yaml:/etc/graphite-api.yaml \
-v /etc/go-carbon/data:/data \
$(GRAPHITE_API_IMAGE)

upgrade_graphite-api: ## upgrade and launch a new graphite-api container
$(MAKE) build_graphite-api && \
(docker inspect graphite-api >/dev/null && { docker stop graphite-api && docker rm graphite-api; } || true) \
&& $(MAKE) create_graphite-api

# grafana
build_grafana: ## build the grafana container
docker pull $(GRAFANA_IMAGE)

create_grafana: _configure_networks ## create and start the grafana container
docker run -d --name grafana --restart=always \
-l collectd_docker_app=grafana \
-l collectd_docker_task=grafana \
--network=metrics \
-p 3000:3000 \
-e "GF_INSTALL_PLUGINS=grafana-clock-panel" \
-v /etc/grafana:/var/lib/grafana \
$(GRAFANA_IMAGE)

upgrade_grafana: ## upgrade and launch a new grafana container
$(MAKE) build_grafana && \
(docker inspect grafana >/dev/null && { docker stop grafana && docker rm grafana; } || true) \
&& $(MAKE) create_grafana

# collectd-docker
build_collectd-docker: ## build the collectd-docker container
docker pull $(COLLECTD_DOCKER_IMAGE)

create_collectd-docker: _configure_networks ## create and start the collectd-docker container
docker run -d --name collectd-docker --restart=always \
-l collectd_docker_app=collectd-docker \
-l collectd_docker_task=collectd-docker \
--network=metrics \
-e GRAPHITE_HOST=go-carbon \
-e COLLECTD_HOST=$$(hostname -s) \
-v /var/run/docker.sock:/var/run/docker.sock \
$(COLLECTD_DOCKER_IMAGE)

upgrade_collectd-docker: ## upgrade and launch a new collectd-docker container
$(MAKE) build_collectd-docker && \
(docker inspect collectd-docker >/dev/null && { docker stop collectd-docker && docker rm collectd-docker; } || true) \
&& $(MAKE) create_collectd-docker

# helpers
help: ## print list of tasks and descriptions
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
Expand Down
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ perms in the /config volumes.
Volumes
-------

Each container follows a similar pattern for config and data volumes:
Each container generally follows a similar pattern for config and data volumes:

- `/files` -> `/files`: Large data volume. In my case, there are folders such
as: `/files/tv_shows`, `/files/movies`, `/files/downloads`, etc.
Expand All @@ -39,6 +39,11 @@ Each container follows a similar pattern for config and data volumes:
mapped to `/config` inside the sabnzbd
container for persistent config storage.

This is not the case for all containers. Check the Makefile for details on
each container.

TODO: enumerate each container's host volume mounts here.

Ports
-----

Expand All @@ -55,6 +60,10 @@ Ports
- is able to obtain its own IP address on the LAN.
See [timecapsule (Samba)](#timecapsule-samba) for more details.
- `muximux`: http web ui on port 8000
- `grafana`: http web ui on port 3000
- `graphite-api`: No forwarded ports. Accessed only by attaching to the `metrics`
network.
- `go-carbon`: graphite line protocol on port 2003.

Note: most of these apps can also expose TLS https ports but the current config
does not expose these.
Expand Down Expand Up @@ -161,7 +170,7 @@ with the following docker command:

$ docker network create -d macvlan \
--subnet 192.168.0.0/24 \
--gateway 192.168.0.1
--gateway 192.168.0.1 \
-o parent=eth0 \
localnet

Expand All @@ -170,3 +179,19 @@ by lying about the max available space on the samba share. This is done using
a `dfree` script. By default, the max space presented to TimeMachine is 750GB.
This can be changed by updating the `TIMEMACHINE_MAX_VOL_SIZE_GB` environment
variable in the Dockerfile.

### metrics (grafana, graphite-api, go-carbon)

All three metrics containers are attached to a user-defined bridge network
named `metrics`. The only forwarded port is port 3000 (http) to the `grafana`
host.

Metrics are stored in `/etc/go-carbon/data` which is mounted into both the
`go-carbon` and `graphite-api` containers.

`grafana` fetches metrics from the `graphite-api` container over port 8000.

Metrics are sent to port 2003 which is forwarded into the `go-carbon` container,
example from host:

echo "testdata.foo.bar $RANDOM $(date +%s)" | tee >&2 | nc localhost 2003
24 changes: 24 additions & 0 deletions go-carbon/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM ubuntu:16.04

ENV GO_CARBON_PKG_URL https://github.com/lomik/go-carbon/releases/download/v0.9.1/go-carbon_0.9.1_amd64.deb

RUN apt-get update -q \
&& apt-get install -qy \
wget \
&& apt-get -y autoremove \
&& apt-get -y clean \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/*

RUN cd /tmp \
&& wget -q "${GO_CARBON_PKG_URL}" \
&& dpkg -i /tmp/*.deb \
&& rm -rf /tmp/*

EXPOSE 2003 2004 7002 7007 8080 2003/udp
VOLUME /data

ADD carbon.conf /config/carbon.conf
ADD storage-schemas.conf /config/storage-schemas.conf

CMD ["go-carbon", "-config", "/config/carbon.conf"]
Loading

0 comments on commit 3f4d308

Please sign in to comment.