Exploring Docker Integration with HestiaCP: Seeking Official Guidance or Community Best Practices

Hello HestiaCP Community,

I’ve been delving into the integration of Docker containers within HestiaCP and have come across several discussions on this topic. Notably, many of these threads are over two years old, and I wanted to inquire if there have been any official developments or updated best practices regarding Docker support in HestiaCP.

From what I’ve gathered, HestiaCP doesn’t officially support Docker at this time. However, community members have shared various methods to run Docker containers alongside HestiaCP, primarily by creating custom Nginx templates to reverse proxy Dockerized applications.

Given the evolving nature of software and the increasing adoption of containerization, I’m curious if there have been any recent updates or official guidelines on this integration.

If no official documentation exists, I am considering compiling a comprehensive, step-by-step guide based on current community practices and my own experiences. This guide would aim to assist users in effectively running Docker containers within the HestiaCP environment.

Before proceeding, I wanted to check if such a resource already exists to avoid redundancy. If anyone has insights, experiences, or resources to share on this topic, your input would be greatly appreciated.

Thank you for your time and assistance.

Best regards

I’m interested in reading this.

I just think we should start with a discussion of

  • lets’ make a list of the TEN different things that ‘Docker Support’ might mean.

Some people might just want to RUN ‘HestiaCP’ INSIDE of docker (on various O/S).
Then, yeah how you’re talking about running HestiaCP in the host, and then connecting to different methods of docker containers

I just don’t wanna try and turn HestiaCP into the ‘Next Version Of TrueNAS’.

I’d rather have ‘Official Plugins For Installing HestiaCP in TrueNAS / Unraid / TurnkeyLinux / Proxmox’

I think that would be a better use of resources. ‘To Focus On Making Things Easier’

Personally, I’m a developer and I haven’t READ 3 pages of documentation in 25 years. I read

  • Reddit (until I caught a permaban for claiming that ‘Musk Is Not a Fascist’)
  • Other Forums
  • Facebook Groups
  • Twitter
  • Email
  • WordPress (should be somehow cloneable for people to ‘self-host’ offline)

I would love to see content like ‘How To “Use HestiaCP In Docker” Shared Online, Instead of What.. GitHub Documents??’

1 Like

Thank you for your input, Aaron.

To clarify what “Docker support” means from my perspective:

I’m referring to the ability to run and manage Docker containers natively within a HestiaCP environment, ideally with some form of integration or at least compatibility that aligns with how HestiaCP manages web domains and services.

Since HestiaCP does not currently offer native Docker support, my interim idea is to allow applications such as Radicale, Immich, or Paperless-NGX to run in Docker containers on the same host where HestiaCP is installed, and then expose them via HestiaCP-managed domains using reverse proxy rules.

For example:

The domain domaina. de is created and managed via HestiaCP.

On the host, I install Docker and run a containerized instance of paperless-ngx.

Then I modify the proxy config file for domaina. de (via custom Nginx templates or manual changes) to add a proxy_pass to the container’s internal port.

This approach would allow users to integrate containerized services under domains managed by HestiaCP without interfering with its core operations

yeah, it sounds interesting.
I’d use it. I just think that’s the 3-years-from-now goal. And we need simpler steps to plan out how to get there.

I don’t know ANYONE that actually uses ANYTOOLS that don’t support Docker.
I just love HestiaCP as it is. I don’t think that EVERYTOOL needs docker support.

The ENTIRE BUDGET for this site is a LOT lower than I expected. So if we expect THEM to build something, I think we ALLLLLLL need to ‘start donating more’.

I would, but my entire allowance is $330/month, and I have 2 webservers, and I spend 80-90% of my remaining budget on hardware every month. That is CHANGING to probably being focused on me buying CLASSES and SERVICES.

I’ve spent more in Software ($400) In the last 12 months than I have in the last 25 years of my life (WITHOUT GAMES) = ($0).

I was trying:

1. I Pull the official Radicale image

docker pull tomsquest/docker-radicale:latest

2. I Run the container as your HestiaCP user

docker run -d \
  --name radicale \
  --user 1004:1004 \
  -p 127.0.0.1:5232:5232 \
  --read-only \
  --init \
  --security-opt="no-new-privileges:true" \
  --cap-drop ALL \
  --cap-add CHOWN \
  --cap-add SETUID \
  --cap-add SETGID \
  --cap-add KILL \
  --pids-limit 50 \
  --memory 256M \
  --health-cmd="curl --fail http://localhost:5232 || exit 1" \
  --health-interval=30s \
  --health-retries=3 \
  -v /home/<user>/web/<your-domain>/radicale-data:/data \
  tomsquest/docker-radicale:latest
  • --user 1004:1004 ensures the process runs under your HestiaCP UID/GID.
  • -v …:/data mounts the Radicale data directory into your web folder.

3. Create Nginx “custom include” files

