Introduction
Back in 2022, when I was first messing with Linux(Simplify Chinese) , I had this idea that you don’t necessarily have to pay for a special OS just to build a NAS.
Fast forward to today. While tinkering with my server, the mount speeds on my cloud drives have been just… disappointing. On impulse, I ordered an N5095 motherboard. I realized the 4GB RAM stick I have lying around is a bit low, but I really didn’t want to spend any more money.
And so, my tinkering journey began again.
Tech Choices
First up, the OS. For this low-spec setup, the lightest choice is obvious: Alpine Linux.
Next, how to install it. To stay compatible with WEPE , I used Ventoy as the main bootloader to install the system.
Services are all deployed using Docker to keep the host system clean and make everything reproducible.
Services I’m using:
Services I considered but skipped:
- Media: Jellyfin
- Comics/Novels: Kavita
- Cloud Mount: CloudDrive
File Structure
My usual style for service locations: each service gets its own folder under /home.
All HDDs are mounted under /mnt, which is pretty standard.
I use mount –bind to “bind” the actual files on the HDDs to the locations where the services expect them.

System Installation
Download Alpine Linux from the official site , put it on a Ventoy USB drive. Set the motherboard BIOS to boot from USB, select Alpine Linux from the Ventoy menu, and boot.
After it finishes loading, log in as root (no password needed). Once logged in, run the install command:
| |
Just follow the prompts to complete the installation.
Official docs: setup-alpine - Alpine Linux
Public Key Login
Edit the SSH config. First, create the .ssh folder.
| |
Go into the folder:
| |
Add your public key to authorized_keys.
| |
(Your public key is in %USERPROFILE%\.ssh on Windows)
Enable public key authentication in the SSH daemon config:
| |
Around line 41, uncomment the line so it says:
| |
Enable Community Repository
Open the repositories file:
| |
Remove the comment (#) from the community line:
| |
Install Docker
Update packages:
| |
Install Docker:
| |
Set it to start on boot:
| |
Start Docker:
| |
Check if it’s running:
| |
Add Swap
The server image didn’t have swap by default, so I added it. (Though I later realized it did add some, so this is optional depending on your needs).
Create a swap file:
| |
Set permissions to root-only:
| |
Format as swap:
| |
Enable the swap:
| |
Check if it’s active:
| |
Mount Hard Drives
Check all block devices:
| |
Install NTFS support:
| |
Create a mount point folder:
| |
Mount the drive:
| |
To unmount, you can use the path (recommended):
| |
Or the device name:
| |
Auto-mount on Boot
Get the partition’s UUID. This prevents issues if the device name (/dev/sdc1) changes on reboot.
| |
Edit /etc/fstab:
| |
Add this line (using your UUID):
| |
Test if it worked. First, unmount:
| |
Now, mount all entries in fstab:
| |
Check if you can see your files:
| |
SMB Share
Using Samba, you can mount the drive in Windows and use it just like a local drive.
In /home/samba, create a docker-compose.yml:
| |
Edit the Samba config file config.yml:
| |
Mounting as a Drive in Windows
Press Win + R, type cmd, and enter the command:
| |
Refresh Explorer:
| |
Or you can just add it through the File Explorer GUI.
Bind Mount
Compared to a symbolic link, a bind mount is compatible with Docker.
| |
To make this automatic on boot, add it to /etc/fstab. It must be after the main drive mount line (because the file is processed in order).
| |
Verify:
| |
Other Services
As for the other services, I feel like I’ve written about them plenty in my previous posts, so I won’t repeat myself here.
Related articles(Simplify Chinese):
- 2025-10-05: Tinkering with Comic and Audio Websites
- 2023-05-02: Building a Personal Music Website
- 2022-09-16: Tinkering with My Internal Network
- 2022-09-14: My Notes on Installing Komga on Fedora
Custom Domain
I use my OpenWRT router’s DNS Hijacking feature for this. It lets me visit a specific domain (like emby.mynas) and have it point to my NAS.
The requirement is that your devices use the router as their DNS server. Then, in the router’s DHCP/DNS settings, give the NAS a static IP and add the custom domains, pointing them all to the NAS’s IP.
Nginx-UI
To make the custom domains work, you need a reverse proxy. I use Nginx.
Docker Compose file:
| |
When a container needs to access another container, its bridge IP is 172.17.0.1.
So, if you have a service mapped to port 8888 on the host, the reverse proxy address isn’t 127.0.0.1:8888, it’s 172.17.0.1:8888.
(See: 2025 New Server Setup Log#Installing-nginx-ui(Simplify Chinese) for why I set that environment variable).
Conclusion
I feel like I’ve finally achieved what I was talking about back in 2022.
It’s also weird… in just three years, even though I subjectively feel like I haven’t changed at all, when I read my old articles and remember my situation when I wrote them, I can truly feel that my way of thinking has changed, top to bottom.
To be honest, back then I was probably thinking of using a specialized system like True NAS. But I never would have imagined that when I finally did it, I would use a “from scratch” method that my past self wouldn’t have even dared to try. Looking back at my old posts, piecing this all together… I can genuinely feel the “value” in it.
The tinkering never stops, and neither does the passion.