How to upload images to another volume inside /mnt

Hi,

I’m trying to avoid using external services as Cloudinary or CloudImage, they looks like excelent services but I’m trying to avoid in future implementations and use the beneficts of volumes in Hetzner Cloud:
https://docs.hetzner.com/cloud/volumes/overview

The Volumes are mouted in /mnt directory.
My project is in NodeJS on Ubuntu 22.

The “File Upload” component in server action allow to choose the Path were the file will be upload, but this path is restricted to relative site root path, so, no posibility to write root directory like /mnt/myvolume/mydata

In docker I guess that can be easy by just changing volumes path inside .yml file, but my project is not docker.

Someone know how to upload files to outside directory from site root of app.

Thanks

Try to read this topic - Securing Public User Uploads Files

Create a symlink (hopefully it works)

Thanks, but like I said, project is not in Docker. It is published directly on server, I’m using pm2.

Hi, thanks or sugestion, but I guess that doing a hard link will be a double task, I mean, more system resource, the fact that copy each file itself I suppose more resource will be used. Keeping in mind that this project is a SaaS and users will upload multiple image at one like products gallery.

I don’t know if maybe exist a way to handle this using a custom extension, I don’t know. Right now File upload component only allow to choose inside root site. Write a root path like /mnt/myvolume/mydata cause errors.

If the solution is a custom extension, I don’t know where to start.

Don’t you think Linux is so widely used that so many people attempted to optimize it? :penguin: I’m almost certain the kernel is smarter than that

Alternatively, you could indeed build a custom extension, but I don’t know how to handle file uploads. I think someone did it for PHP?

1 Like

Actually, let me clarify this @Alexander_Paladines

I was referring to a symbolic link link, not a hard link - I didn’t even know there was such a thing

When writing to a symbolic link, the file is only written to the destination

Thanks @Apple, but I think that symbolic link, the soft link means that the original file can not be deleted, and only create a shortcut in other location. The idea behind all this is to use a dedicate volume for images that can growth as necessary.

And I suppose. I’m not sure, this is not my field, but in Wappler I guess that need to first mount /mnt volume to symbolic link into public directoy inside root project folder, otherwise I don’t think that a nodejs project read files inside /mnt root system folder. With docker looks a easy task using volume, but I’m not using docker.

Right now I’m trying with min.io but Wappler default s3 component use virtual-hosted style and not path-style that minio use as default.

I’ve just tested this on the Terminal, I can create and delete files on the symlink (destination), your problem is solved :sweat_smile:

To answer your other question, NodeJS could easily read /mnt if it runs under a user with such permissions (I guess, by default, every user has such permissions). It’s just Wappler doesn’t allow you to do it because it prepends the location of the NodeJS project

Edit: The command for symlink:

ln -s /mnt/your_volume /path/to/nodejs/project/your_volume

I think you missreading my answer, the original file can not be deleted, not the symbolic link.
Anyway, the second part sound interesting. How to choose a /mnt location inside upload file compoement inside wappler?

I think I misread, I thought you also wanted the ability to delete files, but I still don’t understand the issue :frowning: I understand you want to upload images to /mnt/your_volume, and that’s possible by using a symlink - I’m not understanding the issue

Crude solution:

// lib/modules/upload.js
path = toSystemPath(path);

Replace with:

        // Won't prepend project path if path starts with /mnt/
        if (!path.startsWith('/mnt/')) {
            path = toSystemPath(path);
        }

Wappler will always attempt to override that, so I’d recommend a custom extension or the usage of symlinks.

The question is why can’t you use a symlink? In the end it’s the exact same result :thinking:

Because of this

Symlink I think that only represent a shortcut of the original file, and this original can not be deleted, so, the space that use the original folder will be subject to the space of the server, instead an external volume in cloud services like hetzner, the volume can growth as necessary.

Symlink of a folder to /mnt/your_volume

The disk space usage for a symlink is like a few bytes

You won’t ever fill your server’s disk space by writing to a symlink, because the file will be written directly to the external volume, and it’s just one symlink, not each per file

Edit: If you attempt to write a file, like:

echo 123 > ./my_symlink/hello.txt

The Linux Kernel will handle that file write, it’ll see where my_symlink points to, and write there hello.txt
I discovered this by testing in the terminal

So, the Upload File component will upload it inside public folder, lets say /public/img/ inside root site path, this is a normal configuration.

How the symlink will act, I mean, the original file will be upload inside root site /public/img/, creating a symlink will create a shortcut inside root server /mnt but the original file will remains inside root site. What I need is acttually the oposite of that. That the original file store in root system /mnt and probably the symlink points to root site /public/img/. The Wappler Upload File component only allow to store files inside root site.

You use Upload File component and store in path:

/external_volume/img

Which, after Wappler prepends the project path becomes:

/path/to/nodejs/project/external_volume/img

So, you create a symlink:

ln -s /mnt/your_volume /path/to/nodejs/project/external_volume

So, when Wappler writes the file, it’ll actually be written to /mnt/your_volume/img

Thanks @Apple,

Sorry, I misread your solution before, and this works.

Right now I’m just thinking in about how feasible will be this in future.