How to configure HAProxy with Artifactory?

How to configure HAProxy with Artifactory?

AuthorFullName__c
JFrog Support
articleNumber
000004020
ft:sourceType
Salesforce
FirstPublishedDate
2017-08-15T12:45:38Z
lastModifiedDate
2021-04-27
VersionNumber
8

JFrog already provides extensive reverse proxy support for multiple uses of Artifactory. The application even has a built-in Reverse Proxy Configuration Generator. Nevertheless, if you’d like to use HAProxy with Artifactory, the following instructions and Artifactory Docker repository configuration examples – one for a single instance and the other for a cluster with two nodes – may help you in your efforts.

When you’re configuring a reverse proxy to work with Artifactory as a Docker registry, you can choose one of two options:

  1. The Ports Method
  2. The Subdomain Method

In the configuration below, although we’ll show you how to work with a self-signed SSL certificate, be aware that you can also use a signed publicly trusted CA certificate.

  1. First, create a self-signed certificate for your HAProxy as described HERE (for Ubuntu). Note: Only the Generate Certificate and Private Key step is required. Also, when you are creating the certificate, the common name is the most important component, as the FQDN of your server must match the DNS record of the HAProxy endpoint, which will be in front of your Artifactory server(s). In other words, if your public server name is artifactory1, then artifactory1 must be the DNS name for your HAProxy endpoint.

 

  1. Copy the code and paste the code below into the /etc/haproxy/haproxy.cfg file. Note: This is an example for a Docker virtual repository using the 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

Note: If you only need to access docker-dev-local2, then skip the following boxed section. However, while configuring the docker-virtual repository, you can select docker-dev-local2 as your Default Deployment Repository to store the images:       
 

 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>

Note: The code snippet below is a baseline for an HA cluster, as well as a Docker setup. Use it to enable HAProxy balancing of 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

Note: If you only need to access docker-dev-local2, then skip the following boxed section. However, while configuring the docker-virtual repository, you can select docker-dev-local2 as your Default Deployment Repository to store the images.       

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

Note: If you only need to access docker-dev-local2, then skip the following boxed section.        

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

Note: If you only need to access docker-dev-local2, then skip the following boxed section. However, while configuring the docker-virtual repository, you can select docker-dev-local2 as your Default Deployment Repository to store the images.       

 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>

 

  1. Restart HAProxy: $sudo /etc/init.d/haproxy restart
  2. Add the following to the  /etc/hosts file: <Machine_IP>             <Public_Server_Name>
    Note
    : In production environments, use your DNS configuration, as the hosts file is typically used only for local testing.
  3. Information on how to use a self-signed certificate with your Docker client can be found HERE. If you’d like to avoid using any certificates, add the following to your /etc/default/docker file, which will configure Docker to work with an insecure registry:

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

  1. Restart Docker: $sudo systemctl daemon-reload

                              $sudo systemctl restart docker

Note: $ systemctl was used in the example above due to the use of Ubuntu 16.04 (which uses systemd).

You should now be able to execute $docker login and pulls to/pushes from Artifactory.

More information on how to get started with Artifactory Docker registries is available HERE.