How do I access multiple Artifactory Docker repositories from a single URL?

It is possible to configure a reverse proxy in such a way that an image can be tagged with the repository name and the reverse proxy can route such requests to the appropriate Artifactory Docker repository. 

Subdomain Method Solution

The optimal solution would be to utilize our provided subdomain method along with our generated reverse proxy configuration. This method does require a wildcard certificate, if obtaining a wildcard certificate is not possible, you may use the alternative solution described below with a single URL certificate.

Alternative Solution

The alternative solution works by embedding the repository name in the image name as opposed to the registry url. 

The workflow would then look like this:

docker tag <image> <artifactory-reverse-proxy-url>/<repo-name>/<optional-namespace>/<image-name>

docker push <artifactory-reverse-proxy-url>/<repo-name>/<optional-namespace>/<image-name>


This would result in a new image created in the Artifactory repository <repo-name> with the path <optional-namespace>/<image-name>.


Here is a more concrete example:


docker tag busybox example.com/dockerv2/busybox

docker push example.com/dockerv2/busybox


Requirements: Apache 2.4+

See Required modules for Apache.

Implementation


1. Create a local docker repository named docker-login 

2. Modify the VirtualHost entry with your details (replace all <value> – There are 15)

3. Apply the Apache configuration and restart Apache


  Listen <port#>

<VirtualHost *:<port#>>

    ProxyPreserveHost On


    ServerName <apache-server-name>

    ServerAdmin server@admin


    SSLEngine on

    SSLCertificateFile <cert-file-location>

    SSLCertificateKeyFile <cert-key-file-location>


    RewriteEngine on


    RewriteCond %{SERVER_PORT} (.*)

    RewriteRule (.*) – [E=my_server_port:%1]


    RewriteCond %{REQUEST_SCHEME} (.*)

    RewriteRule (.*) – [E=my_scheme:%1]


    RewriteCond %{HTTP_HOST} (.*)

    RewriteRule (.*) – [E=my_custom_host:%1]


    RewriteCond “%{REQUEST_URI}” “^/v2/(.*?)/”

    RewriteRule “^/v2/.*?/(.*)$” “/api/docker/%1/v2/$1” [PT,E=repo:%1]


    RewriteRule ^/v2/$ <art-URL>/artifactory/api/docker/docker-login/v2/ [P]

    RewriteRule ^/v2/token$ <art-URL>/artifactory/api/docker/docker-login/v2/token [P]


    RequestHeader set Host <apache-server-name>/%{repo}e

    RequestHeader set X-Forwarded-Port %{my_server_port}e

    RequestHeader set X-Forwarded-Proto %{my_scheme}e

    RequestHeader set X-Artifactory-Override-Base-Url %{my_scheme}e://<apache-server-name>:<port#>

    ProxyPassReverseCookiePath /artifactory /


    Header edit* Location “^https://<apache-server-name>/(.*?)/v2/(.*)$” “https://<apache-server-name>:<port#>/v2/$1/$2″

    ProxyRequests off

    ProxyPass / <art-URL>/artifactory/

    ProxyPassReverse / <art-URL>/artifactory/

</VirtualHost>  


Example (Proxy port: 5000, apache-server-name: jfrog-docker, art-URL: http://192.168.99.100:8081):

Listen 5000<VirtualHost *:5000>    ProxyPreserveHost On    ServerName jfrog-docker.com    ServerAdmin server@admin    SSLEngine on    SSLCertificateFile /etc/ssl/demo.pem    SSLCertificateKeyFile /etc/ssl/demo.key    RewriteEngine on    RewriteCond %{SERVER_PORT} (.*)    RewriteRule (.*) - [E=my_server_port:%1]    RewriteCond %{REQUEST_SCHEME} (.*)    RewriteRule (.*) - [E=my_scheme:%1]    RewriteCond %{HTTP_HOST} (.*)    RewriteRule (.*) - [E=my_custom_host:%1]    RewriteCond "%{REQUEST_URI}" "^/v2/(.*?)/"    RewriteRule "^/v2/.*?/(.*)$" "/api/docker/%1/v2/$1" [PT,E=repo:%1]    RewriteRule ^/v2/$ http://192.168.99.100:8081/artifactory/api/docker/docker-login/v2/ [P]    RewriteRule ^/v2/token$ http://192.168.99.100:8081/artifactory/api/docker/docker-login/v2/token [P]    RequestHeader set Host jfrog-docker.com/%{repo}e    RequestHeader set X-Forwarded-Port %{my_server_port}e    RequestHeader set X-Forwarded-Proto %{my_scheme}e    RequestHeader set X-Artifactory-Override-Base-Url %{my_scheme}e://jfrog-docker.com:5000    ProxyPassReverseCookiePath /artifactory /    Header edit* Location "^https://jfrog-docker.com/(.*?)/v2/(.*)$" "https://jfrog-docker.com:5000/v2/$1/$2"    ProxyRequests off    ProxyPass / http://192.168.99.100:8081/artifactory/    ProxyPassReverse / http://192.168.99.100:8081/artifactory/</VirtualHost>  

 


A note about permissions and the repository docker-login:

The repository docker-login is needed to allow users the ability to login. The login is only required once and will provide a token that identifies the particular user that logged in. This token will then be supplied regardless of the repository the user is pushing or pulling from. These pull/push requests will follow the permissions the user has to those particular repositories and not to the repository docker-login, so permissions will work as expected.