How to configure HAProxy with Artifactory?

How to configure HAProxy with Artifactory?

 

JFrog already provides an extensive reverse proxy support for multiple uses with Artifactory, and Artifactory even has built-in reverse proxy configuration generator.
However, currently HAProxy is yet to be included in the generator (here’s the improvement request for this), you can take advantage of our provided configurations examples and instructions below in order to utilize HAProxy with Artifactory.

 

In this knowledge base article, we will provide two snippets, one for a single instance, and another for a cluster with two nodes. Both include the configuration required for Artifactory Docker repositories.

 

When you configure a reverse proxy to work with Artifactory as a Docker registry, it is possible to choose one of two methods:

 

 

* For HA clusters, Artifactory 5.x removes the requirement of having a “mechanism that takes care of sticky sessions” for persisting UI logins between Artifactory cluster nodes.

 

* In the configuration below we will show how to work with SSL, with self-signed certificate, nevertheless, it also possible to use publicly entrusted certificates/trusted CA signed ones.

 

  1. First, you need to create a self-signed certificate for HAProxy as described here for Ubuntu, only the “Generate Certificate and Private Key” step is required.

 

*Note: while creating the certificate the common name is the most important component when generating certificates, as the FQDN of your server will have to match the DNS record of the HAProxy endpoint which will be in-front of the Artifactory server(s).

 

E.g: Public Server Name = “artifactory1” (“artifactory1” is the DNS name of the HAProxy endpoint)

 

 
2. Copy the code snippet below into /etc/haproxy/haproxy.cfg file:
* This is an example for a Docker virtual repository with Port Method, for a single Artifactory instance.

 

global
       log <Machine_IP>   local0
       chroot /var/lib/haproxy
       maxconn 4096
       user haproxy
       group haproxy
       daemon
       tune.ssl.default-dh-param 2048
       stats socket /run/haproxy/admin.sock mode 660 level admin
defaults
       log     global
       mode    http
       option  httplog
       option  dontlognull
       option  redispatch
       option  forwardfor
       option  http-server-close
       maxconn 4000
       timeout connect 5000
       timeout client 50000
       timeout server 50000
       errorfile 400 /etc/haproxy/errors/400.http
       errorfile 403 /etc/haproxy/errors/403.http
       errorfile 408 /etc/haproxy/errors/408.http
       errorfile 500 /etc/haproxy/errors/500.http
       errorfile 502 /etc/haproxy/errors/502.http
       errorfile 503 /etc/haproxy/errors/503.http
       errorfile 504 /etc/haproxy/errors/504.http
frontend normal
        bind *:80
        bind *:443 ssl crt /etc/ssl/certs/server.bundle.pem
        mode http
        option forwardfor
        reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker/v22
        reqadd X-Forwarded-Proto: https if { ssl_fc }
        option forwardfor header X-Real-IP
        default_backend normal
 
# if only need to access the docker-dev-local2 then skip this section. Docker-virtual can be configured to deploy to docker-dev-local2 frontend dockerhub
        bind *:<Docker_Virtual_Port> ssl crt /etc/ssl/certs/server.bundle.pem
        mode http
        option forwardfor
        option forwardfor header X-Real-IP
        reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker/v22
        reqadd X-Forwarded-Proto: https if { ssl_fc }
        default_backend normal

 

backend normal
        mode http
        server <Public_Server_Name> <Machine_IP>:<Port>
 
*** The snippet below is a baseline for HA cluster setup + Docker, use it in order to enable HAProxy balancing your Artifactory nodes

 

# haproxy server configuration
# version 1.0
# History
# —————————————————————————
# Features enabled by this configuration
# HA configuration
# port 80, 443  Artifactory GUI/API
#
# This uses ports to distinguish artifactory docker repositories
# port 443  docker-virtual (v2) docker v1 is redirected to docker-dev-local.
# port 5001 docker-prod-local (v1); docker-prod-local2 (v2)
# port 5002 docker-dev-local (v1); docker-dev-local2 (v2)
#
# Edit this file with required information enclosed in <…>
# 1. certificate and key
# 2. artifactory-host
# 3  replace the port numbers if needed
# —————————————————————————-
global
       log 127.0.0.1   local0
       chroot /var/lib/haproxy
       maxconn 4096
       user haproxy
       group haproxy
       daemon
       tune.ssl.default-dh-param 2048
       stats socket /run/haproxy/admin.sock mode 660 level admin
