Self-Hosted File Cloud with Cloudflare
Deploy a personal Nextcloud instance accessible globally via Cloudflare Tunnel.
Introduction
30 Second Summary
Every file you store in Google Drive, iCloud, or Dropbox lives on someone else's computer. You are trusting a third party with your personal documents, family photos, and private videos.
In this project, you will deploy your own file cloud on an Ubuntu server you control. You will make it accessible from anywhere in the world at your custom domain with full HTTPS security, all without opening a single port on your router.
What You'll Build
A personal file cloud running on Docker with Nextcloud All-in-One, secured and globally accessible via a Cloudflare Tunnel at your custom domain.
By the end of this project, you'll have:
- A running Nextcloud AIO instance on Docker with PostgreSQL, Redis, and Apache bundled together.
- A Cloudflare Tunnel securely routing traffic to your server without any port forwarding or router configuration.
- A person-based folder structure with uploaded sample files including PDFs, images, videos, and text documents.
- Secret Mission: Harden your installation with Two-Factor Authentication and server-side encryption.
Are there any prerequisites?
You need an Ubuntu Server 26.04 machine that you can access via SSH or a keyboard and monitor. You should be comfortable navigating the Linux terminal (running commands, editing files).
Before We Start
Before We Start...
Install Docker and Configure the Firewall
Your Nextcloud file cloud runs inside Docker containers. Before you can deploy anything, you need the Docker Engine installed on your Ubuntu server.
You also need to lock down your server's firewall. Since Cloudflare Tunnel only uses outbound connections, the only inbound port you need open is SSH for your own access.
In this step, get ready to:
- Install Docker Engine from the official apt repository.
- Configure your user account for Docker access and lock down the firewall.
- Verify everything is working with a test container.
Update your system and install Docker Engine
Ubuntu's default package repositories don't include the latest Docker Engine. You'll add Docker's official apt repository so you always get up-to-date packages.
Why the official Docker repository?
Nextcloud AIO does not support Snap-based Docker installations. Using the official apt repository ensures you get a compatible, fully-featured Docker Engine that AIO can manage properly.
- Set up Docker's official GPG key and apt repository by running these commands:
# Update package index and install prerequisites
sudo apt update
sudo apt install ca-certificates curl
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the Docker repository to apt sources
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
# Refresh package index with new repository
sudo apt update
What do these commands do?
- The first block installs ca-certificates and curl so your server can securely download files over HTTPS.
- The GPG key lets apt verify that Docker packages are authentic and haven't been tampered with.
- The docker.sources file tells apt where to find Docker's packages. It uses the DEB822 format and automatically detects your Ubuntu version codename.
- When prompted to continue with any installation, type y and press Enter.
- Install Docker Engine and its companion packages by running:
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
What are all these packages?
- docker-ce is the Docker Engine itself.
- docker-ce-cli provides the docker command you'll use in the terminal.
- containerd.io manages the container lifecycle behind the scenes.
- docker-buildx-plugin and docker-compose-plugin add build and multi-container orchestration capabilities.
- Type y and press Enter when prompted to confirm the installation.
- Verify Docker is running by launching the test container:
sudo docker run hello-world
You should see a message that starts with "Hello from Docker!" followed by an explanation of what just happened.
Not seeing the Hello from Docker message?
- Make sure you ran the repository setup commands in order. If you skipped the final sudo apt update, apt won't know about the Docker packages.
- Check that you're using Ubuntu Server 26.04. Other Ubuntu versions or derivatives may behave differently.
- If you see a Snap-related Docker package, remove it first and reinstall from the official repository.
Help me troubleshoot my Docker installation on Ubuntu
Add your user to the docker group and configure the firewall
Right now you need sudo for every Docker command. Adding your user to the docker group removes that requirement.
- Add your current user to the docker group by running:
sudo usermod -aG docker $USER
What does this command do?
The -aG flag appends your user to the docker group without removing them from any other groups. $USER automatically expands to your current username.
This change takes effect after you log out and back in. You'll do that after setting up the firewall.
Now you'll configure UFW (Uncomplicated Firewall) to only allow SSH connections inbound. Cloudflare Tunnel works entirely over outbound connections, so no other ports need to be open.
- Allow SSH through the firewall and enable it by running these commands:
# Allow SSH connections so you don't get locked out
sudo ufw allow ssh
# Enable the firewall (denies all other inbound traffic by default)
sudo ufw enable
- When prompted "Command may disrupt existing SSH connections. Proceed with operation?", type y and press Enter.
- Verify the firewall is active and configured correctly by running:
sudo ufw status
You should see output showing the firewall is active with port 22 (SSH) allowed from anywhere.
Why only allow SSH?
Cloudflare Tunnel creates an outbound-only connection from your server to Cloudflare's network. Traffic from the internet reaches your Nextcloud through this tunnel without needing any inbound ports open.
SSH (port 22) is the only exception because you need it to manage your server remotely.
Lost your SSH connection after enabling UFW?
- If you're connected via SSH and lost access, you'll need physical access (keyboard + monitor) to your server. Run sudo ufw allow ssh directly on the machine.
- Always run sudo ufw allow ssh before sudo ufw enable to avoid locking yourself out.
Help me fix my SSH connection after enabling UFW
Confirm Docker starts on boot and apply group changes
On Ubuntu, Docker is automatically enabled to start on boot after installation via the official apt repository. You can confirm this with systemd.
- Verify Docker is enabled on boot by running:
sudo systemctl is-enabled docker
You should see enabled in the output. This means Docker will start automatically whenever your server reboots.
- Log out and log back in to apply the docker group membership change:
logout
- After logging back in, confirm the group change took effect by running a Docker command without sudo:
docker run hello-world
You should see the same "Hello from Docker!" success message, this time without needing sudo.
Still getting permission denied?
- Make sure you fully logged out and back in. Just opening a new terminal tab is not enough.
- If you're connected via SSH, disconnect the session completely and reconnect.
- Run groups to check if docker appears in the list. If not, re-run the sudo usermod -aG docker $USER command.
Help me fix Docker permission denied errors
Your server is now running Docker and locked down to SSH-only inbound access. Next up, you'll register a domain and connect it to Cloudflare so your Nextcloud can be reached from anywhere in the world.
Register a Domain and Set Up Cloudflare
Your server is locked down and running Docker. The next challenge is giving the outside world a way to reach your Nextcloud instance.
In this step, you'll register a domain name and set up Cloudflare to manage its DNS. This gives your file cloud a real web address that anyone (including you on your phone) can type into a browser.
In this step, get ready to:
- Purchase a domain name from a registrar.
- Create a free Cloudflare account and add your domain.
- Update your registrar's nameservers to point to Cloudflare.
Purchase a domain and create a Cloudflare account
Your Nextcloud instance needs a domain name so you can access it from any browser. A .xyz domain costs roughly $1-2 per year and works perfectly for a personal file cloud.
- Go to a domain registrar of your choice (Namecheap, Porkbun, or Cloudflare Registrar all work well).
- Search for and purchase a cheap domain. A .xyz domain is a great budget option.
- Make a note of the domain you purchased. You'll use a subdomain like cloud.yourdomain.xyz for your Nextcloud instance.
What is a domain name?
A domain name is the human-readable address that people type into a browser (like example.com). Without one, you'd have to remember your server's raw IP address to access your files.
Registrars like Namecheap, Porkbun, and Cloudflare Registrar let you reserve a domain name for a small annual fee.
- Open a new browser tab and go to cloudflare.com.
- Click Sign Up and create a free account using your email address and a secure password.
- Verify your email address if prompted.
Why Cloudflare?
Cloudflare acts as your DNS provider and will later enable you to create a secure tunnel to your server. The free plan includes everything you need for this project.
By managing DNS through Cloudflare, you also get built-in DDoS protection and a web application firewall at no extra cost.
Add your domain to Cloudflare and update nameservers
Now you need to tell Cloudflare about your domain so it can manage your DNS records and, later, route traffic through a tunnel.
- In the Cloudflare dashboard, click Domains in the left sidebar.
- Click Onboard a domain.
- Enter your domain (for example, yourdomain.xyz) in the domain field.
- Click Continue.
- Select the Free plan when prompted, then click Continue.
- Cloudflare will scan for existing DNS records. Review them (they may be empty for a brand-new domain) and click Continue.
Cloudflare now displays two nameservers assigned to your domain. These look something like adam.ns.cloudflare.com and bella.ns.cloudflare.com (your specific names will differ).
- Copy both nameserver addresses.
- Log in to your domain registrar (Namecheap, Porkbun, etc.) where you purchased the domain.
- Find the Nameservers or DNS settings for your domain.
- Replace the existing nameservers with the two Cloudflare nameservers you copied.
- Save the changes at your registrar.
What are nameservers?
Nameservers are specialized servers that store your domain's DNS records. They answer queries from browsers by providing the IP address needed to connect to your website.
By pointing your domain's nameservers to Cloudflare, you're telling the internet that Cloudflare is now in charge of resolving DNS queries for your domain.
If you bought your domain through Cloudflare Registrar
Domains purchased directly from Cloudflare Registrar already use Cloudflare nameservers automatically. You can skip the nameserver update step entirely.
Verify your domain is active in Cloudflare
DNS propagation (the time it takes for the nameserver change to spread across the internet) usually takes 5-30 minutes but can take up to 24 hours.
- Return to the Cloudflare dashboard.
- Click Domains in the left sidebar.
- Look for your domain in the list. Wait until the status column shows Active.
What should I see?
Your domain appears in the Domains list with a green Active status. This confirms Cloudflare is now the authoritative DNS provider for your domain.
Still showing Pending?
If your domain still shows a pending status after 30 minutes, double-check that you entered the Cloudflare nameservers exactly as shown (names are case-sensitive and must be copied precisely).
Also confirm at your registrar that the old nameservers were fully replaced, not just added alongside them.
Why is my domain still pending in Cloudflare after updating nameservers?
Your domain is live and Cloudflare is managing its DNS. Next up, you'll deploy Nextcloud on your server and configure it to work with a Cloudflare Tunnel.
Deploy Nextcloud AIO with Docker
Your server has Docker running and your domain is active in Cloudflare. Now it is time to deploy the actual application that will power your file cloud.
Nextcloud AIO (All-in-One) bundles everything you need into a single managed Docker container stack. It handles the database, caching, web server, and auto-updates for you. In this step, you will launch the AIO mastercontainer with settings configured for Cloudflare Tunnel mode, then start all the internal services.
In this step, get ready to:
- Deploy the Nextcloud AIO mastercontainer with Cloudflare Tunnel environment variables.
- Access the AIO management interface and save your admin passphrase.
- Start all Nextcloud services and verify they show green status.
Run the Nextcloud AIO mastercontainer
The AIO mastercontainer is the brain of your Nextcloud deployment. It manages all the other containers (database, cache, web server) and provides a web interface for administration.
- Launch the Nextcloud AIO mastercontainer by running this command:
sudo docker run \
--init \
--sig-proxy=false \
--name nextcloud-aio-mastercontainer \
--restart always \
--publish 8080:8080 \
--env APACHE_PORT=11000 \
--env APACHE_IP_BINDING=0.0.0.0 \
--env SKIP_DOMAIN_VALIDATION=true \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
ghcr.io/nextcloud-releases/all-in-one:latest
What does this command do?
- --name nextcloud-aio-mastercontainer names the container. Do not change this name. AIO updates depend on it.
- --restart always ensures the container restarts automatically whenever Docker starts.
- --publish 8080:8080 exposes the AIO management interface on port 8080 using a self-signed certificate.
- --env APACHE_PORT=11000 tells the internal Apache proxy to listen on port 11000 instead of port 443 (required for Cloudflare Tunnel).
- --env APACHE_IP_BINDING=0.0.0.0 binds Apache to all network interfaces so the tunnel can reach it.
- --env SKIP_DOMAIN_VALIDATION=true disables AIO's built-in domain check, which cannot work behind a Cloudflare Tunnel.
- --volume /var/run/docker.sock:/var/run/docker.sock:ro gives the mastercontainer read-only access to the Docker socket so it can manage other containers.
Why skip domain validation?
AIO normally checks that your domain resolves to the server's public IP. Cloudflare Tunnel routes traffic through Cloudflare's network instead, so this validation always fails. Setting SKIP_DOMAIN_VALIDATION=true is the officially documented workaround for Cloudflare Tunnel setups.
- Wait for the image to download and the container to start. You will see output ending with a message about the AIO interface being available on port 8080.
- Verify the container is running by running:
sudo docker ps
- You should see a container named nextcloud-aio-mastercontainer with status Up.
Container not starting?
- If you see a port conflict error, another service is already using port 8080. Check with sudo ss -tlnp | grep 8080 and stop the conflicting service.
- If Docker cannot pull the image, check your internet connection. The server needs outbound access to ghcr.io.
- If you see a permissions error on the Docker socket, make sure you are using sudo or that your user is in the docker group.
help me troubleshoot my Nextcloud AIO container not starting
Access the AIO interface and configure your domain
The mastercontainer is running. Now you need to access its web interface to set your domain name and retrieve the admin passphrase.
- Find your server's local IP address by running:
hostname -I | awk '{print $1}'
- Open a web browser on any computer on the same network as your server.
- Navigate to https:// followed by your server's IP address and :8080 (for example, https://192.168.1.50:8080).
You will see a certificate warning. This is expected.
The AIO interface uses a self-signed certificate on port 8080. Your browser will show a security warning. Click Advanced and then Proceed (or Accept the Risk and Continue in Firefox) to access the interface.
Always access this port by IP address, not by domain name. Using a domain on port 8080 can trigger HSTS and block future access.
- On the login page, you will see a generated admin passphrase. Copy this passphrase and save it somewhere safe (a text file, password manager, or written down).
- Enter the passphrase to log in to the AIO interface.
- In the Domain field, enter your full Nextcloud subdomain (for example, cloud.yourdomain.xyz).
- Click Submit.
Use whatever subdomain you prefer
You can use any subdomain like cloud, files, or nextcloud. You will configure this same subdomain in Cloudflare in the next step.
Cannot reach the AIO interface?
- Make sure you are using https:// (not http://) in the URL. Port 8080 only serves HTTPS.
- Confirm the browser is on the same local network as your server, or that you are accessing it directly via SSH-forwarded port.
- Run sudo docker ps to confirm the mastercontainer is still running.
help me access the Nextcloud AIO interface on port 8080
Start all Nextcloud containers
With your domain configured, AIO is ready to launch the full stack of services that power Nextcloud.
- In the AIO interface, click Start containers.
- Wait for all containers to download and initialize. This can take 3-10 minutes depending on your internet speed.
What services are starting?
AIO launches several containers that work together as a complete stack:
- Nextcloud is the main application handling files, users, and the web interface.
- PostgreSQL is the database storing user accounts, file metadata, and settings.
- Redis is an in-memory cache that speeds up page loads and session handling.
- Apache is the reverse proxy handling HTTPS connections on port 11000.
- Notify Push provides real-time file sync notifications to connected clients.
- Wait until all containers show a green status indicator in the AIO interface.
- Note the admin credentials displayed on the screen. You will use these to log in to Nextcloud itself after the tunnel is connected.
Containers stuck or showing errors?
- If a container shows a red or yellow status, wait a few more minutes. Large image downloads can take time on slower connections.
- If a container repeatedly fails to start, check your server has at least 4 GB of available RAM. AIO requires memory for the database and cache services.
- Click Stop containers and then Start containers again to retry.
help me fix Nextcloud AIO containers that are not starting properly
Your Nextcloud instance is fully deployed and running locally. Next up, you will create a Cloudflare Tunnel to make it accessible from anywhere in the world with a valid HTTPS certificate.
Create and Connect the Cloudflare Tunnel
Your Nextcloud instance is running and all containers show green status. Right now, it is only reachable from your local network through the server's IP address.
In this step, you will create a Cloudflare Tunnel that establishes a secure, outbound-only connection from your server to Cloudflare's network. This makes Nextcloud reachable at your custom domain from anywhere in the world without opening any router ports.
In this step, get ready to:
- Create a Cloudflare Tunnel in the dashboard.
- Install cloudflared on your server as a systemd service.
- Configure a public hostname route to reach Nextcloud.
Create a new tunnel in the Cloudflare dashboard
A Cloudflare Tunnel creates a persistent outbound connection from your server to Cloudflare's edge network. Your server initiates the connection, so no inbound ports or port forwarding are needed.
- Return to the Cloudflare dashboard in your browser.
- In the left sidebar, click Networking.
- Click Tunnels.
- Click Create Tunnel.
- Enter nextcloud-tunnel as the tunnel name.
- Click Create Tunnel (or Save tunnel, depending on the dashboard version).
- Under Setup Environment, make sure Linux is selected as the operating system.
- Copy the install command shown on the page. It contains your unique tunnel token.
Why Cloudflare Tunnel?
Traditional approaches like DuckDNS require port forwarding on your router. If you cannot port-forward (e.g., behind a carrier-grade NAT or restrictive ISP), those approaches fail entirely.
Cloudflare Tunnel uses only outbound connections from your server. It also gives you a custom domain, a free HTTPS certificate, and built-in DDoS protection.
Install cloudflared on your server
The install command you copied downloads cloudflared (the tunnel connector binary) and registers it as a systemd service so it starts automatically on boot.
- Switch back to your server terminal.
- Paste the install command you copied from the Cloudflare dashboard and press Enter. The command follows this format:
sudo cloudflared service install <TUNNEL_TOKEN>
What does this command do?
The token uniquely identifies your tunnel and authenticates your server with Cloudflare. The command downloads cloudflared, writes a systemd unit file, and starts the service automatically.
You do not need to type this command manually. Paste the exact command from the dashboard, which includes your token already embedded.
- Wait for the command to complete. You should see output confirming the service was installed.
- Verify the service is running by running this command:
sudo systemctl status cloudflared
- You should see active (running) in the output. Press q to exit the status view.
Not seeing active (running)?
If the status shows activating (auto-restart) or failed, check these common causes:
- Make sure you pasted the full command from the dashboard without truncating the token.
- Ensure your server has outbound internet access (the tunnel only needs outbound connections).
- Run journalctl -u cloudflared -e to see detailed error logs.
Still stuck? Help me troubleshoot why cloudflared is not running on my Ubuntu server.
- Back in the Cloudflare dashboard, you should see your connector appear. Click Next to proceed to route configuration.
Add a public hostname route
Now you will tell Cloudflare which domain should route to your Nextcloud instance. This creates a DNS record and maps incoming requests to your server's local port.
- In the Public Hostnames tab (or Routes section), click Add a public hostname (or Add route then Published application).
- In the Subdomain field, enter cloud.
- In the Domain dropdown, select your domain (e.g., yourdomain.xyz).
- Under Service, set the type to HTTP.
- For the URL, enter localhost:11000.
- Click Save.
Why localhost:11000?
Port 11000 is where the Nextcloud AIO Apache container listens for web traffic. This is the APACHE_PORT you configured when starting the mastercontainer. The tunnel routes external requests from your domain to this local port.
Port 8080 is only for the AIO management interface and should never be exposed publicly.
Your tunnel is now fully configured. Cloudflare handles HTTPS termination automatically, so visitors get a valid TLS certificate without any extra setup on your part.
- Open a browser on any device (your phone on mobile data works great for testing).
- Navigate to your Nextcloud URL:
https://cloud.[[YOUR_DOMAIN="yourdomain.xyz"]]
- You should see the Nextcloud login page with a valid HTTPS padlock in the address bar.
Not seeing the Nextcloud login page?
- DNS propagation can take a few minutes after saving the route. Wait 2-3 minutes and try again.
- Make sure your Nextcloud AIO containers are still running with green status. Check the AIO interface at https://<your-server-ip>:8080.
- Confirm you entered localhost:11000 (not localhost:8080) as the service URL in the tunnel route.
- Verify the tunnel shows a Healthy status on the Cloudflare Tunnels page.
Still stuck? Help me figure out why my Cloudflare Tunnel is not serving Nextcloud.
Your server is now securely connected to the internet. Next up, you will log in to Nextcloud and build an organized file storage system.
Set Up File Organization and Upload Files
Your Nextcloud instance is live and globally accessible. The infrastructure is done. Now it's time to make it useful by organizing your files into a structure that scales as your storage grows.
In this step, you'll log into your new cloud, set up a person-based folder system, and upload sample files to confirm everything works. By the end, you'll be able to browse, preview, and stream files from any device in the world.
In this step, get ready to:
- Log in to Nextcloud and configure your account settings.
- Create a person-based folder structure with subfolders for each file type.
- Upload sample files and verify previews work from any device.
Log in to Nextcloud and set your phone region
Your Nextcloud login page is already live at your custom domain. The admin credentials were generated by the AIO interface in the previous step.
- Open a browser on any device and go to your Nextcloud URL (e.g., https://cloud.yourdomain.xyz).
- Enter admin as the username.
- Enter the admin password shown in your AIO management interface.
- Click Log in.
After logging in, Nextcloud prompts you to set your default phone region. This determines the country code format for any phone numbers stored in contacts.
- Select your country from the dropdown when prompted.
- Click Set or Confirm to save.
You should now see the Nextcloud dashboard with the default welcome files. This is your personal file cloud, ready to be organized.
Can't log in?
Make sure you're using the admin password from the AIO management interface (the one at port 8080), not a password you created yourself. The AIO interface generates this password automatically.
If the page doesn't load at all, confirm your Cloudflare Tunnel is still running by checking its status in the Cloudflare dashboard under Networking > Tunnels.
Help me troubleshoot my Nextcloud login
Create person-based folders with subfolders
A person-based folder structure keeps files grouped by who they belong to, making it easy to find and manage files as your cloud grows.
- Click Files in the top navigation bar to open the file browser.
- Delete any default welcome files by selecting them and clicking the Delete action (or leave them if you prefer).
- Click the + button (or New) near the top of the file list.
- Select New folder.
- Type Jane Doe and press Enter.
- Repeat to create two more top-level folders: John Doe and John Bob.
Now create subfolders inside each person's folder to separate file types.
- Click into the Jane Doe folder.
- Create three subfolders: Documents, Images, and Videos (using the same + > New folder process).
- Navigate back to the root file list by clicking All files in the left sidebar or using the breadcrumb navigation at the top.
- Click into John Doe and create the same three subfolders: Documents, Images, Videos.
- Repeat for John Bob with the same three subfolders.
Your root file list should now show three person folders, each containing three subfolders.
Why organize by person?
Person-based top-level folders keep ownership clear. When you need to find Jane's tax documents or John's photos, you go straight to their folder instead of digging through a flat dump of hundreds of files.
The subfolder structure (Documents, Images, Videos) inside each person mirrors how most operating systems organize media. This makes drag-and-drop uploads intuitive.
Upload sample files and verify previews
With your folder structure in place, it's time to upload real files and confirm that Nextcloud can preview and play them directly in the browser.
- Navigate into Jane Doe > Documents.
- Click the + button and select Upload file.
- Choose any PDF from your computer (a receipt, a manual, anything you have handy).
- Navigate to Jane Doe > Images and upload any image file (JPEG, PNG, or similar).
- Navigate to Jane Doe > Videos and upload a short video file (MP4 works best for browser playback).
- Repeat for John Doe and John Bob: upload a PDF, an image, and a video into each person's respective subfolders.
Don't have sample files handy?
Search for "sample PDF" or "sample MP4" online to download free test files. Any file will work. The goal is to prove your cloud can store and preview multiple file types.
Now verify that Nextcloud's built-in previews work correctly.
- Click on any uploaded image. It should open in a full-screen preview with zoom controls.
- Click on any uploaded PDF. It should render inline in the browser without downloading.
- Click on any uploaded video. It should play directly in the browser with playback controls.
What should I see?
Images display in a lightbox-style viewer. PDFs render page-by-page inside the browser. Videos play with a standard video player interface (play/pause, volume, seek bar). If any of these download instead of previewing, the file format may not be supported for inline preview.
Finally, confirm your cloud works from outside your local network.
- On your phone, disconnect from WiFi and switch to mobile data.
- Open your phone's browser and navigate to your Nextcloud URL (e.g., https://cloud.yourdomain.xyz).
- Log in with the same admin credentials.
- Browse to any person's folder and confirm you can see your uploaded files.
- Tap an image to confirm it previews correctly on mobile.
If you can browse, preview, and play files on your phone over mobile data, your self-hosted cloud is fully functional from anywhere in the world.
Files not previewing or loading slowly?
If PDFs or videos download instead of previewing inline, try a smaller file. Cloudflare's free plan limits individual requests to 100 MB without chunking. The Nextcloud web UI uses chunked uploads for large files, but very large single-request downloads may hit this limit.
If the site doesn't load at all on mobile data, make sure your phone is actually off WiFi. Test by turning WiFi off entirely in your phone's settings.
Help me troubleshoot file previews in Nextcloud
Your personal file cloud is complete. You have a globally accessible, organized storage system running on your own hardware. Next up, the Secret Mission will show you how to harden your installation with two-factor authentication and server-side encryption.
Secret mission
Enable Two-Factor Authentication and Server-Side Encryption
Your file cloud is globally accessible, but it is protected by only a password. In this secret mission, you will harden your Nextcloud installation by adding TOTP-based two-factor authentication and encrypting all stored files at rest on the server.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. Your Nextcloud instance and Cloudflare Tunnel run locally on your server at no cost. The only ongoing expense is your domain name at roughly $1-2/year to renew.
Resources you used:
- Nextcloud AIO Docker containers (Nextcloud, PostgreSQL, Redis, Apache, Notify Push) running on your server.
- Cloudflare Tunnel (cloudflared) running as a systemd service on your server.
- A domain name registered with your registrar (renewal cost ~$1-2/year).
- A free Cloudflare account with your domain configured.
Keep everything running
No action needed. Choose this if you plan to keep using Nextcloud as your personal file cloud.
- Docker and cloudflared both restart automatically on reboot. Your Nextcloud stays accessible 24/7 at your domain.
- Your domain costs roughly $1-2/year to renew. You will receive a reminder from your registrar before it expires.
- Nextcloud AIO handles its own container updates through the AIO management interface at https://<your-server-ip>:8080.
Pause - I'll come back to this later
Shut down running processes to free up server resources while keeping all your files and configuration intact.
- Stop all Nextcloud containers from the AIO management interface (click Stop containers).
- Stop the Cloudflare Tunnel service by running:
sudo systemctl stop cloudflared
- Your Nextcloud will be offline and unreachable until you restart. To resume later, start cloudflared and restart containers from the AIO interface.
- Restart the tunnel later by running:
sudo systemctl start cloudflared
- Then access the AIO interface at https://<your-server-ip>:8080 and click Start containers.
Delete - I don't want to use this again
Remove all project resources from your server and start fresh. This deletes all files stored in Nextcloud.
This will permanently delete your data
The following steps remove all Nextcloud containers, volumes (including your stored files and database), and the Cloudflare Tunnel. Make sure you have backed up anything you want to keep before proceeding.
- Stop all containers from the AIO interface first. Then stop and remove the mastercontainer by running:
sudo docker stop nextcloud-aio-mastercontainer
sudo docker stop nextcloud-aio-domaincheck
- Remove all stopped containers by running:
sudo docker container prune
- Remove the AIO Docker network by running:
sudo docker network rm nextcloud-aio
- Remove all dangling volumes (this deletes your Nextcloud files and database) by running:
sudo docker volume prune
- Optionally remove all Docker images to free disk space by running:
sudo docker image prune -a
- Uninstall the Cloudflare Tunnel service by running:
sudo cloudflared service uninstall
- In the Cloudflare dashboard, navigate to Networking then Tunnels. Select your tunnel and delete it.
- Your domain will remain registered until its renewal date. To cancel it, let the domain expire at renewal time through your registrar's dashboard. There is no action needed now.
- Your free Cloudflare account can remain open at no cost. If you want to remove the domain from Cloudflare, go to the domain's Overview page and click Remove Site from Cloudflare.
Nice Work!
Nice Work!
You just deployed a fully self-hosted file cloud on your own hardware, accessible from anywhere in the world with a valid HTTPS certificate. No port forwarding, no monthly hosting fees, no handing your files to a third party.
You've learned how to:
- Deploy Nextcloud All-in-One as a managed Docker container stack with PostgreSQL, Redis, and Apache bundled together.
- Create a Cloudflare Tunnel for secure global access to a local service without opening any router ports or configuring port forwarding.
- Build a person-based file organization system with multiple file types including PDFs, images, and videos, all previewable from any device.
- Secret Mission: Hardened your installation with Two-Factor Authentication and server-side encryption for files at rest.
Ready to quiz yourself?