Self-hosted Network Storage Replacement for Dropbox
This is a guide on how to setup your own Nextcloud, a private self-hosted Google Workspace/Microsoft 365 alternative on your own VPS using Docker and nginx. In this guide, we’ll use the European provider Hetzner.
Infrastructure & Prerequisites
- Hetzner Instance: A Cost-Optimized instance (2 vCPU, 4GB RAM) is the recommended minimum, priced at ~€3.74/month.
- OS: Ubuntu 24.04 LTS.
- Domain: A domain registered at Cloudflare or other registrars is required.
1. Server Access
After creating your server there are two ways to access and setup your server: Hetzner Cloud Console or SSH for a more sustainable approach.
A. Cloud Console
The Cloud Console is a web-based terminal provided by Hetzner that allows you to access your server directly from your browser. This is ideal for initial setup if you do not have an SSH client ready or if you accidentally lock yourself out of your network configuration.
- Log in to Hetzner and select your server.
- Click the Console icon (>_) in the top right corner.
- Log in using the root username and the temporary password sent to your email.
- To reset the root password, visit the Rescue tab on your server page.
B. SSH
It is preferable to use an SSH key. Follow this guide to generate one for your OS. The public key
- Open your terminal and connect to your server via ssh root@YOUR_PUBLIC_SERVER_IP
- If no SSH key is set up, you will be prompted to login with the root password.
2. Server Setup
After gaining access to the server, we’ll setup Docker to run our service using the following commands:
# Add Docker's official GPG key: sudo apt update && sudo apt dist-upgrade sudo apt install ca-certificates curl 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 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 Signed-By: /etc/apt/keyrings/docker.asc EOF sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Create Service User (Optional)
It is wise for security reasons to create a service user instead of using root for managing services. We will create a user named
adduser sysadmin # Add user to sudo and docker groups usermod -aG sudo,docker sysadmin # Optional: Copy root SSH keys to the new user if you have an SSH key on the server rsync --archive --chown=sysadmin:sysadmin ~/.ssh /home/sysadmin
After this, you should be able to connect to the server via:
ssh sysadmin@YOUR_PUBLIC_SERVER_IP
3. Service Config
Docker Compose is used to generate the service. We’ll use nginx as a reverse proxy to route the traffic. Create a new file called
docker volume create nextcloud_aio_mastercontainer vim docker-compose.yaml
services: nginx: image: nginx:latest container_name: nginx-proxy restart: always ports: - "80:80" - "443:443" volumes: - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/certs:/etc/nginx/certs:ro networks: - nextcloud-network nextcloud-aio-mastercontainer: image: nextcloud/all-in-one:latest container_name: nextcloud-aio-mastercontainer restart: always ports: - "8080:8080" environment: - APACHE_PORT=11000 - APACHE_IP_BINDING=0.0.0.0 - SKIP_DOMAIN_VALIDATION=true # Required behind Cloudflare - APACHE_ADDITIONAL_NETWORK=nextcloud-network # Crucial for Nginx routing volumes: - nextcloud_aio_mastercontainer:/mnt/docker-aio-config - /var/run/docker.sock:/var/run/docker.sock:ro networks: - nextcloud-network networks: nextcloud-network: name: nextcloud-network volumes: nextcloud_aio_mastercontainer: external: true
4. Nginx Config
Create a new directory for the nginx config and certs:
mkdir -p nginx/certs mkdir -p nginx/conf.d
Create a new file called
Note: We use a variable for the
server { listen 80; server_name YOUR_DOMAIN; return 301 https://$host$request_uri; } server { listen 443 ssl; http2 on; server_name YOUR_DOMAIN; ssl_certificate /etc/nginx/certs/fullchain.pem; ssl_certificate_key /etc/nginx/certs/privkey.pem; location / { # Use Docker's internal DNS resolver to find the container resolver 127.0.0.11 ipv6=off valid=30s; # 'nextcloud-aio-apache' is the target container name created by AIO set $upstream_app nextcloud-aio-apache; proxy_pass http://$upstream_app:11000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; client_max_body_size 0; # Allows large file uploads proxy_request_buffering off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
5. Encryption Setup
Assuming you use Cloudflare as your domain registrar, you can get your SSL certificates by:
- Logging in to your Cloudflare Dashboard and selecting your domain.
- Navigating to SSL/TLS → Origin Server.
- Clicking Create Certificate. Keep the default settings (RSA 2048, 15-year validity) and ensure your domain (e.g., .jerr.aiandjerr.ai) is listed.
- Saving the certificates; this is the only time you’ll see the private key.
- Origin Certificate: Copy the contents of the first box and save it as fullchain.pemon your server.
- Private Key: Copy the contents of the second box and save it as privkey.pem.
- Origin Certificate: Copy the contents of the first box and save it as
- Copying the files into nginx/certs. Usescpto transfer them if you downloaded the certs locally.
- Crucial: In Cloudflare, navigate to SSL/TLS → Overview and set the encryption mode to Full (Strict). If you leave it on "Flexible", you will encounter infinite redirect loops.
6. Domain Setup
Create an A record (for IPv4) or AAAA record (for IPv6) pointing to your server. Set the Proxy status to Proxied (Orange Cloud) to handle SSL and provide a bridge for IPv4-only clients.
7. Final Access 🚀
- Launch the containers: docker compose up -d
- Open your browser and navigate to the Nextcloud AIO setup: https://YOUR_IP:8080(Use the IP address, not the domain, to avoid HSTS issues initially).
- Enter your domain and the password provided in the AIO logs.
- Select your desired add-ons (it’s highly advised to enable Fail2Ban for extra security).
- Click Start Containers. Once the Apache container spins up, your Nginx proxy will automatically begin routing traffic to your domain.
💡Pro Tip: How to Automate Updates
You can set Nextcloud AIO to update automatically, but it is tied to the Backup system to ensure safety.
- Go to the AIO Interface (:8080).
- Scroll to the Backup section and expand Backup Options.
- Create a backup (this might take some time).
- Go back to Backup Options and enable Daily backups and automatically update all containers.