How to configure HAProxy with Artifactory?

How to configure HAProxy with Artifactory?

AuthorFullName__c
JFrog Support
articleNumber
000004020
FirstPublishedDate
2017-08-15T12:45:38Z
lastModifiedDate
2025-08-27
VersionNumber
11
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: 
HAProxy TLS Termination
Certificate Generation
To begin, you'll need to generate a private key and a self-signed certificate for HAProxy to use. The following commands will create the necessary files:
openssl genrsa -out /etc/ssl/private/server.key
mkdir /etc/ssl/csr
openssl req -new -key /etc/ssl/private/server.key -out /etc/ssl/csr/server.csr
openssl x509 -req -days 365 -in /etc/ssl/csr/server.csr -signkey /etc/ssl/private/server.key -out /etc/ssl/certs/server.crt
cat /etc/ssl/certs/server.crt /etc/ssl/private/server.key > /etc/ssl/certs/server.bundle.pem
HAProxy Configuration
These instructions assume you already have a standard HTTP frontend configured in HAProxy. All changes are made in the /etc/haproxy/haproxy.cfg file.
Disable SSLv3
Due to security vulnerabilities like the POODLE attack, it's recommended to disable SSLv3. To do this globally, add the following line to the global section of your configuration file:
global
    ...
    ssl-default-bind-options no-sslv3

Create an HTTPS Frontend
Next, create a new frontend to handle HTTPS traffic. This configuration tells HAProxy to listen for SSL/TLS connections and use the certificate you generated.
frontend web-https
    bind public_ip:443 ssl crt /etc/ssl/certs/server.bundle.pem
    reqadd X-Forwarded-Proto:\ https
    rspadd Strict-Transport-Security:\ max-age=31536000
    default_backend www-backend


Here is a breakdown of the directives:

  • bind public_ip:443 ssl crt ...: This tells HAProxy to listen for requests on port 443 for the specified public IP. The ssl crt parameter points to the location of your combined certificate and key file.
  • reqadd X-Forwarded-Proto:\ https: This adds an X-Forwarded-Proto header to incoming requests.
  • rspadd Strict-Transport-Security...: This adds a security policy header to responses to help prevent protocol downgrade attacks.
  • default_backend www-backend: This specifies the default backend server pool to forward requests to.
    No changes are needed for your existing backend section.
Optional: Force HTTPS Redirection
If you want to redirect all HTTP traffic to HTTPS, add the following line to your existing HTTP frontend or backend section. The example uses the www-backend section.
redirect scheme https if !{ ssl_fc }

Restart HAProxy
After saving your configuration changes, restart the HAProxy service to apply them:
service haproxy restart
 
 
2. 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 # Recommended for closing connections cleanly
    # --- Session Persistence Configuration --- #
    # Store the cookie value and the server_id in the table.
    # Look up its value in the stick-table and route to the stored server_id.
#    stick-table type string size 1m expire 3h store server_id
#    stick store-response set-cookie(JSESSIONID)
#    stick on cookie(JSESSIONID)
#    server <artifactory-host-ha1> <artifactory-host-ha1_ip>:<artifactory-port> check
#    server <artifactory-host-ha2> <artifactory-host-ha2_ip>:<artifactory-port> check

 

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>
 
4. 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.