{"id":6996,"date":"2019-01-16T23:39:32","date_gmt":"2019-01-16T22:39:32","guid":{"rendered":"https:\/\/pi3g.com\/?p=6996"},"modified":"2019-01-16T23:39:32","modified_gmt":"2019-01-16T22:39:32","slug":"setting-up-envoy-as-a-front-proxy-on-docker-with-communication-to-other-docker-containers","status":"publish","type":"post","link":"https:\/\/pi3g.com\/de\/setting-up-envoy-as-a-front-proxy-on-docker-with-communication-to-other-docker-containers\/","title":{"rendered":"Einrichten von envoy als Front-Proxy auf Docker mit Kommunikation zu anderen Docker-Containern"},"content":{"rendered":"<p>I have already existing containers which I want to use envoy as a proxy &amp; https manager in front of. I am learning to use envoy, and am sharing some of my learnings here, as documentation is a bit confusing to start with.<\/p>\n<p>My already existing container is called \u201ctaxgod\u201d \u2013 it runs a Crystal application on port 3000 (http). I want to proxy it to port 80 on the host for http, and port 443 for https. <\/p>\n<p>I will use a fake certificate for demonstration purposes. Certificate creation is outside the scope of this article.<\/p>\n<p>The envoy container is going to be called penvoyage (<a href=\"https:\/\/picockpit.com\" target=\"_blank\">picockpit<\/a> <strong>envoy <\/strong>)<\/p>\n<h2>Building penvoyage<\/h2>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/01\/image-32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"601\" height=\"183\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/01\/image_thumb-31.png\" border=\"0\"><\/a><\/p>\n<p>The penvoyage folder used for building contains <\/p>\n<ul>\n<li>Dockerfile<\/li>\n<li>envoy.yaml<\/li>\n<li>example.crt (certificate)<\/li>\n<li>example.key (key for the certificate)<\/li>\n<\/ul>\n<h3>Dockerfile<\/h3>\n<blockquote>\n<p>FROM envoyproxy\/envoy:latest<br \/>\nCOPY envoy.yaml \/etc\/envoy\/envoy.yaml<br \/>\nCOPY example.crt \/etc\/example-com.crt<br \/>\nCOPY example.key \/etc\/example-com.key<br \/>\n#VOLUME \/etc\/envoy\/envoy.yaml<\/p>\n<p>EXPOSE 80\/tcp<br \/>\nEXPOSE 443\/tcp<br \/>\n#Educated guess that this is TCP<br \/>\nEXPOSE 9901\/tcp<\/p>\n<p>LABEL version=&#8221;0.2.0&#8243; \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description=&#8221;penvoyage is envoy proxy for PiCockpit&#8221; \\<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maintainer=&#8221;&lt;deleted&gt;&#8221;<\/p>\n<\/blockquote>\n<p>Take care with the &#8221; characters, WordPress might mess them up!<\/p>\n<p>I will go into the envoy.yaml in a bit more detail soon. Suffice it to say, that it is in this folder and will be copied into the newly created container image.<\/p>\n<p>To build the container run (from the directory containing the penvoyage directory):<\/p>\n<blockquote>\n<p>docker build -t jasmine\/penvoyage:0.2.0 -t jasmine\/penvoyage:latest penvoyage<\/p>\n<\/blockquote>\n<p>Your output should terminate with the lines<\/p>\n<p>Successfully tagged jasmine\/penvoyage:0.2.0<br \/>\nSuccessfully tagged jasmine\/penvoyage:latest\n<\/p>\n<p><\/p>\n<h2>Create the docker network<\/h2>\n<blockquote>\n<p>docker network create -d bridge my-bridge-network<\/p>\n<\/blockquote>\n<p>We will use this network to attach both containers to each other, so they see each other.<\/p>\n<p>Containers can talk to each other using their container names, when they are on the same container network. <\/p>\n<p>E.g. you can do <\/p>\n<blockquote>\n<p>ping taxgod <\/p>\n<\/blockquote>\n<p>where taxgod is the container name.<\/p>\n<p>To add a container to a network after it has been run, do the following:<\/p>\n<blockquote>\n<p>docker network connect my-bridge-network taxgod<\/p>\n<\/blockquote>\n<p>In this case my-bridge-network is the network, and taxgod is the container to be connected to it.<\/p>\n<p>To see how a container which is run is connected to a particular network, see below.<\/p>\n<p>To see which containers are on a particular Docker network, run the following command:<\/p>\n<blockquote>\n<p>docker network inspect my-bridge-network<\/p>\n<\/blockquote>\n<h2>Run the penvoyage container image<\/h2>\n<blockquote>\n<p>docker run &#8211;rm -it&nbsp; -p 80:80 -p 443:443 -p 9901:9901 &#8211;network=my-bridge-network jasmine\/penvoyage<\/p>\n<\/blockquote>\n<p>This will:<\/p>\n<ul>\n<li>&#8211;rm remove the container after it\u2019s shutdown <\/li>\n<li>-it attach to the container (so you can see envoy\u2019s output)<\/li>\n<li>-p 80:80 map port 80 to port 80 inside the container (in the Docker file I have defined this to be the tcp port)<\/li>\n<li>repeat for port 443 and port 9901<\/li>\n<li>attach the container to my-bridge-network<\/li>\n<li>build the container from the jasmine\/penvoyage:latest image (:latest is implicit here)<\/li>\n<\/ul>\n<p><strong>What will this container do?<\/strong><\/p>\n<p>It will proxy connections to the host (in my case on IP 192.168.1.2) to the taxgod container, on port 3000.<\/p>\n<p>It will act as a https proxy with the sample certificates, and proxy the connections to the same taxgod container, on port 3000.<\/p>\n<h2>envoy.yaml<\/h2>\n<p>Please note: yaml uses whitespace for structure, most likely WordPress will MESS this up. So use this as a reference, rather than a copy &amp; paste thing!<\/p>\n<hr>\n<p>static_resources:<br \/>&nbsp;&nbsp; listeners:<br \/>&nbsp;&nbsp; &#8211; address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket_address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address: 0.0.0.0<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port_value: 80<br \/>&nbsp;&nbsp;&nbsp;&nbsp; filter_chains:<br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8211; filters:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; name: envoy.http_connection_manager<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; config:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; codec_type: auto<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stat_prefix: ingress_http<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; route_config:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name: local_route<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; virtual_hosts:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; name: local_service<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; domains: [&#8220;*&#8221;]<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; routes:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; match: { prefix: &#8220;\/&#8221; }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; route: { cluster: target_taxgod }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http_filters:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; name: envoy.router<br \/>&nbsp;&nbsp; &#8211; address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket_address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address: 0.0.0.0<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port_value: 443<br \/>&nbsp;&nbsp;&nbsp;&nbsp; filter_chains:<br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8211; tls_context:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; common_tls_context:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tls_certificates:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; certificate_chain: { filename: &#8220;\/etc\/example-com.crt&#8221; }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private_key: { filename: &#8220;\/etc\/example-com.key&#8221; }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filters:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; name: envoy.http_connection_manager<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; config:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stat_prefix: ingress_https<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; route_config:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; virtual_hosts:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; name: default<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; domains: [&#8220;*&#8221;]<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; routes:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; match: { prefix: &#8220;\/&#8221; }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; route: { cluster: target_taxgod }<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http_filters:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8211; name: envoy.router<br \/>&nbsp;&nbsp; clusters:<br \/>&nbsp;&nbsp; &#8211; name: target_taxgod<br \/>&nbsp;&nbsp;&nbsp;&nbsp; connect_timeout: 0.25s<br \/>&nbsp;&nbsp;&nbsp;&nbsp; type: strict_dns<br \/>&nbsp;&nbsp;&nbsp;&nbsp; lb_policy: round_robin<br \/>&nbsp;&nbsp;&nbsp;&nbsp; hosts:<br \/>&nbsp;&nbsp;&nbsp;&nbsp; &#8211; socket_address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address: taxgod<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port_value: 3000<br \/>\nadmin:<br \/>&nbsp;&nbsp; access_log_path: &#8220;\/tmp\/envoy.log&#8221;<br \/>&nbsp;&nbsp; address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp; socket_address:<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address: 0.0.0.0<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port_value: 9901<\/p>\n<hr>\n<p><\/p>\n<p>Short explanation of the envoy yaml file:<\/p>\n<p>There are two main sections, static_resources and admin<\/p>\n<p>admin is for the administration of envoy and outside the scope of this article. In a production environment you will probably need to secure it appropriately. DO NOT COPY &amp; PASTE THAT PART!!!<\/p>\n<p>static_resources defines a static configuration for envoy (envoy can also be set up using it\u2019s API)<\/p>\n<p><\/p>\n<p>in listeners, we define which ports we want to listen on, and what should happen to the connections.<\/p>\n<ul>\n<li>address \u2013 defines address and port to listen on<\/li>\n<ul>\n<li>envoy.http_connection_manager \u2013 manages http connections, reads headers, and so on. it is a predefined filter<\/li>\n<li>stat_prefix: defines a human readable name for logs \/ statistics<\/li>\n<li>domains: [&#8220;*&#8221;] \u2013 matches all domains<\/li>\n<li>route: { cluster: target_taxgod } \u2013 will route traffic to our cluster target_taxgod (will match for \/, that is everything on the site)<\/li>\n<\/ul>\n<\/ul>\n<p>the address and it\u2019s sub configuration is repeated two times, one for port 80, and one for port 443. For port 443 we also add the tls_context and common_tls_context in the filter_chains to inject the certificates.<\/p>\n<p>Note that it still is <strong>envoy.http_connection_manager<\/strong>, NOT https_connection_manager for port 443.<\/p>\n<p><\/p>\n<p>in clusters we define our endpoints we want to be able to connect to \/ proxy traffic to.<\/p>\n<ul>\n<li>the cluster has a name<\/li>\n<li>a connection timeout<\/li>\n<li>lb_policy \u2013 the load balancing policy. There is only one host, so it will get all of the traffic (round_robin means that each host will get traffic in turn)<\/li>\n<li>in the hosts, the socket_address is set as address taxgod \u2013 this is the Docker name of the container, and the port as port_value <strong>3000<\/strong> <\/li>\n<\/ul>\n<p>The port 3000 is the internal port of the container taxgod, it is not the port which you bind it to on the external host!<\/p>\n<p><\/p>\n<p>I hope this blog post helps people trying to set up a https:\/\/ setup in envoy.<\/p>\n<p><\/p>\n<h2>Error messages<\/h2>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/01\/image-33.png\"><img loading=\"lazy\" decoding=\"async\" width=\"493\" height=\"102\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/01\/image_thumb-32.png\" border=\"0\"><\/a><\/p>\n<p>Envoy <strong>no healthy upstream <\/strong>error message <\/p>\n<p>the envoy container <strong>is not on the same Docker network<\/strong> as your target container, as it can\u2019t see it, it can\u2019t connect to it.<\/p>\n<p><\/p>\n<p><a href=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/01\/image-34.png\"><img loading=\"lazy\" decoding=\"async\" width=\"587\" height=\"111\" title=\"image\" style=\"display: inline; background-image: none;\" alt=\"image\" src=\"https:\/\/pi3g.com\/wp-content\/uploads\/2019\/01\/image_thumb-33.png\" border=\"0\"><\/a><\/p>\n<p>Envoy <strong>upstream connect error or disconnect\/reset before headers <\/strong>error<\/p>\n<p>Try to <strong>remove<\/strong> <\/p>\n<blockquote>\n<p>http2_protocol_options: {}<\/p>\n<\/blockquote>\n<p>from your envoy.yaml<\/p>\n<p><\/p>\n<h2>Useful resources<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/intro\/arch_overview\/http_connection_management\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/intro\/arch_overview\/http_connection_management<\/a><\/li>\n<li><a href=\"https:\/\/runnable.com\/docker\/basic-docker-networking\">https:\/\/runnable.com\/docker\/basic-docker-networking<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/network_create\/\">https:\/\/docs.docker.com\/engine\/reference\/commandline\/network_create\/<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/v17.09\/engine\/userguide\/networking\/\">https:\/\/docs.docker.com\/v17.09\/engine\/userguide\/networking\/<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/envoyproxy\/envoy\/tree\/master\/examples\/front-proxy\">https:\/\/github.com\/envoyproxy\/envoy\/tree\/master\/examples\/front-proxy<\/a><\/li>\n<li><a href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/intro\/arch_overview\/http_routing\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/intro\/arch_overview\/http_routing<\/a><\/li>\n<li><a href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/http_conn_man\/header_sanitizing\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/http_conn_man\/header_sanitizing<\/a><\/li>\n<li><a href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/api-v2\/api\/v2\/route\/route.proto#envoy-api-field-route-routeaction-host-rewrite\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/api-v2\/api\/v2\/route\/route.proto#envoy-api-field-route-routeaction-host-rewrite<\/a><\/li>\n<ul>\n<li>prefix_rewrite looks interesting \u2013 it allows to change application URLs to a different path than exposed at the reverse proxy layer<\/li>\n<\/ul>\n<li><a href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/api-v2\/config\/filter\/network\/http_connection_manager\/v2\/http_connection_manager.proto#envoy-api-enum-config-filter-network-http-connection-manager-v2-httpconnectionmanager-codectype\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/api-v2\/config\/filter\/network\/http_connection_manager\/v2\/http_connection_manager.proto#envoy-api-enum-config-filter-network-http-connection-manager-v2-httpconnectionmanager-codectype<\/a><\/li>\n<ul>\n<li>there are built-in filters <\/li>\n<\/ul>\n<li><a href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/http_filters\/router_filter#config-http-filters-router\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/http_filters\/router_filter#config-http-filters-router<\/a><\/li>\n<ul>\n<li>\u201cThe router filter implements HTTP forwarding. It will be used in almost all HTTP proxy scenarios that Envoy is deployed for.\u201d<\/li>\n<\/ul>\n<li><a href=\"https:\/\/blog.turbinelabs.io\/setting-up-ssl-with-envoy-f7c5aa06a5ce\">https:\/\/blog.turbinelabs.io\/setting-up-ssl-with-envoy-f7c5aa06a5ce<\/a><\/li>\n<ul>\n<li>has a section on redirecting insecure traffic<\/li>\n<\/ul>\n<li><a href=\"https:\/\/www.envoyproxy.io\/try\/migrating-from-nginx-to-envoy\">https:\/\/www.envoyproxy.io\/try\/migrating-from-nginx-to-envoy<\/a><\/li>\n<ul>\n<li>useful as an introduction to Envoy as well<\/li>\n<\/ul>\n<li><a title=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/access_log#config-access-log-format-dictionaries\" href=\"https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/access_log#config-access-log-format-dictionaries\">https:\/\/www.envoyproxy.io\/docs\/envoy\/latest\/configuration\/access_log#config-access-log-format-dictionaries<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Ich habe bereits bestehende Container, die ich envoy als Proxy &amp; https-Manager vor verwenden m\u00f6chten. Ich lerne, envoy zu verwenden, und teile einige meiner Erkenntnisse hier, da die Dokumentation ein wenig verwirrend ist, mit zu beginnen. Mein bereits vorhandener Container hei\u00dft \"taxgod\" - es l\u00e4uft ein Crystal...<\/p>","protected":false},"author":830,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-6996","post","type-post","status-publish","format-standard","hentry","category-raspberrypi-blog"],"_links":{"self":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/6996","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/users\/830"}],"replies":[{"embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/comments?post=6996"}],"version-history":[{"count":1,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/6996\/revisions"}],"predecessor-version":[{"id":6997,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/posts\/6996\/revisions\/6997"}],"wp:attachment":[{"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/media?parent=6996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/categories?post=6996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pi3g.com\/de\/wp-json\/wp\/v2\/tags?post=6996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}