- Self-Hosted Cloud & Media Server Setup on Oracle Cloud Free Tier
- Table of Contents
- 1. Overview
- 2. Oracle Cloud VM Setup
- 3. Initial Server Configuration
- 4. HestiaCP Installation
- 5. Domain & DNS Configuration
- 6. User Management in HestiaCP
- 7. Nextcloud Manual Installation
- 8. Plex Media Server Installation & Configuration
- 9. Oracle Cloud Backups
- What Success Looks Like
- 10. Final Recommendations
This guide documents the process of setting up a self-hosted cloud and media server using HestiaCP, Nextcloud, and Plex on an Oracle Cloud Free Tier VM, with custom domains and shared storage. All user-specific values are marked as <VARIABLE>
for you to replace.
- Provision a VM (Ampere ARM A1, 4 OCPUs, Ubuntu 22.04 LTS recommended).
- Open required ports: 22 (SSH), 80 (HTTP), 443 (HTTPS), 32400 (Plex).
- Note: 4 OCPUs can run 24/7 within the free 3000 OCPU hours/month.
sudo apt update
sudo apt install zsh -y
sudo chsh -s $(which zsh) <USERNAME>
# Log out and back in
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
- Set a password for the
<USERNAME>
user:sudo passwd <USERNAME>
- To enable password SSH login (not recommended for security), edit
/etc/ssh/sshd_config
:
Then restart SSH:PasswordAuthentication yes
sudo systemctl restart ssh
sudo apt update && sudo apt upgrade -y
sudo hostnamectl set-hostname <HOSTNAME>
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh --force
- Access HestiaCP at
https://<SERVER_IP>:8083
- If you see
Error: group admin exists
, use the--force
flag as above.
- Add your domain (e.g.,
<NEXTCLOUD_DOMAIN>
) in HestiaCP under Web. - In your DNS provider (e.g., afraid.org/FreeDNS), create an A record pointing your domain to your VM's public IP.
- Enable SSL Support and Let's Encrypt Support in HestiaCP for your domain.
- Create a standard user (e.g.,
<USERNAME>
) in HestiaCP for security. - Log in as this user for all web/domain/database management.
- In HestiaCP, go to DB > Add Database.
- Note the database name, username, and password.
cd /tmp
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
sudo rm -rf <WEBROOT>/*
sudo mv nextcloud/* <WEBROOT>/
sudo mv nextcloud/.htaccess <WEBROOT>/
sudo mv nextcloud/.user.ini <WEBROOT>/
sudo chown -R www-data:<USERNAME> <WEBROOT>
sudo find <WEBROOT>/ -type d -exec chmod 750 {} \;
sudo find <WEBROOT>/ -type f -exec chmod 640 {} \;
- If you need to increase PHP memory limit, add to
.user.ini
in your web root:memory_limit = 512M
- Create shared folder:
sudo mkdir -p <SHARED_FOLDER> sudo chown -R www-data:<USERNAME> <SHARED_FOLDER> sudo chmod 775 <SHARED_FOLDER> sudo chmod 755 /srv
- In Nextcloud, enable the External storage support app.
- Add
<SHARED_FOLDER>
as a local external storage.
- If you see "local storage path does not exist":
- Ensure
<SHARED_FOLDER>
exists and is owned bywww-data:<USERNAME>
with775
permissions. - Ensure
/srv
is755
(if using/srv
as parent). - Restart PHP-FPM and Apache:
sudo systemctl restart php<PHP_VERSION>-fpm sudo systemctl restart apache2
- Ensure
- Edit
/etc/php/<PHP_VERSION>/fpm/pool.d/<USERNAME>.conf
(orwww.conf
):php_admin_value[open_basedir] = <WEBROOT>:<SHARED_FOLDER>:/tmp
- Restart PHP-FPM:
sudo systemctl restart php<PHP_VERSION>-fpm
- .mjs MIME Type:
Add to.htaccess
:AddType application/javascript .mjs
- Integrity Check (missing .reuse/dep5):
Download the same Nextcloud version, copy.reuse/dep5
to your install, and set correct permissions. - SSL:
Enable Let's Encrypt in HestiaCP. - PHP Memory Limit:
Setmemory_limit = 512M
in.user.ini
. - Strict-Transport-Security:
Add to.htaccess
:<IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" </IfModule>
- OPcache, memcache, phone region, email, and other warnings:
See Nextcloud documentation for detailed fixes.
wget https://downloads.plex.tv/plex-media-server-new/<PLEX_VERSION>/debian/plexmediaserver_<PLEX_VERSION>_arm64.deb
sudo dpkg -i plexmediaserver_<PLEX_VERSION>_arm64.deb
sudo systemctl enable --now plexmediaserver
-
Add Plex user to the group for media access:
sudo usermod -aG <USERNAME> plex sudo systemctl restart plexmediaserver
-
Open port 32400 in Oracle Cloud Security Lists.
-
Access Plex at
http://<SERVER_IP>:32400/web
- Add
<PLEX_DOMAIN>
in HestiaCP, enable SSL/Let's Encrypt. - In your DNS provider, point
<PLEX_DOMAIN>
to your server IP. - Enable Apache proxy modules:
sudo a2enmod proxy proxy_http proxy_wstunnel sudo systemctl reload apache2
- In HestiaCP, for
<PLEX_DOMAIN>
, add to Additional Apache directives for SSL:ProxyPreserveHost On ProxyPass / http://127.0.0.1:32400/ ProxyPassReverse / http://127.0.0.1:32400/ ProxyPass /websockets http://127.0.0.1:32400/websockets ProxyPassReverse /websockets http://127.0.0.1:32400/websockets RequestHeader set X-Forwarded-Proto "https"
- Restart Apache:
sudo systemctl reload apache2
- Access Plex at
https://<PLEX_DOMAIN>
- In Plex, go to your library settings.
- Enable Show Folders (or "Show Photos in Folders" for photo libraries) in the Advanced tab.
- For both videos and photos, use a "Home Videos & Photos" library type and point it to
<SHARED_FOLDER>
.
To make your Plex server accessible at a domain (e.g., <PLEX_DOMAIN>
) without exposing the port in the URL, use a custom Nginx proxy template in HestiaCP:
cd /usr/local/hestia/data/templates/web/nginx/
sudo nano plex.tpl
Paste the following contents:
server {
listen %ip%:%proxy_port%;
server_name %domain_idn% %alias_idn%;
location / {
proxy_pass http://127.0.0.1:32400;
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;
}
}
sudo nano plex.stpl
Paste the following contents:
server {
listen %ip%:%proxy_ssl_port% ssl http2;
server_name %domain_idn% %alias_idn%;
ssl_certificate %ssl_pem%;
ssl_certificate_key %ssl_key%;
ssl_stapling on;
ssl_stapling_verify on;
location / {
proxy_pass http://127.0.0.1:32400;
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;
}
}
- Go to Web → Edit your
<PLEX_DOMAIN>
domain. - In Proxy Template, select
plex
. - Save changes.
Now, visiting https://<PLEX_DOMAIN>
will reverse proxy to your Plex server on port 32400, without exposing the port in the URL.
To ensure external access to Plex, you need to allow port 32400 through your server's firewall using the HestiaCP interface:
- Open your HestiaCP dashboard in your browser and log in as an admin user.
-
Before adding rules, check the status of the firewall in HestiaCP:
- In the HestiaCP dashboard, go to Server Settings > Firewall.
- Make sure the firewall is enabled and running (there should be an indicator, toggle, or start button for the firewall status).
- If the firewall is disabled, enable or start it from this page.
-
Alternative method:
- Go to Server Settings in HestiaCP.
- Look for the
iptables
(orfirewall
) service in the list. - If it is stopped, use the start button to activate the service.
Note: If you are unsure whether the firewall is active, consult the HestiaCP documentation or your hosting provider's support for guidance on enabling the firewall service via the web interface.
- In the top menu, click on Server Settings.
- In the left sidebar, select Firewall.
- Click the Add Rule button.
- Fill in the rule details:
- Action: ACCEPT
- Protocol: TCP
- Port: 32400
- IP: 0.0.0.0/0 (or restrict to a specific IP range if desired)
- Click Save to add the rule.
- Make sure the new rule is enabled (toggle should be ON).
- The firewall will reload and the rule will take effect immediately.
This will allow external access to Plex on port 32400 using only the HestiaCP web interface.
- You can create a boot volume backup (snapshot) in the Oracle Cloud Console.
- The Free Tier includes 10 GB of Object Storage for free.
- If your snapshot fits within this, it's free.
After completing the setup, you should be able to:
-
Access HestiaCP:
- Visit
https://<SERVER_IP>:8083
or your custom admin domain. - Log in with your admin or user credentials.
- See your domains, users, and services listed and manageable.
- Visit
-
Access Nextcloud:
- Visit your Nextcloud domain (e.g.,
https://<NEXTCLOUD_DOMAIN>
). - Log in with your Nextcloud credentials.
- Upload, download, and manage files.
- See external storage (e.g.,
<SHARED_FOLDER>
) if configured. - No major admin warnings (or all are resolved as per the guide).
- Visit your Nextcloud domain (e.g.,
-
Access Plex:
- Visit
https://<PLEX_DOMAIN>
(or your chosen Plex domain). - The Plex web interface loads and you can log in with your Plex account.
- Your media libraries are visible and playable.
- If you visit
http://<SERVER_IP>:32400/web
, the Plex web interface loads (if you allowed direct access).
- Visit
-
SSL/HTTPS:
- All your domains (Nextcloud, Plex, HestiaCP) are accessible via HTTPS with valid certificates (no browser warnings).
-
Firewall:
- The firewall is active in HestiaCP and port 32400 is open for Plex.
-
Reverse Proxy:
- Your Plex domain does not show the port in the URL and works via HTTPS.
If all of the above are true, your self-hosted cloud and media server setup is complete and working as intended!
- Security: Use strong passwords, keep your system updated, and restrict open ports.
- Backups: Regularly back up your data and monitor Object Storage usage.
- Performance: Monitor server resources and optimize as needed.
- Expandability: You can add more apps (e.g., Jellyfin, other Nextcloud apps) as needed.
Congratulations!
You now have a robust, free, self-hosted cloud and media server with custom domains, SSL, and shared storage, all managed through HestiaCP.
If you need to add more features or troubleshoot further, refer to the relevant section above or reach out for help!