\documentclass[tikz,convert={outfile=\jobname.svg}]{standalone} %\documentclass{article} \usepackage{tikz} \usetikzlibrary{positioning,fit,calc} \begin{document} \begin{tikzpicture}[ block/.style={ draw, fill=white, rectangle, minimum width={width("TLE2JSON")+2pt}, minimum height={height("TLE")+2pt}, font=\small, node distance=2cm } ] % left blocks \node[block] (TLE) {TLE}; \node[block, below = of TLE] (TLE2JSON) {TLE2JSON}; \node[block, left = of TLE2JSON] (celestrack) {celestrack}; \node[block, below = of TLE2JSON] (cache) {cache}; % right blocks \node[block, right = of TLE] (drone) {drone}; \node[block, below = of drone, right = of TLE2JSON] (prometheus) {prometheus}; \node[block, below = of prometheus, right = of cache] (grafana) {grafana}; % left clusters \node[draw, fit=(TLE), label=left:{git.darknebu.la}] (git.darknebu.la) {}; \node[draw, fit=(TLE2JSON) (cache), label=below:{YOU}, draw=red] (you) {}; \node[draw, fit=(celestrack), label=left:{the internet}] (the internet) {}; % right clusters \node[draw, fit=(drone) (prometheus) (grafana), label=right:{nbg1}] (nbg1) {}; \path[draw, ->, line width=0.175mm, >=stealth] (grafana.north) -- (prometheus.south) node[midway, fill=white] {data}; \path[draw, ->, line width=0.175mm, >=stealth] (prometheus.north) -- (drone.south) node[midway, fill=white] {metrics}; \path[draw, ->, line width=0.175mm, >=stealth] (drone.west) -- (TLE.east) node[midway, fill=white] {ci}; \path[draw, ->, line width=0.175mm, >=stealth] (prometheus.west) -- (TLE2JSON.east) node[midway, fill=white] {metrics}; \path[draw, ->, line width=0.175mm, >=stealth] (TLE2JSON.west) -- (celestrack.east) node[midway, fill=white]{TLE}; \path[draw, ->, line width=0.175mm, >=stealth] (TLE2JSON.north) -- (TLE.south) node[midway, fill=white] {go module}; \path[draw, ->, line width=0.175mm, >=stealth] (TLE2JSON.south) -- (cache.north) node[midway, fill=white] {TLE}; \end{tikzpicture} \end{document}