{"id":809,"date":"2020-07-29T10:23:38","date_gmt":"2020-07-29T10:23:38","guid":{"rendered":"https:\/\/blog.samarthya.me\/wps\/?p=809"},"modified":"2022-12-05T18:59:27","modified_gmt":"2022-12-05T18:59:27","slug":"docker-registry","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2020\/07\/29\/docker-registry\/","title":{"rendered":"Docker Registry"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>A Docker registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images.<\/p>\n<\/blockquote>\n\n\n\n<p>Docker registry is a central location that stores and distributes docker images. E.g. hub.docker.com is the default registry used when you are using <code>docker pull<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why use a docker registry?<\/h2>\n\n\n\n<p>The reason can be any, but primarily it is have tighter control over how you distribute your images, and who downloads them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to Run a Registry?<\/h3>\n\n\n\n<p>It is a simple image that you can execute using <code>docker run<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d -p 5000:5000 --name registry registry:latest<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Adding an image to your registry<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/docs.docker.com\/registry\/configuration\/#override-specific-configuration-options\">Configuring registry<\/a><\/h3>\n\n\n\n<p>Registry configuration like other files in docker universe is a YAML file, and can be accessed (for specific options) by supplying <code>-e<\/code> option and creating an environment like <code>REGISTRY_variable<\/code> where <code>variable<\/code> is the name of the option.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d -p 5000:5000 --restart=always --name registry -e REGISTRY_LOG_LEVEL=debug -e REGISTRY_HTTP_SECRET=abcdef12345 registry:2<\/code><\/pre>\n\n\n\n<p>The command outputs a hash.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>d50064a4bb16155711241ff14e0e94dfa17e5e3bbc9136d555dd63e3243cc5f<\/code><\/pre>\n\n\n\n<p>Let&#8217;s see if it has been honored<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs registry<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>time=\"2020-07-29T10:20:02.676285386Z\" level=info msg=\"redis not configured\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:02.676607678Z\" level=info msg=\"Starting upload purge in 20m0s\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:02.68618669Z\" level=info msg=\"using inmemory blob descriptor cache\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:02.686740221Z\" level=info msg=\"listening on &#91;::]:5000\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \n&#91;root@mundev001685 ~]# docker logs registry\ntime=\"2020-07-29T10:20:02.676285386Z\" level=info msg=\"redis not configured\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:02.676607678Z\" level=info msg=\"Starting upload purge in 20m0s\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:02.68618669Z\" level=info msg=\"using inmemory blob descriptor cache\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:02.686740221Z\" level=info msg=\"listening on &#91;::]:5000\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry version=v2.7.1 \ntime=\"2020-07-29T10:20:12.687141013Z\" level=debug msg=\"filesystem.Stat(\"\/\")\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry trace.duration=83.533\u00b5s trace.file=\"\/go\/src\/github.com\/docker\/distribution\/registry\/storage\/driver\/base\/base.go\" trace.func=\"github.com\/docker\/distribution\/registry\/storage\/driver\/base.(*Base).Stat\" trace.id=c5040120-f1fc-4ee2-9b42-9549e6e8535e trace.line=155 version=v2.7.1 \ntime=\"2020-07-29T10:20:22.687191951Z\" level=debug msg=\"filesystem.Stat(\"\/\")\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry trace.duration=66.546\u00b5s trace.file=\"\/go\/src\/github.com\/docker\/distribution\/registry\/storage\/driver\/base\/base.go\" trace.func=\"github.com\/docker\/distribution\/registry\/storage\/driver\/base.(*Base).Stat\" trace.id=55c23278-9c49-4409-84fb-286a013d3fb1 trace.line=155 version=v2.7.1 \ntime=\"2020-07-29T10:20:32.687172108Z\" level=debug msg=\"filesystem.Stat(\"\/\")\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry trace.duration=70.495\u00b5s trace.file=\"\/go\/src\/github.com\/docker\/distribution\/registry\/storage\/driver\/base\/base.go\" trace.func=\"github.com\/docker\/distribution\/registry\/storage\/driver\/base.(*Base).Stat\" trace.id=7fb56ccb-f9be-4727-bf78-0fb43283f5da trace.line=155 version=v2.7.1 \ntime=\"2020-07-29T10:20:42.687180724Z\" level=debug msg=\"filesystem.Stat(\"\/\")\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry trace.duration=75.809\u00b5s trace.file=\"\/go\/src\/github.com\/docker\/distribution\/registry\/storage\/driver\/base\/base.go\" trace.func=\"github.com\/docker\/distribution\/registry\/storage\/driver\/base.(*Base).Stat\" trace.id=6ad9561c-d1f2-4ab6-bd19-3cbd5e58eaca trace.line=155 version=v2.7.1 <\/code><\/pre>\n\n\n\n<p>Voila you can see a debug message at the bottom<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>time=\"2020-07-29T10:20:32.687172108Z\" level=debug msg=\"filesystem.Stat(\"\/\")\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry trace.duration=70.495\u00b5s trace.file=\"\/go\/src\/github.com\/docker\/distribution\/registry\/storage\/driver\/base\/base.go\" trace.func=\"github.com\/docker\/distribution\/registry\/storage\/driver\/base.(*Base).Stat\" trace.id=7fb56ccb-f9be-4727-bf78-0fb43283f5da trace.line=155 version=v2.7.1 \ntime=\"2020-07-29T10:20:42.687180724Z\" level=debug msg=\"filesystem.Stat(\"\/\")\" go.version=go1.11.2 instance.id=a3eab61f-dfc3-481e-bff5-d5148bed033b service=registry trace.duration=75.809\u00b5s trace.file=\"\/go\/src\/github.com\/docker\/distribution\/registry\/storage\/driver\/base\/base.go\" trace.func=\"github.com\/docker\/distribution\/registry\/storage\/driver\/base.(*Base).Stat\" trace.id=6ad9561c-d1f2-4ab6-bd19-3cbd5e58eaca trace.line=155 version=v2.7.1 <\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">TLS security<\/h3>\n\n\n\n<p>Let&#8217;s add some SSL security to the docker registry. <code>Step - 1<\/code>, let&#8217;s generate the certificate.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs\/domain.key -x509 -days 365 -out certs\/domain.crt<\/code><\/pre>\n\n\n\n<p>Now let&#8217;s use this cert to supply to the <code>docker run<\/code> command<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d -p 443:443 --restart=always --name registry   -v \/root\/docker\/certs:\/certs  -e REGISTRY_HTTP_ADDR=0.0.0.0:443   -e REGISTRY_HTTP_TLS_CERTIFICATE=\/certs\/domain.crt   -e REGISTRY_HTTP_TLS_KEY=\/certs\/domain.key registry:2<\/code><\/pre>\n\n\n\n<p>As always it should show a has representation of the container spawned.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>476848e839e456a750a1869373d2b34d14654ed6b18772292324bbc9d4621150<\/code><\/pre>\n\n\n\n<p>Look at the logs by calling <code>docker logs registry<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>time=\"2020-07-29T10:31:57.015857606Z\" level=warning msg=\"No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.015945659Z\" level=info msg=\"redis not configured\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.016037915Z\" level=info msg=\"Starting upload purge in 31m0s\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.025659641Z\" level=info msg=\"using inmemory blob descriptor cache\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.027103156Z\" level=info msg=\"listening on &#91;::]:443, tls\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 <\/code><\/pre>\n\n\n\n<p>Check for <code>https<\/code> request <code>curl -k https:\/\/localhost:443<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs registry<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>time=\"2020-07-29T10:31:57.015857606Z\" level=warning msg=\"No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.015945659Z\" level=info msg=\"redis not configured\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.016037915Z\" level=info msg=\"Starting upload purge in 31m0s\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.025659641Z\" level=info msg=\"using inmemory blob descriptor cache\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \ntime=\"2020-07-29T10:31:57.027103156Z\" level=info msg=\"listening on &#91;::]:443, tls\" go.version=go1.11.2 instance.id=37c25acb-a673-458b-9f40-5632b2ccb6c2 service=registry version=v2.7.1 \n172.17.0.1 - - &#91;29\/Jul\/2020:10:32:20 +0000] \"GET \/ HTTP\/1.1\" 200 0 \"\" \"curl\/7.29.0\"<\/code><\/pre>\n\n\n\n<p>Look at the last line.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>172.17.0.1 - - &#91;29\/Jul\/2020:10:32:20 +0000] \"GET \/ HTTP\/1.1\" 200 0 \"\" \"curl\/7.29.0\"<\/code><\/pre>\n\n\n\n<p>Let&#8217;s add some basic authentication to the registry as well. I am working on a Centos 7.6 VM, so first requirement was to add the <code>htpasswd<\/code> dependency.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>yum install httpd-tools<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt; htpasswd\nUsage:\n        htpasswd &#91;-cimB25dpsDv] &#91;-C cost] &#91;-r rounds] passwordfile username\n        htpasswd -b&#91;cmB25dpsDv] &#91;-C cost] &#91;-r rounds] passwordfile username password\n\n        htpasswd -n&#91;imB25dps] &#91;-C cost] &#91;-r rounds] username\n        htpasswd -nb&#91;mB25dps] &#91;-C cost] &#91;-r rounds] username password\n -c  Create a new file.\n -n  Don't update file; display results on stdout.\n -b  Use the password from the command line rather than prompting for it.\n -i  Read password from stdin without verification (for script usage).\n -m  Force MD5 encryption of the password (default).\n -2  Force SHA-256 crypt() hash of the password (secure).\n -5  Force SHA-512 crypt() hash of the password (secure).\n -B  Force bcrypt aencryption of the password (very secure).\n -C  Set the computing time used for the bcrypt algorithm\n     (higher is more secure but slower, default: 5, valid: 4 to 31).\n -r  Set the number of rounds used for the SHA-256, SHA-512 algorithms\n     (higher is more secure but slower, default: 5000).\n -d  Force CRYPT encryption of the password (8 chars max, insecure).\n -s  Force SHA-1 encryption of the password (insecure).\n -p  Do not encrypt the password (plaintext, insecure).\n -D  Delete the specified user.\n -v  Verify password for the specified user.\nOn other systems than Windows and NetWare the '-p' flag will probably not work.\nThe SHA-1 algorithm does not use a salt and is less secure than the MD5 algorithm.<\/code><\/pre>\n\n\n\n<p>make a <code>auth<\/code> directory<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir auth<\/code><\/pre>\n\n\n\n<p>Use the following command to generate password<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run --entrypoint htpasswd registry -Bbn admin password &gt; auth\/htpasswd<\/code><\/pre>\n\n\n\n<p>A catch with changes to registry image if you simply use the above command you may get an error like below<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused \"exec: \\\"htpasswd\\\": executable file not found in $PATH\": unknown.\nERRO&#91;0000] error waiting for container: context canceled <\/code><\/pre>\n\n\n\n<p>This error can be circumvented by using the version <code>2.7.0<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run --entrypoint htpasswd registry:2.7.0 -Bbn admin password &gt; auth\/htpasswd<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>cat auth\/htpasswd \n\nadmin:$2y$05$xxS3Jj8ZG1JFc7sipI5NQeAgfgJS9V80kbF7zDtFous.VjQe8vqNy<\/code><\/pre>\n\n\n\n<p>With some additions to the command with TLS configuration we are ready to launch<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -d -p 443:443 --restart=always --name registry   -v \/root\/docker\/certs:\/certs -v \/root\/docker\/auth:\/auth  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_AUTH=htpasswd -e REGISTRY_AUTH_HTPASSWD_PATH=\/auth\/htpasswd -e \"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm\" -e REGISTRY_HTTP_TLS_CERTIFICATE=\/certs\/domain.crt   -e REGISTRY_HTTP_TLS_KEY=\/certs\/domain.key registry:2<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker logs registry<\/code><\/pre>\n\n\n\n<p>time=&#8221;2020-07-29T11:01:21.52091005Z&#8221; level=warning msg=&#8221;No HTTP secret provided &#8211; generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.&#8221; go.version=go1.11.2 instance.id=6df183de-4a59-4465-baea-90d07ca4b1f8 service=registry version=v2.7.1<br>time=&#8221;2020-07-29T11:01:21.521019306Z&#8221; level=info msg=&#8221;redis not configured&#8221; go.version=go1.11.2 instance.id=6df183de-4a59-4465-baea-90d07ca4b1f8 service=registry version=v2.7.1<br>time=&#8221;2020-07-29T11:01:21.521165669Z&#8221; level=info msg=&#8221;Starting upload purge in 16m0s&#8221; go.version=go1.11.2 instance.id=6df183de-4a59-4465-baea-90d07ca4b1f8 service=registry version=v2.7.1<br>time=&#8221;2020-07-29T11:01:21.530893238Z&#8221; level=info msg=&#8221;using inmemory blob descriptor cache&#8221; go.version=go1.11.2 instance.id=6df183de-4a59-4465-baea-90d07ca4b1f8 service=registry version=v2.7.1<br>time=&#8221;2020-07-29T11:01:21.53268731Z&#8221; level=info msg=&#8221;listening on [::]:443, tls&#8221; go.version=go1.11.2 instance.id=6df183de-4a59-4465-baea-90d07ca4b1f8 service=registry version=v2.7.1<\/p>\n\n\n\n<p>It is a self signed certificate and if you try <code>docker login<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker login myserver.local.net<\/code><\/pre>\n\n\n\n<p>You might get an error like below<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>x509: certificate signed by unknown authority<\/code><\/pre>\n\n\n\n<p>It is because the local Docker <code>dameon<\/code> doesn&#8217;t trust this certificate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to go around it?<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Disable Certificate Validation [Not recommended]<\/h4>\n\n\n\n<p>You can rely on defining <code>insecure-registries<\/code> option for <code>\/etc\/docker\/daemon.json<\/code> file and restarting the daemon.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"insecure-registries\" : &#91;\"myserver.local.net\"]\n}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl restart docker<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker info<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>.....\n Insecure Registries:\n  myserver.local.net\n  127.0.0.0\/8\n Live Restore Enabled: false<\/code><\/pre>\n\n\n\n<p>Once the changes reflect you can do <code>docker login<\/code> for the server and you can see following message.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Username: admin\nPassword: \nWARNING! Your password will be stored unencrypted in \/root\/.docker\/config.json.\nConfigure a credential helper to remove this warning. See\nhttps:&#47;&#47;docs.docker.com\/engine\/reference\/commandline\/login\/#credentials-store\n\nLogin Succeeded<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Copy the public cert<\/h3>\n\n\n\n<p>Remember when we used <code>openssl<\/code> to generate the certificate <code>domain.crt<\/code> this is the cert we need to copy to a specific location.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/etc\/docker\/certs.d\/myserver.local.net\/<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>cp certs\/domain.crt \/etc\/docker\/certs.d\/myserver.local.net\/domain.crt<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker login myserver.local.net<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Username: admin\nPassword: \nWARNING! Your password will be stored unencrypted in \/root\/.docker\/config.json.\nConfigure a credential helper to remove this warning. See\nhttps:&#47;&#47;docs.docker.com\/engine\/reference\/commandline\/login\/#credentials-store<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Adding images<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>docker tag ubuntu myserver.local.net\/ubuntu:latest<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker push myserver.local.net\/ubuntu:latest<\/code><\/pre>\n\n\n\n<p>Remove the local images using <code>docker rm<\/code> <code>image name<\/code> and finally<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker pull myserver.local.net\/ubuntu<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>https:\/\/docs.docker.com\/registry\/insecure\/<\/li>\n\n\n\n<li>https:\/\/docs.docker.com\/registry\/configuration<\/li>\n\n\n\n<li>https:\/\/docs.docker.com\/engine\/reference\/commandline\/search\/<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Docker registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images. Docker registry is a central location that stores and distributes docker images. E.g. hub.docker.com is the default registry used when you are using docker pull. Why use a docker registry? The reason can be any, but [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":811,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[86],"tags":[82,87],"class_list":["post-809","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-docker","tag-docker","tag-registry","post_format-post-format-image"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=809"}],"version-history":[{"count":1,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/809\/revisions"}],"predecessor-version":[{"id":2390,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/809\/revisions\/2390"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/811"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}