{"id":1491,"date":"2019-03-08T02:32:27","date_gmt":"2019-03-08T02:32:27","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw93\/?p=1491"},"modified":"2019-04-06T00:15:04","modified_gmt":"2019-04-06T00:15:04","slug":"using-jfrog-artifactory-as-docker-image-repository","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/03\/08\/using-jfrog-artifactory-as-docker-image-repository\/","title":{"rendered":"Using JFrog Artifactory as Docker Image Repository"},"content":{"rendered":"<p>This article is a continuation of <a href=\"https:\/\/rancher.com\/blog\/2018\/2018-10-29-jfrog-artifactory-p1\/\">Deploying JFrog Artifactory with Rancher<\/a>. In this chapter we\u2019ll demonstrate how to use JFrog Artifactory as a private repository for your own Docker images.<\/p>\n<p>NOTE: This feature of JFrog Artifactory requires a license, but <a href=\"https:\/\/jfrog.com\/artifactory\/free-trial\/\">you can get a 30-day<\/a> trial and use it to follow along.<\/p>\n<h2>Prepare GCP for the Deployment<\/h2>\n<p>If you plan to use Artifactory as a repository for Docker outside of your local network, you\u2019ll need a public IP address. In the first part of this article we deployed our cluster into Google Cloud, and we\u2019ll continue to use GCP resources now.<\/p>\n<p>You can reserve a public IP by running the following command in the <a href=\"https:\/\/cloud.google.com\/shell\">Google Cloud Shell<\/a> or in your local environment via the gcloud command:<\/p>\n<p>gcloud compute addresses create artifactory-demo &#8211;global<\/p>\n<p>Use the name you chose (artifactory-demo in our case) to retrieve the address:<\/p>\n<p>gcloud compute addresses describe artifactory-demo &#8211;global<\/p>\n<p>Look for the address label in the output:<\/p>\n<p>We\u2019ll use the magical <a href=\"http:\/\/xip.io\">xip.io<\/a> service from <a href=\"https:\/\/basecamp.com\">Basecamp<\/a> to assign a fully-qualifed domain name to our service, which in our case will be 35.190.61.62.xip.io.<\/p>\n<h2>Deploy Artifactory<\/h2>\n<p>You can follow the steps in the <a href=\"https:\/\/rancher.com\/blog\/2018\/2018-10-29-jfrog-artifactory-p1\/\">previous chapter<\/a> to deploy Rancher and Artifactory, but when you reach the part about configuring the variables in the app deployment page, add or change the following variables:<\/p>\n<p>ingress.enabled=true<br \/>\ningress.hosts[0]=35.190.61.62.xip.io<br \/>\nartifactory.service.type=NodePort<br \/>\nnginx.enabled=false<br \/>\ningress.annotations.&#8221;kubernetes.io\/ingress.global-static-ip-name&#8221;=artifactory-demo<\/p>\n<p>(You can copy\/paste that block of text into a field, and Rancher will convert it for you.)<\/p>\n<p>When all is done, it should look like the image below:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-docker-variables.png\" alt=\"Artifactory Docker Registry Configs\" \/><\/p>\n<p>Click <em>Launch<\/em> to begin deploying the resources.<\/p>\n<h3>An Explanation of the Variables<\/h3>\n<p>While your new Artifactory instance spins up, let\u2019s look at what we just configured.<\/p>\n<h4>ingress.enabled=true<\/h4>\n<p>This enables the creation of an <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/ingress\/\">ingress resource<\/a>, which will serve as a proxy for Artifactory. In our case the Ingress will be a load balancer within GCP.<\/p>\n<h4>ingress.hosts[0]=35.190.61.62.xip.io<\/h4>\n<p>This sets the hostname for Artifactory. Part of the magic of xip.io is that we can create any subdomain and have it resolve back to the IP, so when we use docker-demo.35.190.61.62.xip.io later in this walkthrough, it will resolve to 35.190.61.62.<\/p>\n<h4>artifactory.service.type=NodePort<\/h4>\n<p>This exposes Artifactory\u2019s service via a random port on the Kubernetes node. The Ingress resource will send traffic to this port.<\/p>\n<h4>nginx.enabled=false<\/h4>\n<p>Because we\u2019re using the Ingress resource to talk to Artifactory via the Service resource, we want to disable the nginx proxy that Artifactory would otherwise start.<\/p>\n<h4>ingress.annotations&#8230;<\/h4>\n<p>This is the glue that ties Kubernetes to the static public IP address. We set this to the name of the address that you reserved so that the Ingress finds and uses the correct IP. We had to escape a large part of it because that\u2019s the <em>name<\/em> of the annotation. Without escaping the elements, Kubernetes would misunderstand what we were asking it to do.<\/p>\n<h2>Review the Deployment<\/h2>\n<p>Once the deployment completes, look at the <em>Workloads<\/em> tab. There you will see two workloads. One is the application (artifactory-artifactory), and the other is the PostgreSQL database that artifactory uses (artifactory-postgresql).<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-workloads.png\" alt=\"Artifactory Workloads\" \/><\/p>\n<p>Look at the <em>Load Balancing<\/em> tab next. There you will see the Ingress object with the hostname that we provided.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-load-balancing.png\" alt=\"Load Balancing Ingress\" \/><\/p>\n<p>If you select <em>View\/Edit YAML<\/em> and scroll to the bottom, you will see the annotation that points to the address name in GCP (line 10 in the image):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/load-balancer-view-yaml.png\" alt=\"Load Balancer View YAML\" \/><\/p>\n<p>At the bottom of the Ingress definition you will also see that the hostname in spec.rules.host matches the IP address from status.loadBalancer.ingress.ip at the bottom.<\/p>\n<h2>Configure Artifactory<\/h2>\n<p>When you close the <em>View\/Edit YAML<\/em> window, you\u2019ll return to the <em>Load Balancing<\/em> tab. There you\u2019ll find a link with the xip.io address. Click it to open Artifactory, or just enter the hostname into your browser.<\/p>\n<p>Click through the wizard, first adding your license key and then setting an admin password. Click through the rest until the wizard completes.<\/p>\n<p>In the menu on the left side, select <em>Admin<\/em>, and then under <em>Repositories<\/em> select <em>Local<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-admin-local-repo.png\" alt=\"Artifactory Admin Local Repo\" \/><\/p>\n<p>There you will see the default repository created by the setup wizard. Select <em>+ New<\/em> from the upper right corner to create a new repository. Choose <em>Docker<\/em> as the package type and enter a name for the repository. In our case we chose docker-demo. Leave everything else at the defaults and select <em>Save &amp; Finish<\/em> to create the new repository.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-create-docker-registry.png\" alt=\"Artifactory create docker registry\" \/><\/p>\n<p>The name that you chose (docker-demo for us) becomes the subdomain for your xip.io domain. For our installation, we\u2019ll be using docker-demo.35.190.61.62.xip.io. Yours will of course be different, but it will follow the same format.<\/p>\n<h2>Test the Registry<\/h2>\n<p>What fun is it to have a private Docker repository if you don\u2019t use it?<\/p>\n<p>For a production deployment you would secure the registry with an SSL certificate, and that would require a real hostname on a real domain. For this walkthrough, though, you can use the newly-created registry by telling Docker that it\u2019s an <a href=\"https:\/\/docs.docker.com\/registry\/insecure\/\">insecure registry<\/a>.<\/p>\n<p>Create or edit daemon.json according to the <a href=\"https:\/\/docs.docker.com\/registry\/insecure\/\">documentation<\/a>, adding your host like we do in the following example:<\/p>\n<p>{<br \/>\n&#8220;insecure-registries&#8221;: [&#8220;docker-demo.35.190.61.62.xip.io:80&#8221;]<br \/>\n}<\/p>\n<p>If you use Docker for Mac or Docker for Windows, set this in the preferences for the application:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/docker-for-mac-insecure-registry.png\" alt=\"Docker for Mac Insecure Registry\" \/><\/p>\n<p>Restart Docker for it to pick up the changes, and after it restarts, you can use the registry:<\/p>\n<p>docker login docker-demo.35.190.61.62.xip.io<br \/>\nUsername: admin<br \/>\nPassword:<br \/>\nLogin Succeeded<\/p>\n<p>To continue with the test, we\u2019ll pull a public container image, re-tag it, and then push it to the new private registry.<\/p>\n<h3>Pull a Public Container Image<\/h3>\n<p>$ docker pull nginx<br \/>\nUsing default tag: latest<br \/>\nlatest: Pulling from library\/nginx<br \/>\nf17d81b4b692: Pull complete<br \/>\nd5c237920c39: Pull complete<br \/>\na381f92f36de: Pull complete<br \/>\nDigest: sha256:b73f527d86e3461fd652f62cf47e7b375196063bbbd503e853af5be16597cb2e<br \/>\nStatus: Downloaded newer image for nginx:latest<\/p>\n<h3>Re-tag the Image<\/h3>\n<p>You can see the current image id and information on your system:<\/p>\n<p>$ docker images<br \/>\nREPOSITORY TAG IMAGE ID CREATED SIZE<br \/>\nnginx latest dbfc48660aeb 2 days ago 109MB<\/p>\n<p>Re-tag it so that Docker knows to push it to your new private registry:<\/p>\n<p>$ docker tag nginx docker-demo.35.190.61.62.xip.io:80\/nginx:latest<\/p>\n<h3>Push the Image to the Private Registry<\/h3>\n<p>With the image re-tagged, use docker push to send it to your private registry:<\/p>\n<p>$ docker push docker-demo.35.190.61.62.xip.io:80\/nginx:latest<br \/>\nThe push refers to repository [docker-demo.35.190.61.62.xip.io:80\/nginx]<br \/>\n86df2a1b653b: Pushed<br \/>\nbc5b41ec0cfa: Pushed<br \/>\n237472299760: Pushed<br \/>\nlatest: digest: sha256:d98b66402922eccdbee49ef093edb2d2c5001637bd291ae0a8cd21bb4c36bebe size: 948<\/p>\n<h3>Verify the Push in Artifactory<\/h3>\n<p>Back in the Artifactory UI, select <em>Artifacts<\/em> from the menu.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-artifacts.png\" alt=\"Artifactory Artifacts\" \/><\/p>\n<p>There you\u2019ll see your nginx image and information about it.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/rancher.com\/img\/blog\/2018\/artifactory-pushed-image.png\" alt=\"Artifactory Pushed Image\" \/><\/p>\n<h2>Next Steps<\/h2>\n<p>If you have an Artifactory License and want to run a private registry, repeat this walkthrough using your own domain and an SSL certificate on the ingress. With those additional items complete, you\u2019ll be able to use the private registry with any Docker or Kubernetes installation without having to tell the host that it has permission to talk to an insecure registry.<\/p>\n<h2>Cleanup<\/h2>\n<p>To clean up the resources that we used in this article, delete the Kubernetes cluster from Rancher and then delete the Rancher server from GCP:<\/p>\n<p>gcloud compute &#8211;project=rancher-20 instances delete<br \/>\nrancher-instance &#8211;zone=europe-west2-c<\/p>\n<p>You\u2019ll also need to delete the public IP address reservation:<\/p>\n<p>gcloud compute addresses delete artifactory-demo &#8211;global<\/p>\n<h2>Closing<\/h2>\n<p>JFrog Artifactory provides services that are at the core of a development lifecycle. You can store and retrieve almost any type of artifact that your development teams produce, and having these artifacts stored in a central, managed location makes Artifactory an important part of any IT infrastructure.<\/p>\n<p><a href=\"https:\/\/rancher.com\">Rancher<\/a> makes it easy to deploy Artifactory into a Kubernetes installation. In only a few minutes we had Artifactory up and running, and it actually took longer to configure Artifactory itself than it did to install it!<\/p>\n<p>Rancher makes Kubernetes <em>easy<\/em>. Artifactory makes managing binary resources easy. Together they free you to focus on the things that matter for your business, and that freedom is what matters most.<\/p>\n<p><a href=\"https:\/\/rancher.com\/blog\/2018\/2018-11-05-jfrog-artifactory-part-two\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article is a continuation of Deploying JFrog Artifactory with Rancher. In this chapter we\u2019ll demonstrate how to use JFrog Artifactory as a private repository for your own Docker images. NOTE: This feature of JFrog Artifactory requires a license, but you can get a 30-day trial and use it to follow along. Prepare GCP for &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/03\/08\/using-jfrog-artifactory-as-docker-image-repository\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using JFrog Artifactory as Docker Image Repository&#8221;<\/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],"tags":[],"class_list":["post-1491","post","type-post","status-publish","format-standard","hentry","category-kubernetes"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1491","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=1491"}],"version-history":[{"count":2,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1491\/revisions"}],"predecessor-version":[{"id":1542,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1491\/revisions\/1542"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=1491"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=1491"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=1491"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}