defaults
       log global
       mode http
       option  httplog
       option  dontlognull
       option  redispatch
       option  forwardfor
       option  http-server-close
       maxconn 4000
       timeout connect 5000
       timeout client 50000
       timeout server 50000
       errorfile 400 /etc/haproxy/errors/400.http
       errorfile 403 /etc/haproxy/errors/403.http
       errorfile 408 /etc/haproxy/errors/408.http
       errorfile 500 /etc/haproxy/errors/500.http
       errorfile 502 /etc/haproxy/errors/502.http
       errorfile 503 /etc/haproxy/errors/503.http
       errorfile 504 /etc/haproxy/errors/504.http
frontend normal
        bind *:80
        bind *:443 ssl crt </etc/ssl/certs/server.bundle.pem>
        mode http
        option forwardfor
        reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker-virtual/v22
        reqadd X-Forwarded-Proto: https if { ssl_fc }
        option forwardfor header X-Real-IP
        default_backend normal
 
# if only need to access the docker-dev-local2 then skip this section. Docker-virtual can be configured to deploy to docker-dev-local2 frontend dockerhub
        bind *:5000 ssl crt </etc/ssl/certs/server.bundle.pem>
        mode http
        option forwardfor
        option forwardfor header X-Real-IP
        reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker-remote/v22
        reqadd X-Forwarded-Proto: https if { ssl_fc }
        default_backend normal
 
# if only need to access the docker-dev-local2 then skip this section. Docker-virtual can be configured to deploy to docker-dev-local2 frontend dockerprod
        bind *:5001 ssl crt </etc/ssl/certs/server.bundle.pem>
        mode http
        option forwardfor
        option forwardfor header X-Real-IP
        reqirep ^([^ :]*) /v1(.*$) 1 /artifactory/api/docker/docker-prod-local/v12
        reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker-prod-local2/v22
        reqadd X-Forwarded-Proto: https if { ssl_fc }
        default_backend normal
 
# if only need to access the docker-dev-local2 then skip this section. Docker-virtual can be configured to deploy to docker-dev-local2 frontend dockerdev
        bind *:5002 ssl crt </etc/ssl/certs/server.bundle.pem>
        mode http
        option forwardfor
        option forwardfor header X-Real-IP
        reqirep ^([^ :]*) /v1(.*$) 1 /artifactory/api/docker/docker-dev-local/v12
        reqirep ^([^ :]*) /v2(.*$) 1 /artifactory/api/docker/docker-dev-local2/v22
        reqadd X-Forwarded-Proto: https if { ssl_fc }
        default_backend normal
 
# Artifactory Non HA Configuration
# i.e server artifactory 198.168.1.206:8081
#
backend normal
        mode http
        server <artifactory-host> <artifactory-host ip address>:<artifactory-host port>
 
#
# Artifactory HA Configuration
# Using default failover interval – rise = 2; fall =3 3; interval – 2 seconds
# backend normal
#     mode http
#     balance roundrobin
#     option httpchk OPTIONS /
#     option forwardfor
#     option http-server-close
#     appsession JSESSIONID len 52 timeout 3h
#     server <artifactory-host-ha1> <artifactory-host ip address>:<artifactory-host port>
#     server <artifactory-host-ha2> <artifactory-host ip address>:<artifactory-host port>

 

3. Restart HAProxy: $sudo /etc/init.d/haproxy restart

 

4. Add the following to /etc/hosts file: <Machine_IP>             <Public_Server_Name>

 

* In production environments – use DNS configuration, using the hosts file is typically only for local testing

 

5. Use this page to trust the self signed certificate with your Docker client.
Otherwise (if you are want to avoid using any certificates) add the following to /etc/default/docker file configure Docker to work with “insecure registry”:

 

DOCKER_OPTS=" –insecure-registry <Public_Server_Name>:<Repository_Port>"

 

6. Restart Docker: $sudo systemctl daemon-reload
                              $sudo systemctl restart docker

 

* $ systemctl is used in the example below due the use of Ubuntu 16.04 (which uses systemd)

 

Now everything is set and you should be able to $docker login and pull/push from/to Artifactory.

 

For more info on how to get started with Artifactory Docker registries, refer to our Wiki Page.