web_photo_folders_server_2
Simple web photo gallery with folder tree.
version: 2026.926.1712 date: 2026-09-26 author: bestia.dev repository: codeberg.org
Hashtags: #tutorial #rust
My projects on codeberg.org are more like a tutorial than a finished product: bestia-dev tutorials.
Goals
Make this project in small increments in separate repositories to make the progress visible to beginners.
I want to display my photos on the web, but just for me.
It has to be secured by google oauth2.
My photos are in a neat folder structure.
I have a lot of photos and videos.
The web page has the folder tree on the left and thumbnails on the right with movable divider.
Click on the photo to see it as big as possible.
Use key presses to navigate. Mouse use is secondary, but it must be there.
Always use the server inside a linux container with podman.
The server is build using musl, so the container can be very small.
Axum web server
I will use the Axum web server crate.
Axum uses some type magic flexibility in function signatures called Extractors.
Rust doesn't have function overloading.
Magical handler functions in Rust
dependency injection like Bevy
extract-as-argument pattern
The internal port for Axum web-app will be 8080. Then in podman run it will be forwarded as 8014 or other port.
WSL
I am using WSL inside Win11.
By default the port forwarding between WSL and Windows is limited I guess.
Modify the file c:\Users\Luciano\.wslconfig to contain:
[wsl2]
# forward ports from WSL to Win, so I can have a web server on port 8014 in WSL and use the browser in Windows
localhostForwarding = true
Then restart the computer or only the WSL so the change can take effect.
Sometimes WSL just don't forward the ports with no obvious reason. Just restart WSL and it will work again.
Linux container
I will run the web server inside a new container in WSL, not inside the CRUSTDE container.
Follow the instructions at the step cargo auto release to copy the new executable binary, create a container image and run it in WSL.
Open the browser in Windows and it should work.
How to Create a Container from Scratch with Buildah and Podman
There will be 2 volumes/folders attached to the web_photo_folders_cnt_8014 or web_photo_folders_cnt_8015 container: photos_readonly and thumbnails.
Install to web server
Edit the reverse proxy nginx file /etc/nginx/sites-available/default
# in remote web server bash
sudo fresh /etc/nginx/sites-available/default
# add these lines to the nginx config
# region web_photo_folders_8014
# only complete route with trailing slash works
# the trailing / after both of these lines means this route is not appended to the forwarding
location /web_photo_folders_8014/ {
proxy_pass http://127.0.0.1:8014/web_photo_folders_8014/;
proxy_buffering off;
}
# endregion web_photo_folders_8014
# region web_photo_folders_8015
# only complete route with trailing slash works
# the trailing / after both of these lines means this route is not appended to the forwarding
location /web_photo_folders_8015/ {
proxy_pass http://127.0.0.1:8015/web_photo_folders_8015/;
proxy_buffering off;
}
# endregion web_photo_folders_8015
# after save, reload nginx
sudo service nginx reload
Install the folders and container on the web server.
# in VSCode bash terminal from project web_photo_folders_server_2
sshadd_emb hetzner_com_debian_1_luciano_ssh_1
# Copy the example photos: first `dry-run`, then without `dry-run`
rsync -e ssh -avz --itemize-changes --delete-after --progress web_photo_folders_8014/ hetzner_com_debian_1_luciano:/var/www/webapps/web_photo_folders_8014/
rsync -e ssh -avz --itemize-changes --delete-after --progress web_photo_folders_8015/ hetzner_com_debian_1_luciano:/var/www/webapps/web_photo_folders_8015/
# from windows git-bash connect to your web server
sshadd_emb hetzner_com_debian_1_luciano_ssh_1
ssh luciano@bestia.dev
# in the remote bash
zellij attach
# new tab: ctrl+t (new tab), n (new)
sh /var/www/webapps/web_photo_folders_8014/podman_run_on_server_8014.sh
sh /var/www/webapps/web_photo_folders_8015/podman_run_on_server_8015.sh
Folder structure of web server
I want a folder tree with the information about the number of jpg.
The tree is always fully opened. No need to close anything here.
When clicked, under the item I would like to see a photo gallery of the folder.
The executable_binary will be on the same level as the web-app folder, so every path will start with web_server_folder/ without the start slash.
The file and folder structure will be:
- executable_binary (on the same level as the web-app folder)
- web_server_folder (web-app folder)
- photos_readonly
- folders and jpg images
- thumbnails
- folders and jpg images
- template_one.html
- template_two.html
- style.css
- images
- files for images
The URI structure is very similar, but different.
Root is never used for this web-app (http://localhost:8014/ or https://bestia.dev/), because I have many web-apps on the same web site domain.
I want to start the web-app in the first URI fragment. It is the web-app folder. (ex. http://localhost:8014/web_photo_folders_8014/ or https://bestia.dev/web_photo_folders_8015/, ...).
Using nginx reverse proxy it is easy to have the many instances of the same web-app on different ports with different first URI path fragment.
The web-app will mostly use the web-app folder, so the paths must be always relative and never absolute. Never start a link with a slash. We don't need to repeat the web-app folder ever in any link.
Links examples: folder_tree.html, folder_photos_view.html, photos_readonly/2023/, thumbnails/2023/
- root (Root is never used for this web-app: //localhost:8014/ or //bestia.dev/)
- web-app folder (ex. web_photo_folders_8014, web_photo_folders_8015, ...)
- photos_readonly
- folders and jpg images
- thumbnails
- folders and jpg images
- template_folder_tree.html
- template_folder_photos_view.html
- style.css
- images
- files for images
Custom html elements
I will use un-registered custom html elements. According to the HTML specification, any valid custom tag (which must contain a hyphen) behaves like an inline element by default.
Fo example <accordion-group>...</accordion-group>
htmx
htmx is an modern open-source front-end JavaScript library that extends HTML with custom attributes that enable the use of AJAX directly in HTML and with a hypermedia-driven approach.
Key Features of htmx
- hx-get / hx-post / hx-put / hx-delete: Tells the element to issue an AJAX request to that specific URL when triggered.
- hx-target: Specifies exactly where on the page the server's response should be loaded.
- hx-trigger: Changes what causes the request (e.g., hx-trigger="mouseenter" fires the request when you hover over the element).
- hx-swap: Controls how the new content is injected (e.g., replacing the element entirely, or just updating its inner contents).
CSS nesting
The CSS nesting module defines a syntax for nesting selectors, providing the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule.
CSS nesting helps with the readability, modularity, and maintainability of CSS stylesheets. It also potentially helps reduce the size of CSS files, thereby decreasing the amount of data downloaded by users.
The CSS & nesting selector explicitly states the relationship between parent and child rules when using CSS nesting.
Development details
Read the development details in a separate md file: DEVELOPMENT.md
Releases changelog
Read the releases changelog in a separate md file: RELEASES.md
TODO
Everything as for now.
create thumbnails from photos
create tree from folder structure
Open-source and free as a beer
My open-source projects are free as a beer (MIT license).
I just love programming.
But I need also to drink. If you find my projects and tutorials helpful, please buy me a beer by donating to my PayPal.
You know the price of a beer in your local bar ;-)
So I can drink a free beer for your health :-)
Na zdravje! Alla salute! Prost! Nazdravlje! 🍻
//bestia.dev
//codeberg.org/bestia-dev
//github.com/bestia-dev
//bestiadev.substack.com
//youtube.com/@bestia-dev-tutorials