These live under /home/<user>/conf/web/<your-domain>/.

  • nginx.conf_custom (for HTTP):

    # Radicale proxy (HTTP)
    location / {
        proxy_pass         http://127.0.0.1:5232/;
        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;
        proxy_read_timeout 360;
    }
    
  • nginx.ssl.conf_custom (for HTTPS):

    # Radicale proxy (HTTPS)
    location / {
        proxy_pass         http://127.0.0.1:5232/;
        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;
        proxy_read_timeout 360;
    }
    

HestiaCP’s main nginx.conf and nginx.ssl.conf already include these custom files via:

include /home/<user>/conf/web/<your-domain>/nginx.conf_*;
include /home/<user>/conf/web/<your-domain>/nginx.ssl.conf_*;

4. Reload Nginx or rebuild the domain

systemctl reload nginx

At this point, accessing https:// www./ should show the Radicale web interface—but i still seeing the “We’re working on it!” placeholder.

Where do you think the misconfiguration is?

Please remove the domain name from your posts. That domain redirects to another domain, which has loads of ads. Popups etc.

1 Like

Its Working!


Prerequisites

  • A HestiaCP account named <user>.
  • A web domain <domain> already configured in HestiaCP.
  • Your server’s public IP: <server-ip>.
  • Root or sudo access on the host.

1. Prepare data and config directories

# 1.1 Create calendar-data folder (will hold collections)
mkdir -p /home/<user>/web/<domain>/radicale-data/collections

# 1.2 Create Radicale config folder
mkdir -p /home/<user>/web/<domain>/radicale-config

# 1.3 Ensure Hestia user owns both
chown -R 1004:1004 /home/<user>/web/<domain>/radicale-data
chown -R 1004:1004 /home/<user>/web/<domain>/radicale-config

Note: Replace 1004:1004 with your HestiaCP user’s UID:GID if different.


2. Write the Radicale configuration

Create /home/<user>/web/<domain>/radicale-config/config with these contents:

[server]
hosts = 0.0.0.0:5232

[storage]
filesystem_folder = /data/collections

[auth]
type = none

Set ownership and permissions:

chown 1004:1004 /home/<user>/web/<domain>/radicale-config/config
chmod 640       /home/<user>/web/<domain>/radicale-config/config

3. Pull the Radicale Docker image

docker pull tomsquest/docker-radicale:latest

4. Run the Radicale container

docker run -d \
  --name radicale \
  --user 1004:1004 \
  -p 127.0.0.1:5232:5232 \
  --read-only \
  --init \
  --security-opt no-new-privileges:true \
  --cap-drop ALL \
  --cap-add CHOWN \
  --cap-add SETUID \
  --cap-add SETGID \
  --cap-add KILL \
  --pids-limit 50 \
  --memory 256M \
  --health-cmd="curl --fail http://localhost:5232 || exit 1" \
  --health-interval=30s \
  --health-retries=3 \
  -v /home/<user>/web/<domain>/radicale-data:/data \
  -v /home/<user>/web/<domain>/radicale-config:/config:ro \
  tomsquest/docker-radicale:latest

Verify operation:

docker ps --filter name=radicale
docker logs radicale
curl -L http://127.0.0.1:5232/.web/

5. Create HestiaCP Nginx “custom include” files

HestiaCP will automatically include any file in /home/<user>/conf/web/<domain>/ matching nginx.conf_* or nginx.ssl.conf_*.

5.1 HTTP proxy (nginx.conf_custom)

File:

/home/<user>/conf/web/<domain>/nginx.conf_custom
# Redirect root to Radicale UI
location = / {
    return 302 /.web/;
}

# Proxy everything under /.web/ to Radicale
location ^~ /.web/ {
    proxy_pass           http://127.0.0.1:5232;
    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;
    proxy_read_timeout   360s;
}

5.2 HTTPS proxy (nginx.ssl.conf_custom)

File:

/home/<user>/conf/web/<domain>/nginx.ssl.conf_custom
location = / {
    return 302 /.web/;
}

location ^~ /.web/ {
    proxy_pass           http://127.0.0.1:5232;
    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;
    proxy_read_timeout   360s;
}

6. Reload Nginx / Rebuild the domain

nginx -t
systemctl reload nginx

7. Verify end-to-end

  1. HTTP → HTTPS redirect

    curl -i -H "Host: <domain>" http://<server-ip>:80/
    

    You should get a 301 to https://<domain>/.

  2. Radicale UI via domain

    curl -L -i -H "Host: <domain>" http://<server-ip>:80/
    

    302 to /.web/, then 200 OK with the Radicale interface HTML.

  3. Browser test
    Open

    https://www.<domain>/
    

    You should see Radicale’s UI instead of the “Under Construction” placeholder.


That’s it! This setup runs Radicale in Docker as your HestiaCP user, stores data under your web folder, and proxies all //.web/ traffic through Nginx.

Hi, very nice example!
I wonder if the http-only: nginx.conf_custom is needed
since all requests to http will be redirected to https.