{"id":656,"date":"2012-10-08T10:00:24","date_gmt":"2012-10-08T08:00:24","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=656"},"modified":"2016-01-11T23:51:38","modified_gmt":"2016-01-11T22:51:38","slug":"vagrant-tutorial","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/vagrant-tutorial\/","title":{"rendered":"Vagrant Tutorial"},"content":{"rendered":"<p>Vagrant (zu Deutsch: &#8222;umherwandernd&#8220;) ist ein klasse Tool f\u00fcr verteilte Entwicklung. Muss man sich so vorstellen: Entwickler A soll soll einen Bug fixen, holt die entsprechende Vagrant-Box hervor und findet in ihr die komplette Projektumgebung wieder &#8211; Apache, MySQL, PHP in der jeweils korrekten Version, Anbindung an den CI-Server und alles was man eben so ben\u00f6tigt. Nach getaner Arbeit wird das Projekt deployed und die Vagrant Box gespeichert. Wenn dann sp\u00e4ter wieder jemand an diesem Projekt arbeitet, schnappt er sich einfach die Box und legt los. Kein l\u00e4stiges Umherk\u00e4mpfen mit vhosts, falschen Softwareversionen und allem, worauf eigentlich niemand Lust hat. Aber der Reihe nach.<\/p>\n<h2>Vagrant installieren<\/h2>\n<p>Zuerst wird die VirtualBox von Oracle ben\u00f6tigt. Hier ist allerdings Vorsicht geboten. Vagrant unterst\u00fctzt unter Umst\u00e4nden nicht die neuste Version, also <a href=\"http:\/\/vagrantup.com\/v1\/docs\/getting-started\/index.html\">hier nachlesen<\/a>, welche Versionen supported werden und dann <a href=\"https:\/\/www.virtualbox.org\/wiki\/Downloads\">von hier herunterladen<\/a>. Vagrant verwendet VirtualBox zur Virtualisierung des Betriebssystems in der Box.  Danach ist Vagrant selbst dran &#8211; <a href=\"http:\/\/downloads.vagrantup.com\/\">Download befindet sich hier<\/a>.<\/p>\n<p><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-Vagrant.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-Vagrant.png\" alt=\"\" title=\"Installation Vagrant\" width=\"500\" height=\"394\" class=\"alignnone size-full wp-image-657\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-Vagrant.png 500w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-Vagrant-300x236.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><\/p>\n<p>Nun muss der Hauptordner von VirtualBox zum <i>PATH<\/i> (Umgebungsvariable) hinzugef\u00fcgt werden.<\/p>\n<div id=\"attachment_658\" style=\"width: 426px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PATH.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-658\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PATH.png\" alt=\"PATH\" title=\"PATH\" width=\"416\" height=\"486\" class=\"size-full wp-image-658\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PATH.png 416w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PATH-256x300.png 256w\" sizes=\"auto, (max-width: 416px) 100vw, 416px\" \/><\/a><p id=\"caption-attachment-658\" class=\"wp-caption-text\">PATH<\/p><\/div>\n<p>Als n\u00e4chstes ins <i>bin<\/i>-Verzeichnis von Vagrant per cmd wechseln, bei mir ist das <i>D:\\vagrant\\vagrant\\bin<\/i>. Weiter mit der Installation der Box.<\/p>\n<h2>Eine Box installieren<\/h2>\n<p>Wir installieren <i>Ubuntu 12.04 Precise Pangolin<\/i>, die Box dazu befindet sich unter <i>http:\/\/files.vagrantup.com\/precise32.box<\/i>.<\/p>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">vagrant box add webdev http:\/\/files.vagrantup.com\/precise32.box<\/pre>\n<div id=\"attachment_660\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Box-Installieren.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-660\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Box-Installieren-300x148.png\" alt=\"Box installieren\" title=\"Box installieren\" width=\"300\" height=\"148\" class=\"size-medium wp-image-660\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Box-Installieren-300x148.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Box-Installieren.png 672w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-660\" class=\"wp-caption-text\">Box installieren<\/p><\/div>\n<p>Die Box ist heruntergeladen, nun gehts weiter mit:<\/p>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">\r\nvagrant init\r\n<\/pre>\n<p>Dieser Befehl erstellt ein sog. <i>Vagrantfile<\/i> im <i>bin<\/i>-Ordner, welches die Konfiguration beinhaltet. Hier kann bspw. festgelegt werden, welche Ports benutzt werden sollen und ob Ordner zwischen Hostsystem und Box geteilt werden.<\/p>\n<h2>Das Vagrant-File<\/h2>\n<p>Im Wesentlichen sieht ein Vagrantfile (Ruby-Syntax) &#8211; auf die n\u00f6tigsten Optionen reduziert &#8211; so aus:<\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">\r\nVagrant::Config.run do |config|\r\n  config.vm.box = &quot;webdev&quot;\r\n  config.vm.box_url = &quot;http:\/\/files.vagrantup.com\/precise32.box&quot;\r\n\r\n  config.vm.share_folder(&quot;v-web&quot;, &quot;\/vagrant\/www&quot;, &quot;D:\/www&quot;)\r\n  config.vm.forward_port 80, 3456\r\n\r\n  config.vm.define &quot;webdev&quot; do |default_config|\r\n\r\n    #Puppet\r\n    default_config.vm.provision :puppet do |puppet|\r\n      puppet.facter = { &quot;fqdn&quot; =&gt; &quot;local.dev&quot;, &quot;hostname&quot; =&gt; &quot;www&quot; }\r\n      puppet.manifests_path = &quot;puppet\/manifests&quot;\r\n      puppet.manifest_file  = &quot;ubuntu-apache2-mysql-php5.pp&quot;\r\n      puppet.module_path  = &quot;puppet\/modules&quot;\r\n    end\r\n  end\r\nend\r\n<\/pre>\n<p>Beachtenswerte Zeilen:<\/p>\n<ul>\n<li><b>config.vm.share_folder<\/b> &#8211; Der Ordner D:\/www wird im Vagrant-Filesystem unter <i>\/vagrant\/www<\/i> verf\u00fcgbar gemacht.<\/li>\n<li><b>config.vm.forward_port<\/b> &#8211; Port 3456 auf unserem Host-System soll in Port 80 der Vagrant-Box enden.<\/li>\n<li>Wir verwenden Puppet zum Konfigurieren der &#8222;webdev&#8220; genannten Box, dazu gleich mehr<\/li>\n<\/ul>\n<h2>Puppet-File anlegen<\/h2>\n<p>Das in der Config angegebene Puppet-File <i>ubuntu-apache2-mysql-php5.pp<\/i> beinhaltet s\u00e4mtliche Anweisungen f\u00fcr die Vagrant-Box. Alternativ l\u00e4sst sich auch <a href=\"http:\/\/wiki.opscode.com\/display\/chef\/Home\">Chef<\/a> zum Konfigurieren verwenden. Puppet machte auf mich aber einen besseren Eindruck.<\/p>\n<p>Wir legen unter <i>\\vagrant\\vagrant\\bin\\puppet\\manifests<\/i> eine leere Datei <b>ubuntu-apache2-mysql-php5.pp<\/b> an.<\/p>\n<div id=\"attachment_661\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/puppet-file.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-661\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/puppet-file-300x69.png\" alt=\"Puppet-File\" title=\"Puppet-File\" width=\"300\" height=\"69\" class=\"size-medium wp-image-661\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/puppet-file-300x69.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/puppet-file.png 643w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-661\" class=\"wp-caption-text\">Puppet-File<\/p><\/div>\n<p>Folgenden Inhalt packen wir in die <b>ubuntu-apache2-mysql-php5.pp<\/b> hinein:<\/p>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">\r\nExec { path =&gt; [ &quot;\/bin\/&quot;, &quot;\/sbin\/&quot; , &quot;\/usr\/bin\/&quot;, &quot;\/usr\/sbin\/&quot; ] }\r\n\r\nclass system-update {\r\n\r\n  exec { &#039;apt-get update&#039;:\r\n    command =&gt; &#039;apt-get update -y&#039;,\r\n  }\r\n\r\n  $sysPackages = [ &quot;build-essential&quot; ]\r\n  package { $sysPackages:\r\n    ensure =&gt; &quot;installed&quot;,\r\n    require =&gt; Exec[&#039;apt-get update&#039;],\r\n  }\r\n}\r\n\r\ninclude system-update\r\n\r\nclass php5 {\r\n\r\n  package { &quot;php5&quot;:\r\n    ensure =&gt; present,\r\n  }\r\n\r\n  $phpPackages = [ &quot;php5-cli&quot;, &quot;php5-common&quot;, &quot;php5-dev&quot;, &quot;php5-mysql&quot;, &quot;php5-curl&quot; ]\r\n  package { $phpPackages:\r\n    ensure =&gt; &quot;installed&quot;,\r\n    require =&gt; Exec[&#039;apt-get update&#039;]\r\n  }\r\n  \r\n  package { &quot;libapache2-mod-php5&quot;:\r\n\tensure =&gt; present,\r\n  }\r\n}\r\n\r\ninclude php5\r\n\r\nclass apache2 {\r\n\r\n\tpackage { &quot;apache2&quot;:\r\n\t\tensure =&gt; present,\r\n\t}\r\n\r\n\tservice { &quot;apache2&quot;:\r\n\t\tensure =&gt; running,\r\n\t\trequire =&gt; Package[&quot;apache2&quot;]\r\n\t}\r\n}\r\n\r\ninclude apache2\r\n\r\npackage { &quot;php-pear&quot; :\r\n    ensure =&gt; present,\r\n    require =&gt; Package[&#039;php5&#039;],\r\n\tnotify  =&gt; Service[&#039;apache2&#039;]\r\n}\r\n\r\n\r\nclass mysql {\r\n\t package {\r\n\t\t[&quot;mysql-client&quot;, &quot;mysql-server&quot;, &quot;libmysqlclient-dev&quot;]: \r\n\t\t  ensure =&gt; installed, require =&gt; Exec[&#039;apt-get update&#039;],\r\n\t\t  notify  =&gt; Service[&#039;apache2&#039;]\r\n\t  }\r\n}\r\n\r\ninclude mysql\r\n\r\nclass development {\r\n\r\n  $devPackages = [ &quot;curl&quot;, &quot;git&quot; ]\r\n  package { $devPackages:\r\n    ensure =&gt; &quot;installed&quot;,\r\n    require =&gt; Exec[&#039;apt-get update&#039;],\r\n  }\r\n}\r\n\r\ninclude development\r\n\r\nfile { &quot;\/var\/www\/index.html&quot;:\r\n\tensure =&gt; absent\r\n}\r\n \r\nfile { &quot;\/var\/www\/index.php&quot;:\r\n\tensure =&gt; present,\r\n\tcontent =&gt; &#039;&lt;?php echo &quot;Hello, World!&quot;;&#039;,\r\n\tmode =&gt; 644,\r\n\towner =&gt; www-data,\r\n\tgroup =&gt; www-data\r\n}\r\n<\/pre>\n<p>Das muss man jetzt erstmal auf sich wirken lassen. Prinzipiell ist das Puppet-File so aufgebaut, dass die Instruktionen in Klassen stecken, die nach ihrem include dann ausgef\u00fchrt werden. Wir definieren zuerst eine <i>Exec<\/i>-Funktion, die an den typischen Orten nach ausf\u00fchrbaren Dateien sucht &#8211; brauchen wir sp\u00e4ter noch. Zuerst machen wir ein System-Update, dass alles auf dem neusten Stand ist. Weiterhin werden die &#8222;build-essentials&#8220; installiert &#8211; kann man immer gebrauchen. Dann der Reihe nach <b>PHP<\/b> mit den Paketen <i>&#8222;php5-cli&#8220;, &#8222;php5-common&#8220;, &#8222;php5-dev&#8220;, &#8222;php5-mysql&#8220;, &#8222;php5-curl&#8220;<\/i> und <b>Apache<\/b>. Dann noch <B>pear<\/b> und <b>mysql<\/b>. Nach der Installation von mysql wird Apache benachrichtigt, dass er bitte neu laden soll (&#8222;notify&#8220;). Abschlie\u00dfend holen wir dann noch <b>curl und git<\/b>. Zu guter Letzt l\u00f6schen wir die Apache-Standard &#8222;index.html&#8220;-Datei im <i>\/var\/www\/<\/i>-Verzeichnis und packen daf\u00fcr eine <i>index.php<\/i>-Datei hinein. Ich denke, das Prinzip sollte klar sein. Weiterf\u00fchrende Erkl\u00e4rung zu <a href=\"http:\/\/docs.puppetlabs.com\/\">Puppet finden sich hier<\/a>.<\/p>\n<h2>vagrant up<\/h2>\n<p>Es wird Zeit, die Box zu starten. Das l\u00e4uft mit <\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">vagrant up<\/pre>\n<p>. Alternativ k\u00f6nnen wir auch <\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">vagrant up webdev<\/pre>\n<p> verwenden, wenn mehrere Boxen existieren &#8211; unsere Box hei\u00dft ja schlie\u00dflich <i>webdev<\/i>. Nun startet die Box und installiert alle gew\u00fcnschten Dependencies aus dem Puppet-File &#8211; das dauert etwas, allerdings ist die vollst\u00e4ndige Installation ein einmaliger Vorgang, weil danach nur noch inkrementelle Updates n\u00f6tig sind, falls sich am Puppet-File etwas \u00e4ndert. \u00dcbrigens: Ist die Box einmal geladen und ihr nehmt am Puppet-File eine \u00c4nderung vor, muss nicht die ganze Box neu gestartet werden. Folgendes Kommando tuts auch: <\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">vagrant provision<\/pre>\n<p>. Hier wird allerdings nur das Provisioning durchgef\u00fchrt (=alles, was sich in der Puppet-Datei befindet). <\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">vagrant reload<\/pre>\n<p> l\u00e4dt im Gegensatz dazu auch die Konfiguration neu.<\/p>\n<div id=\"attachment_662\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-fertig.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-662\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-fertig-300x150.png\" alt=\"Installation fertig\" title=\"Installation fertig\" width=\"300\" height=\"150\" class=\"size-medium wp-image-662\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-fertig-300x150.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Installation-fertig.png 672w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-662\" class=\"wp-caption-text\">Installation fertig<\/p><\/div>\n<h2>Verbindung zur Box<\/h2>\n<p>Nun ist die Box gestartet und l\u00e4uft brav im Hintergrund mit. Als n\u00e4chstes verbinden wir uns mit <a href=\"http:\/\/www.chiark.greenend.org.uk\/~sgtatham\/putty\/download.html\">Putty<\/a> per SSH auf die Box. Dazu feuern wir erstmal das Kommando<\/p>\n<pre data-enlighter-language=\"bash\" class=\"EnlighterJSRAW\">vagrant ssh<\/pre>\n<p> ab, was uns folgendes verr\u00e4t:<\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">\r\n`vagrant ssh` isn&#039;t available on the Windows platform. You are still able\r\nto SSH into the virtual machine if you get a Windows SSH client (such as\r\nPuTTY). The authentication information is shown below:\r\n\r\nHost: 127.0.0.1\r\nPort: 2200\r\nUsername: vagrant\r\nPrivate key: C:\/Users\/dav\/.vagrant.d\/insecure_private_key\r\n<\/pre>\n<p>Also schnappen wir uns den Private Key aus genanntem Verzeichnis und laden uns <a href=\"http:\/\/www.chiark.greenend.org.uk\/~sgtatham\/putty\/download.html\">PuTTYgen<\/a> herunter, um den Private Key ins Putty-Format zu konvertieren. PuTTygen starten, auf &#8222;Load&#8220; dr\u00fccken und den Private Key <i>C:\/Users\/dav\/.vagrant.d\/insecure_private_key<\/i> ausw\u00e4hlen.<\/p>\n<div id=\"attachment_663\" style=\"width: 490px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PuTTyGen.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-663\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PuTTyGen.png\" alt=\"PuTTygen\" title=\"PuTTygen\" width=\"480\" height=\"469\" class=\"size-full wp-image-663\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PuTTyGen.png 480w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/PuTTyGen-300x293.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><p id=\"caption-attachment-663\" class=\"wp-caption-text\">PuTTygen<\/p><\/div>\n<p>Nun auf <i>Save Private Key<\/i> (jaja, ohne Passwort&#8230;) und den ins Putty-Format konvertierten Private Key auf der Festplatte speichern. Jetzt kommt wieder Putty selbst zum Einsatz. Wir verbinden uns auf <i>127.0.0.1<\/i> mit Port <i>2222<\/i>. Dann unter <i>Connection -> SSH -> Auth<\/i> w\u00e4hlen wir den Key und speichern die Session.<\/p>\n<div id=\"attachment_664\" style=\"width: 471px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Private-Key.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-664\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Private-Key.png\" alt=\"Private Key\" title=\"Private Key\" width=\"461\" height=\"449\" class=\"size-full wp-image-664\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Private-Key.png 461w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/Private-Key-300x292.png 300w\" sizes=\"auto, (max-width: 461px) 100vw, 461px\" \/><\/a><p id=\"caption-attachment-664\" class=\"wp-caption-text\">Private Key<\/p><\/div>\n<p>Und wenn alles klargegangen ist, begr\u00fc\u00dft uns eine vollwertige Linux-Shell:<\/p>\n<div id=\"attachment_665\" style=\"width: 633px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/SSH.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-665\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/SSH.png\" alt=\"SSH\" title=\"SSH\" width=\"623\" height=\"227\" class=\"size-full wp-image-665\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/SSH.png 623w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2012\/09\/SSH-300x109.png 300w\" sizes=\"auto, (max-width: 623px) 100vw, 623px\" \/><\/a><p id=\"caption-attachment-665\" class=\"wp-caption-text\">SSH<\/p><\/div>\n<p>Hier sind jetzt bereits Apache, PHP, MySQL und alle anderen Raffinessen aus dem Puppet-File aufgespielt. Nun den Browser auf dem Host-System angeworfen und <i>http:\/\/127.0.0.1:3456\/<\/i> besucht &#8211; voil\u00e0. Der Rest erschlie\u00dft sich jetzt von alleine. Wenn die Box in ihrem fertigen Zustand gespeichert werden soll, ben\u00f6tigt es das <i>vagrant package<\/i>-Command. N\u00e4heres hierzu findet sich <a href=\"http:\/\/vagrantup.com\/v1\/docs\/getting-started\/packaging.html\">auf der Vagrant-Seite zum Packaging<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vagrant (zu Deutsch: &#8222;umherwandernd&#8220;) ist ein klasse Tool f\u00fcr verteilte Entwicklung. Muss man sich so vorstellen: Entwickler A soll soll einen Bug fixen, holt die entsprechende Vagrant-Box hervor und findet in ihr die komplette Projektumgebung wieder &#8211; Apache, MySQL, PHP &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/vagrant-tutorial\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,7,11],"tags":[],"class_list":["post-656","post","type-post","status-publish","format-standard","hentry","category-webdev","category-linux","category-misc-it"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/656","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=656"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/656\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=656"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=656"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=656"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}