Duplicati + Internxt WebDAV

I would like to use my internxt 2 TB drive to backup my NAS through Duplicati.

Currenty my Duplicati is installed as a docker container under a debian server. Can someone help me?

Here are some references…

Hi @devishian, welcome to the forum!

Duplicati needs access to the the files that it is backing up.
When running under Docker, you need to make sure the source files are mounted in Docker.
If Duplicati is running on the NAS this should be simple to do.

Then you need to configure Duplicati, pick the mounted source folder, and choose Webdav as the destination and type in the details.

If you are not using the UI, the CLI has a syntax similar to:

duplicati-cli backup webdav://hostname/folder?username=...&password=... /source/data

thanks… I’m using docker with the interface. The problem is, as you may read from the links that I posted, that internxt uses its own CLI to authenticate and to enable webdav (GitHub - internxt/cli)

How can I start using WebDAV?

To start using WebDav with Internxt, you will need to install our CLI on your computer. To configure your WebDAV settings, follow the installation steps from our GitHub page. Having the CLI on your machine allows for secure, client-side zero-knowledge encryption algorithms to work while using WebDAV.

Once you have the CLI installed, you will need to log into the CLI using the internxt login command. Once you’ve logged in, you’ll need to enable WebDAV using internxt webdav enable. Once you’ve done that you can start using WebDav with your preferred WebDAV client.

From what you explained, it sounds like the CLI will host a WebDav server on your local computer that forwards the data. So you probably need to check which port is used and expose that to the docker container in the configuration. Then you configure WebDav in Duplicati on localhost.

I’m not that technical and maybe I’m wrong. It seems to me that the CLI allows you to manage all the functions (upload, download, delete, directories and so on) directly even without going through webdav. Would it be possible for it to be integrated into Duplicati among the possible server choices in order to use Internxt as a backup platform? It has very popular pricing in the lifetime options… I spent 165 euros for 2 terabytes forever with an offer.

Does Internxt support WebDAV?

On your WebDAV client you’ll need to insert the URL webdav.local.internxt.com and port 3005.

and at least for me, the URL resolves to 127.0.0.1, localhost, but how does Docker fit in here?

Because I don’t use Docker, I will let someone else work on that, but I assume the plan is for the
WebDAV server to be on Debian host server rather than try to stuff it inside the Duplicati Docker.

This is a painful way to go compared to having a normal WebDAV server available without install.
https://www.reddit.com/r/internxt/comments/1c1a0ss/webdav_is_now_available/ has feedback…

Adding another storage type is not trivial, because it needs to be developed, tested and maintained in the future. It is usually preferable to use existing connection capabilities.

For your setup, you need to add the 3005 port to the docker compose file. Then use WebDav on localhost:3005 as the destination in the backup config.

So basically I need to create a Docker Container with the CLI inside that will act as a local WebDAV server and manage the connection with Internxt. I don’t know if I have to create a script to keep the login and connection up or it is directly managed by the CLI.

I assumed you’d head the other way, but maybe you can do it as above, not as below, which seemed generally the Docker approach (not that I do Docker). Containers are usually not meant to get stuffed, because they’re barely big enough and sometimes one updates by replacing them, losing the stuffing.

The other comment sounds to me like it had the same approach in mind, per the “expose” thought:

About loosing settings or data by updating Docker, this can be circumvented in different several ways. Settings can be placed in environmental variables like also exposed ports. Also one che set one or many external volumes that saves data in the hosting OS instead of inside the Docker. Two different Docker environments can speak to each other with virtual a bridge network.

The main issue that I see using these two different environments is coordinating the login and the WebDAV enabling before each backup.

Is it possible under Duplicati GUi to add a personalized script to be executed each time before launching a backup via webdav? This would solve the problem.

See this reply to a similar question:

You are asking questions about Internxt which Internxt in theory could answer. Could you contact them per Does Internxt support WebDAV? which to my reading doesn’t seem to talk about trouble keeping things up.

The blue Get Started box has contact information, but the whole article is worth reading. The summary is:

Once you have the CLI installed, you will need to log into the CLI using the internxt login command. Once you’ve logged in, you’ll need to enable WebDAV using internxt webdav enable. Once you’ve done that you can start using WebDAV with your preferred WebDAV client.

This approach is complicated by needing to get Docker access to the Debian host, however there is some information on that around the web, and you sound more familiar with Docker than I am, so pick an answer.

If you really want to have WebDAV available only within the container, you might be forced to start it in there, having it run only on the container localhost, however I think this is probably a harder way to set things up…

You are right. I will ask them and come back with a possible solution. Thanks for the kind help.

1 Like

I was able to establish a connection with this dockerfile I have created:

# Use a lightweight base image of Ubuntu
FROM ubuntu:latest

# Update the system and install necessary packages
RUN apt-get update && apt-get install -y \
    curl \
    wget \
    unzip \
    python3 \
    python3-venv \
    nodejs \
    npm

# Install Internxt CLI using npm
RUN npm install -g @internxt/cli

# Create a virtual environment
RUN python3 -m venv /opt/venv

# Activate the virtual environment and install Flask
RUN /opt/venv/bin/pip install flask

