HaRP is a reverse proxy system designed to simplify the deployment workflow for Nextcloud 32’s AppAPI.
It enables direct communication between clients and ExApps, bypassing the Nextcloud instance to improve performance and reduce the complexity traditionally associated with DockerSocketProxy
setups.
HaRP provides a flexible and scalable solution for managing ExApps, supporting deployments both locally and on remote servers.
It can be installed alongside Nextcloud or on a separate host, allowing for optimized performance and security.
The system supports simultaneous HTTP and HTTPS communication, enabling trusted networks to use direct HTTP access while securing external or untrusted connections via HTTPS.
In addition, HaRP includes built-in brute-force protection and dynamic routing capabilities, making it well-suited for a wide range of network infrastructures, from simple home setups to large distributed environments.
- Simplifies Deployment: Replaces more complex setups (such as DockerSocketProxy) with an easy-to-use container.
- Direct Communication: Routes requests directly to ExApps, bypassing the Nextcloud instance.
- Enhanced Security: Uses brute-force protection and basic authentication to secure all exposed interfaces.
- Flexible Frontends: Supports both HTTP and HTTPS for ExApps and Nextcloud control, and FRP (TCP) frontend.
- Multi-Docker Management: A single HaRP instance can manage multiple Docker engines.
- Automated TLS for FRP: Generates self-signed certificates for FRP communications (unless explicitly disabled).
HaRP should be deployed where your reverse proxy (NGINX, Caddy, Traefik, etc.) can reach its HP_EXAPPS_ADDRESS
. For home installations, you may run it on your Nextcloud instance. Below are a couple of deployment examples using Docker:
docker run \
-e HP_SHARED_KEY="some_very_secure_password" \
-e NC_INSTANCE_URL="http://nextcloud.local" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v `pwd`/certs:/certs \
--name appapi-harp -h appapi-harp \
--restart unless-stopped \
-p 8780:8780 \
-p 8782:8782 \
-d ghcr.io/nextcloud/nextcloud-appapi-harp:release
Note: By default,
HP_EXAPPS_ADDRESS
is set to0.0.0.0:8780
— ensure this port is published to the desired interface (for example, host’s 127.0.0.1:8780).
For even faster communication by avoiding internal network routing, you can use host networking:
docker run \
-e HP_SHARED_KEY="some_very_secure_password" \
-e NC_INSTANCE_URL="http://nextcloud.local" \
-e HP_EXAPPS_ADDRESS="192.168.2.5:8780" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v `pwd`/certs:/certs \
--name appapi-harp -h appapi-harp \
--restart unless-stopped \
--network host \
-d ghcr.io/nextcloud/nextcloud-appapi-harp:release
Warning: Do not forget to change the HP_SHARED_KEY value to a secure one!
HaRP requires your reverse proxy to forward traffic from your public domain (e.g., nextcloud.com/exapps/
) to the HaRP container’s HP_EXAPPS_ADDRESS
. Below are sample configurations for NGINX, Caddy, and Traefik:
server {
listen 80;
server_name nextcloud.com;
location /exapps/ {
proxy_pass http://127.0.0.1:8780/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
nextcloud.com {
reverse_proxy /exapps/* 127.0.0.1:8780
}
http:
routers:
exapps:
rule: "PathPrefix(`/exapps/`)"
service: exapps-service
entryPoints:
- web
services:
exapps-service:
loadBalancer:
servers:
- url: "http://127.0.0.1:8780"
Note: Replace
127.0.0.1
with the actual IP address of your HaRP container if it is running on a different host.
HaRP is configured via several environment variables. Here are the key variables and their defaults:
-
HP_EXAPPS_ADDRESS
/HP_EXAPPS_HTTPS_ADDRESS
- Description: IP:Port for ExApps HTTP/HTTPS frontends.
- Default:
HP_EXAPPS_ADDRESS="0.0.0.0:8780"
HP_EXAPPS_HTTPS_ADDRESS="0.0.0.0:8781"
- Note: Must be reachable by your reverse proxy.
-
HP_FRP_ADDRESS
- Description: IP:Port for the FRP (TCP) frontends.
- Default:
HP_FRP_ADDRESS="0.0.0.0:8782"
- Note: Should be accessible from where your ExApps are running.
-
HP_SHARED_KEY
(orHP_SHARED_KEY_FILE
)- Description: A secret token used for authentication between services.
- Requirement: Must be set at runtime. Use only one of these methods.
-
NC_INSTANCE_URL
- Description: The base URL of your Nextcloud instance.
- Requirement: Must be accessible from the HaRP container.
-
HP_FRP_DISABLE_TLS
- Description: Disables TLS for the FRP service.
- Default:
HP_FRP_DISABLE_TLS="false"
- Advanced: Use only for specialized setups where TCP TLS termination is managed externally.
-
HP_LOG_LEVEL
- Default:
warning
- Possible Values:
debug
,info
,warning
,error
- Default:
-
HP_VERBOSE_START
- Description: Flag that determines whether to output verbose logging to the console during container startup.
- Default:
1
-
HP_SESSION_LIFETIME
- Description: A floating-point value that determines how long the Nextcloud session is retained in HaRP, in seconds. Possible values range from
0
(disable session caching) to10
seconds. - Default:
3
- Description: A floating-point value that determines how long the Nextcloud session is retained in HaRP, in seconds. Possible values range from
-
Timeout Variables:
HP_TIMEOUT_CONNECT
- Description: Maximum time allowed for establishing a connection.
- Default:
30s
HP_TIMEOUT_CLIENT
- Description: Timeout for client-side connections.
- Default:
30s
HP_TIMEOUT_SERVER
- Description: Timeout for server-side connections. We do not recommend to change this value.
- Default:
1800s
HaRP supports two approaches for connecting Docker Engines:
If your Docker Engine is running on the same host as HaRP, simply mount the Docker socket into the container. This direct method allows HaRP to interact with the Docker Engine immediately:
-v /var/run/docker.sock:/var/run/docker.sock
For remote or external Docker Engines - or if you prefer not to mount the Docker socket - you can use an FRP (Fast Reverse Proxy) client to establish a secure connection. Follow these steps:
-
Retrieve Certificate Files: HaRP automatically generates the necessary FRP certificate files, and places them in its folder
/certs/frp
. You need next files from it to connect external Docker Engine to HaRP:client.crt
client.key
ca.crt
-
Create an FRP Client Configuration: With the certificate files in hand, create a configuration file (for example,
frpc.toml
) on the Docker Engine host. Below is a sample configuration:# frpc.toml serverAddr = "your.harp.server.address" # Replace with your HP_FRP_ADDRESS host serverPort = 8782 # Default port for FRP transport.tls.certFile = "certs/frp/client.crt" transport.tls.keyFile = "certs/frp/client.key" transport.tls.trustedCaFile = "certs/frp/ca.crt" transport.tls.serverName = "harp.nc" metadatas.token = "HP_SHARED_KEY" # HP_SHARED_KEY in quotes [[proxies]] remotePort = 24001 # Unique remotePort for each Docker Engine (range: 24001-24099) name = "deploy-daemon" # Unique name for each Docker Engine type = "tcp" [proxies.plugin] type = "unix_domain_socket" unixPath = "/var/run/docker.sock"
-
Deploy the FRP Client: Run the FRP client on the host with the Docker Engine using the configuration file. This establishes a secure tunnel between the remote Docker Engine and HaRP. Each connection requires a unique
remotePort
value; HaRP supports up to 99 Docker Engines by assigning a different port in the allowed range.
We strongly recommend starting support for
HaRP
in ExApps from the start of Nextcloud32
, as the oldDSP
way will be deprecated and marked for removal in Nextcloud35
.Adding
HaRP
support is fully compatible with the existingDSP
system, so you won’t need to maintain two separate release types of your ExApp.
-
Copy the
start.sh
script from theexapps_dev
folder of this repository and set it as the entry point in your ExApp’sDockerfile
. -
After copying
start.sh
, edit its last line so that it runs your ExApp’s main binary (or script). -
Add the following lines to your
Dockerfile
to automatically include theFRP client
binaries in your Docker image:# Download and install FRP client RUN set -ex; \ ARCH=$(uname -m); \ if [ "$ARCH" = "aarch64" ]; then \ FRP_URL="https://raw.githubusercontent.com/nextcloud/HaRP/main/exapps_dev/frp_0.61.1_linux_arm64.tar.gz"; \ else \ FRP_URL="https://raw.githubusercontent.com/nextcloud/HaRP/main/exapps_dev/frp_0.61.1_linux_amd64.tar.gz"; \ fi; \ echo "Downloading FRP client from $FRP_URL"; \ curl -L "$FRP_URL" -o /tmp/frp.tar.gz; \ tar -C /tmp -xzf /tmp/frp.tar.gz; \ mv /tmp/frp_0.61.1_linux_* /tmp/frp; \ cp /tmp/frp/frpc /usr/local/bin/frpc; \ chmod +x /usr/local/bin/frpc; \ rm -rf /tmp/frp /tmp/frp.tar.gz
Note: For
Alpine 3.21
Linux you can just installFRP
from repo usingapk add frp
command.
That's it!
Note: All ExApps developed by Nextcloud will support HaRP when Nextcloud 32 is released. We hope that most ExApps from the community will also support it. Contact us if you need assistance.
If you've upgraded to Nextcloud 32 and want to switch from using DSP to HaRP, follow these steps:
- Install HaRP on the same Docker Engine that you were using for DSP.
- Test Deployment on HaRP with usual
TestDeploy
button. - Set HaRP as the default deployment daemon for ExApps.
- Remove the ExApps without deleting their data volumes:
- Terminal: Do not use the
--rm-data
option when removing the app. - From UI: Do not use the "Delete data when removing" checkbox.
- Terminal: Do not use the
- Install the ExApp: Install removed ExApps, now they will be installed on
HaRP
. - Remove DSP: Now DSP (Docker Socket Proxy) can be safely removed.
Contributions to HaRP are welcome. Feel free to open issues, discussions or submit pull requests with improvements, bug fixes, or new features.