diff --git a/dev.playbook.yml b/dev.playbook.yml
index 0484e819c6a852f1aa755184f0baf6a255dee8de..b9f2842646f0037e4e28dd571acbce4a49fddfa8 100644
--- a/dev.playbook.yml
+++ b/dev.playbook.yml
@@ -26,6 +26,9 @@
     - minimum_memory
     - system-tweaks-nepeta
     - lockss
+    - lockss-config-frontend
   tasks:
+    - debug:
+        msg: "Web front-end: http://{{ hostname }}/"
     - debug:
         msg: "LOCKSS UI password: {{ lockss_ui_password }}"
diff --git a/roles/lockss-config-frontend/defaults/main.yml b/roles/lockss-config-frontend/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb117b29c295dea3c63297f8a0f064c17b655b
--- /dev/null
+++ b/roles/lockss-config-frontend/defaults/main.yml
@@ -0,0 +1,3 @@
+---
+
+lockss_frontend_port: 80
diff --git a/roles/lockss-config-frontend/tasks/main.yml b/roles/lockss-config-frontend/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a7fb40c9fae834a8bcc696eb3f41e950793b9535
--- /dev/null
+++ b/roles/lockss-config-frontend/tasks/main.yml
@@ -0,0 +1,32 @@
+---
+
+- name: Install configuration file.
+  template:
+    dest: /root/ingress-httpd.conf
+    src: httpd.conf.j2
+    owner: root
+    mode: 0644
+
+- name: Add ferm rule.
+  template:
+    dest: /etc/ferm.d/11-in-lockss-frontend.ferm
+    src: 11-in-lockss-frontend.ferm.j2
+    validate: ferm -n %s
+
+- service:
+    name: ferm
+    state: restarted
+
+- name: Remove ingress Docker container.
+  command:
+    cmd: docker rm -f apache
+  ignore_errors: true
+
+- name: Create ingress Docker container.
+  command:
+    cmd: docker run -d --rm
+         --name apache
+         -p 80:80
+         --network host
+         -v /root/ingress-httpd.conf:/usr/local/apache2/conf/httpd.conf
+         httpd:2.4
diff --git a/roles/lockss-config-frontend/tasks/main.yml-v_nginx b/roles/lockss-config-frontend/tasks/main.yml-v_nginx
new file mode 100644
index 0000000000000000000000000000000000000000..17151cd3bebb34a80f48e2b1522b58b76ce340b5
--- /dev/null
+++ b/roles/lockss-config-frontend/tasks/main.yml-v_nginx
@@ -0,0 +1,49 @@
+---
+
+- name: Place configuration file.
+  copy:
+    dest: /root/ingress.conf
+    owner: root
+    mode: 0644
+    content: |
+      server {
+          listen 80;
+          location /config/ {
+              sub_filter
+                  "{{ lockss_hostname }}:24621"
+                  "{{ lockss_hostname }}/config";
+              sub_filter
+                  "{{ lockss_hostname }}:24621"
+                  "{{ lockss_hostname }}/config";
+              sub_filter_once off;
+              proxy_pass http://127.0.0.1:24621/;
+              proxy_set_header Accept-Encoding "";
+          }
+      }
+
+- name: Add ferm rule.
+  copy:
+    dest: /etc/ferm.d/11-in-lockss-frontend.ferm
+    content: |
+      @def $MGMT_NET = ({{ lockss_admin_ips | join(" ") }});
+      domain (ip ip6) table filter chain INPUT
+          saddr $MGMT_NET proto tcp dport 80 ACCEPT;
+    validate: ferm -n %s
+
+- service:
+    name: ferm
+    state: restarted
+
+- name: Remove nginx Docker container.
+  command:
+    cmd: docker rm -f nginx
+  ignore_errors: true
+
+- name: Create nginx Docker container.
+  command:
+    cmd: docker run -d --rm
+         --name nginx
+         -p 80:80
+         --network host
+         -v /root/ingress.conf:/etc/nginx/conf.d/default.conf
+         nginx
diff --git a/roles/lockss-config-frontend/templates/11-in-lockss-frontend.ferm.j2 b/roles/lockss-config-frontend/templates/11-in-lockss-frontend.ferm.j2
new file mode 100644
index 0000000000000000000000000000000000000000..cc2edcaa4a70e1e57396a6a890c58d4eab8b0697
--- /dev/null
+++ b/roles/lockss-config-frontend/templates/11-in-lockss-frontend.ferm.j2
@@ -0,0 +1,3 @@
+@def $MGMT_NET = ({{ lockss_admin_ips | join(" ") }});
+domain (ip ip6) table filter chain INPUT
+    saddr $MGMT_NET proto tcp dport {{ lockss_frontend_port }} ACCEPT;
diff --git a/roles/lockss-config-frontend/templates/httpd.conf.j2 b/roles/lockss-config-frontend/templates/httpd.conf.j2
new file mode 100644
index 0000000000000000000000000000000000000000..72bdb00bab338acb05e79850debeed9eb24ba891
--- /dev/null
+++ b/roles/lockss-config-frontend/templates/httpd.conf.j2
@@ -0,0 +1,114 @@
+ServerRoot "/usr/local/apache2"
+Listen {{ lockss_frontend_port }}
+LoadModule mpm_event_module modules/mod_mpm_event.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule env_module modules/mod_env.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule version_module modules/mod_version.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule status_module modules/mod_status.so
+LoadModule autoindex_module modules/mod_autoindex.so
+<IfModule !mpm_prefork_module>
+</IfModule>
+<IfModule mpm_prefork_module>
+</IfModule>
+LoadModule dir_module modules/mod_dir.so
+LoadModule alias_module modules/mod_alias.so
+<IfModule unixd_module>
+User daemon
+Group daemon
+</IfModule>
+ServerAdmin you@example.com
+<Directory />
+    AllowOverride none
+    Require all denied
+</Directory>
+DocumentRoot "/usr/local/apache2/htdocs"
+<Directory "/usr/local/apache2/htdocs">
+    Options Indexes FollowSymLinks
+    AllowOverride None
+    Require all granted
+</Directory>
+<IfModule dir_module>
+    DirectoryIndex index.html
+</IfModule>
+<Files ".ht*">
+    Require all denied
+</Files>
+ErrorLog /proc/self/fd/2
+LogLevel warn
+<IfModule log_config_module>
+    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+    LogFormat "%h %l %u %t \"%r\" %>s %b" common
+    <IfModule logio_module>
+      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+    </IfModule>
+    CustomLog /proc/self/fd/1 common
+</IfModule>
+<IfModule alias_module>
+    ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"
+</IfModule>
+<IfModule cgid_module>
+</IfModule>
+<Directory "/usr/local/apache2/cgi-bin">
+    AllowOverride None
+    Options None
+    Require all granted
+</Directory>
+<IfModule headers_module>
+    RequestHeader unset Proxy early
+</IfModule>
+<IfModule mime_module>
+    TypesConfig conf/mime.types
+    AddType application/x-compress .Z
+    AddType application/x-gzip .gz .tgz
+</IfModule>
+<IfModule proxy_html_module>
+Include conf/extra/proxy-html.conf
+</IfModule>
+<IfModule ssl_module>
+SSLRandomSeed startup builtin
+SSLRandomSeed connect builtin
+</IfModule>
+
+RedirectMatch ^/$ /{{ lockss_frontend_default_backend }}/
+
+LoadModule proxy_module modules/mod_proxy.so
+LoadModule proxy_http_module modules/mod_proxy_http.so
+ProxyRequests off
+{% for b in lockss_frontend_backends %}
+ProxyPass /{{ b.name }}/ http://{{ lockss_hostname }}:{{ b.port }}/
+{% endfor %}
+
+LoadModule proxy_html_module modules/mod_proxy_html.so
+LoadModule xml2enc_module modules/mod_xml2enc.so
+Include conf/extra/proxy-html.conf
+
+{% for b in lockss_frontend_backends %}
+<Location /{{ b.name }}/>
+    ProxyPassReverse /
+    ProxyPassReverseCookiePath / /{{ b.name }}/
+
+    ProxyHTMLURLMap / /{{ b.name }}/
+</Location>
+{% endfor %}
+
+<Location />
+    ProxyHTMLEnable On
+{% for b in lockss_frontend_backends %}
+    ProxyHTMLURLMap http://{{ lockss_hostname }}:{{ b.port }} /{{ b.name }}
+{% endfor %}
+    RequestHeader unset Accept-Encoding
+</Location>
diff --git a/roles/lockss-config-frontend/vars/main.yml b/roles/lockss-config-frontend/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..39b8379ba26de4769806a5a342ac562e14c34da1
--- /dev/null
+++ b/roles/lockss-config-frontend/vars/main.yml
@@ -0,0 +1,26 @@
+---
+
+lockss_frontend_backends:
+  - name: config
+    port: 24621
+  - name: api/config
+    port: 24620
+  - name: crawler
+    port: 24631
+  - name: api/crawler
+    port: 24630
+  - name: metadata-extraction
+    port: 24641
+  - name: api/metadata-extraction
+    port: 24640
+  - name: metadata-query
+    port: 24651
+  - name: api/metadata-query
+    port: 24650
+  - name: api/repo
+    port: 24610
+  - name: pywb
+    port: 8080
+  - name: solr
+    port: 8983
+lockss_frontend_default_backend: config