# Define environment variables
ENV INTERNXT_EMAIL=your-email@example.com
ENV INTERNXT_PASSWORD=your-password
ENV ENABLE_WEBCALLS=false
ENV PASSPHRASE=my-passphrase
ENV VIRTUAL_ENV=/opt/venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

# Script to check and activate the connection to Internxt
RUN echo '#!/bin/bash\n\
# Function to check if the user is already logged in to Internxt\n\
check_connection() {\n\
    if internxt account info >/dev/null 2>&1; then\n\
        echo "Already logged in to Internxt."\n\
    else\n\
        echo "Logging in to Internxt..."\n\
        internxt login --email $INTERNXT_EMAIL --password $INTERNXT_PASSWORD\n\
    fi\n\
}\n\
\n\
# Check and activate the connection\n\
check_connection\n\
\n\
# Enable the WebDAV server\n\
internxt webdav enable\n\
\n\
# Keep the container running\n\
tail -f /dev/null\n\
' > /usr/local/bin/inxt-start.sh && chmod +x /usr/local/bin/inxt-start.sh

# Script to close the connection to Internxt
RUN echo '#!/bin/bash\n\
# Function to log out from Internxt\n\
logout() {\n\
    echo "Disabling WebDAV server..."\n\
    internxt webdav disable\n\
    echo "Logging out from Internxt..."\n\
    internxt logout\n\
}\n\
\n\
# Close the connection\n\
logout\n\
' > /usr/local/bin/inxt-stop.sh && chmod +x /usr/local/bin/inxt-stop.sh

# Script to check the status of the connection to Internxt
RUN echo '#!/bin/bash\n\
# Function to check the status of the connection to Internxt\n\
check_status() {\n\
    internxt webdav status\n\
}\n\
\n\
# Check the connection status\n\
check_status\n\
' > /usr/local/bin/inxt-status.sh && chmod +x /usr/local/bin/inxt-status.sh

# Flask app to handle web calls
RUN echo 'from flask import Flask, request, abort\n\
import os\n\
import subprocess\n\
\n\
app = Flask(__name__)\n\
\n\
ENABLE_WEBCALLS = os.getenv("ENABLE_WEBCALLS", "false").lower() == "true"\n\
PASSPHRASE = os.getenv("PASSPHRASE", "my-passphrase")\n\
\n\
def check_passphrase(request):\n\
    passphrase = request.args.get("passphrase")\n\
    if passphrase != PASSPHRASE:\n\
        abort(403)\n\
\n\
@app.route("/start")\n\
def start():\n\
    if not ENABLE_WEBCALLS:\n\
        return "Web calls are disabled.", 403\n\
    check_passphrase(request)\n\
    subprocess.Popen(["/usr/local/bin/inxt-start.sh"])\n\
    return "Started WebDAV server.", 200\n\
\n\
@app.route("/stop")\n\
def stop():\n\
    if not ENABLE_WEBCALLS:\n\
        return "Web calls are disabled.", 403\n\
    check_passphrase(request)\n\
    subprocess.call(["/usr/local/bin/inxt-stop.sh"])\n\
    return "Stopped WebDAV server.", 200\n\
\n\
@app.route("/status")\n\
def status():\n\
    if not ENABLE_WEBCALLS:\n\
        return "Web calls are disabled.", 403\n\
    check_passphrase(request)\n\
    result = subprocess.run(["/usr/local/bin/inxt-status.sh"], capture_output=True, text=True)\n\
    return result.stdout, 200\n\
\n\
if __name__ == "__main__":\n\
    app.run(host="0.0.0.0", port=6000)\n\
' > /usr/local/bin/app.py

# Expose the necessary ports
EXPOSE 3005 6000

# Command to start the Flask app
CMD ["python3", "/usr/local/bin/app.py"]

Basically, I created a virtual enviroment with two open ports one 3005 which is the webdav port created by internxt local webdav server and one 6000 which is an http port to check if the service is running, to start it or to stop it. I made several test through the docker console and the appliance work ad I can even list files that are on the server.

However when I tried to connect, Duplicati doesn’t accept an anonymous login to webdav and I cannot go on

1 Like

That looks good. I edited it to code tags instead of quote to make it display properly.

So, if I understand correctly, the connection works but you have to specify a username to make it work in Duplicati? I think there was a post about this and the suggestion was to just put in a dummy username and leave the password empty. Try to see if that works.

It seems that the Webdav backend implementation explicitly supports having an empty username to disable authentication, but this is not reflected in the UI. Otherwise, a trick you could do to bypass the UI verification is exporting the configuration to JSON after you are finished. Edit the destination URL to remove the username, then import it with Save immediately. That will make it difficult to change the job, though.

I get this error

Failed to connect: Error getting response stream (ReadDoneAsync2): ReceiveFailure

I successfully tested a local webdav served by rclone:

rclone serve webdav ./backup

This has no authentication enabled by default, and it accepts user with an empty password without any problems. It could be that internxt handles this differently, but it would be odd.

I would suspect that the docker setup might not connect the ports correctly. Can you reach the served ports from within the duplicati container, using docker exec bash?