You can self-host R Shiny applications on an x86-64 Linux VPS by installing R and the Shiny package, installing Shiny Server separately, placing each app under /srv/shiny-server/, and publishing it through a domain and HTTPS proxy. The open-source edition is free under AGPLv3, listens on port 3838 by default, and does not include user login. For private data, add an identity-aware proxy or use Shiny Server Pro or Posit Connect.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
What Shiny Server does
Shiny Server is the web server program that publishes R Shiny applications and manages their HTTP connections. One installation can host several apps, each available at its own URL path. With the default directory and listener, an application named sales-dashboard is reached at http://HOST:3838/sales-dashboard/.
As an Amazon Associate I earn from qualifying purchases.
The open-source project is free and licensed under AGPLv3. It is software you operate yourself: you are responsible for Linux updates, firewall rules, TLS certificates, backups, application dependencies, monitoring and access control.
A VPS is useful because it provides a persistent public IP address and an always-on environment. It is not a substitute for sizing or security work. Shiny apps can consume substantial memory and CPU, especially when several users trigger expensive R calculations at the same time.
#1 Best Overall
Supported operating systems and prerequisites
Use a 64-bit x86-64 VPS and a current distribution supported by Posit’s administrator guide. The current support list covers:
| Platform | Supported baseline | Practical note |
|---|---|---|
| Red Hat Enterprise Linux-compatible systems | RHEL 8 or newer, x86-64 | Use the package instructions for the exact compatible distribution. |
| Ubuntu | Ubuntu 22.04 LTS or newer, x86-64 | Ubuntu 22.04 LTS and 24.04 LTS are the straightforward choices for a new VPS. |
| SUSE Linux Enterprise Server | SLES 15 SP7 | Follow the current Posit instructions rather than an older README. |
Older support lists may still appear in cached READMEs or blog posts. Treat those lists as historical and check the current administrator guide before creating the server.
VPS checklist
- An x86-64 CPU architecture, not an ARM-only instance unless the current Shiny Server release explicitly supports it.
- A non-root administrator account with
sudoaccess. - A hostname and a plan for DNS. A fully qualified name such as
shiny.example.commakes HTTPS and future migration easier. - Enough memory for R, the Shiny process and your app’s data. Start with a small instance for a test app, then measure real memory use before increasing concurrency.
- Inbound SSH during administration and inbound HTTPS for visitors. Keep the Shiny port private when a reverse proxy is used.
- Regular snapshots or backups for application code, configuration and any data the app can recreate or restore.
Prepare Ubuntu safely
The commands below assume Ubuntu 22.04 LTS or newer and an account with sudo. Replace the example hostname and username with your own values.
- Create a non-root administrator. Create the account in your VPS control panel or with
sudo adduser deploy, then grant administrative access withsudo usermod -aG sudo deploy. Test a second SSH session before disabling root login. - Set the hostname. Use your provider’s hostname controls or
sudo hostnamectl set-hostname shiny.example.com. Ensure the name resolves to the VPS address before requesting a certificate. - Update the operating system.
sudo apt update sudo apt full-upgradeReboot if the kernel or another system component requests it, then reconnect.
- Configure the firewall. With UFW, allow SSH and web traffic before enabling it:
sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status verboseDo not open 3838 publicly unless you intentionally want direct access. If you test directly from a remote machine, allow it only temporarily and remove the rule afterward.
Install R and the Shiny package first
The Shiny Server installer does not include R or the Shiny R package. Install those prerequisites before installing the server itself.
Install the distribution R package
sudo apt update
sudo apt install r-base
Ubuntu’s repository version is adequate for many applications. If your app requires a newer R release than Ubuntu currently provides, add the appropriate CRAN repository for your Ubuntu release using CRAN’s current instructions, then install or update r-base. Do not copy a repository stanza meant for a different Ubuntu release.
Install Shiny system-wide
Install the package into the library visible to the service account:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsRank #2
sudo R -e 'install.packages("shiny", repos="https://cloud.r-project.org")'
Verify both components before proceeding:
R --version
sudo R -e 'packageVersion("shiny")'
Every package imported by your application must also be installed in a library that the shiny service user can read. For reproducible deployments, record the R version and package versions in your deployment notes and update them deliberately rather than during an unrelated server change.
Install Shiny Server
Shiny Server is distributed separately from R. On Ubuntu, Posit’s documented installation flow uses an amd64 .deb package and gdebi.
- Open Posit’s current Shiny Server download page in a browser and select the package for your Ubuntu release and x86-64 architecture. Save the package on the VPS or transfer it over SSH. Do not use an ARM package on an x86-64 host, or vice versa.
- Install the package installer:
sudo apt update
sudo apt install gdebi-core
- Install the downloaded package. Replace the filename with the exact file you downloaded:
sudo gdebi shiny-server-*.deb
The installation places the server under /opt/shiny-server/, creates a shiny service account and installs the standard configuration and service files. Record the package version in your change log so an upgrade is a planned operation, not an accidental replacement.
Start and enable the service
sudo systemctl enable --now shiny-server
sudo systemctl status shiny-server --no-pager
If the unit is not found on an older or unusual distribution, consult the package’s service instructions instead of inventing a unit name. On supported modern Linux systems, the installed systemd unit is the normal control point.
Deploy your first Shiny application
The default application root is /srv/shiny-server/. Each immediate subdirectory can represent an application. A minimal layout looks like this:
/srv/shiny-server/
└── hello/
└── app.R
Copy application files
Create the directory and copy your tested app from a workstation or source repository:
sudo mkdir -p /srv/shiny-server/hello
sudo cp app.R /srv/shiny-server/hello/app.R
sudo chown -R shiny:shiny /srv/shiny-server/hello
sudo chmod -R u=rwX,go=rX /srv/shiny-server/hello
The service account needs to read the application and any bundled assets. Avoid making the entire tree world-writable. If the app writes uploads, caches or generated files, give write permission only to the specific directory that needs it and consider placing mutable data outside the application code.
Test locally before exposing the VPS
From the VPS, request the default listener:
curl -I http://127.0.0.1:3838/hello/
A successful response confirms that the listener is reachable, but it does not prove that the app can load every R package or data file. Open the app in a browser using the VPS address only after the local check works. If the VPS firewall blocks direct testing, use an SSH tunnel from your workstation:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
ssh -L 3838:127.0.0.1:3838 [email protected]
Then browse to http://127.0.0.1:3838/hello/ on your workstation. This keeps port 3838 closed to the Internet while you debug.
Understand and edit shiny-server.conf
The default configuration file is /etc/shiny-server/shiny-server.conf. A basic configuration for the default application directory is:
run_as shiny;
server {
listen 3838;
location / {
site_dir /srv/shiny-server;
log_dir /var/log/shiny-server;
directory_index on;
}
}
The listen directive controls the TCP port. Port 3838 is the default. Change it only when another service already occupies that port or when you want the listener on a private, proxy-only port. Keep the configuration in version control, but never commit private keys, passwords or tokens.
Apply a configuration change
- Back up the current file:
sudo cp /etc/shiny-server/shiny-server.conf /etc/shiny-server/shiny-server.conf.bak. - Edit it with your preferred editor:
sudoedit /etc/shiny-server/shiny-server.conf. - Restart the service:
sudo systemctl restart shiny-server. - Check the result immediately:
sudo systemctl status shiny-server --no-pagerandsudo tail -n 100 /var/log/shiny-server.log.
If the service fails after an edit, restore the backup, restart, and inspect the log for the offending directive. A syntax error, an occupied port or an unreadable application directory is more likely than a problem with the VPS provider.
Rank #4
Put the server behind a domain and HTTPS
A public deployment should use a DNS name and trusted TLS. Point an A or AAAA record for your chosen hostname to the VPS address, then obtain a certificate through your certificate authority’s documented process. Renew the certificate before it expires and test renewal in advance.
Option 1: terminate TLS in Shiny Server
Shiny Server documents native SSL directives. This keeps the TLS configuration in the Shiny Server process, but you must manage certificate files, private-key permissions, renewal and listener settings there. Restrict private-key files to root and the process that must read them, and review /var/log/shiny-server.log after every certificate change.
Option 2: use a reverse proxy
A reverse proxy such as Nginx, Apache or Caddy can handle certificates and forward requests to a private Shiny listener. In this design, bind Shiny Server to localhost or a private interface and allow only ports 80 and 443 at the firewall. A representative Nginx location is:
Free tools Windows power users keep installed
One-click scans. No signup required.
server {
listen 443 ssl;
server_name shiny.example.com;
ssl_certificate /etc/ssl/shiny/fullchain.pem;
ssl_certificate_key /etc/ssl/shiny/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3838;
proxy_http_version 1.1;
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Use your proxy’s actual certificate paths and validate its configuration before reloading. WebSocket upgrade headers matter for interactive Shiny sessions. If the page loads but controls stop responding, inspect proxy and browser logs for failed WebSocket requests.
Redirect plain HTTP
Keep port 80 only for a redirect to HTTPS or for the certificate authority’s challenge mechanism. Do not expose an unencrypted login or private data endpoint as a permanent alternative.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Authentication: what open-source Shiny Server cannot do
Open-source Shiny Server does not provide built-in user authentication. It cannot create native user accounts or protect an app with a server-managed login screen. Adding an application-level password without a proper identity system can expose credentials and does not provide reliable authorization.
Best Value
Choose an access-control design before publishing confidential data:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →| Option | Authentication | Administration and monitoring | When it fits | Licensing and support |
|---|---|---|---|---|
| Open-source Shiny Server | No built-in user authentication | You manage Linux, logs, TLS, updates and scaling | Public apps or deployments where an external access layer is acceptable | Free, AGPLv3; community-led operation |
| Shiny Server Pro | Designed for managed authentication features | Commercial administration and operational features | Organizations that need integrated access control and vendor support | Commercial product; confirm current terms with Posit |
| Posit Connect | Integrated publishing and authentication workflows | Broader deployment, permissions and monitoring capabilities | Teams publishing multiple content types with centralized governance | Commercial product; confirm current terms with Posit |
If you stay on the open-source edition, place a separately managed identity-aware proxy in front of the HTTPS endpoint. Treat that proxy as a security boundary: enforce MFA where appropriate, validate forwarded headers, define authorization groups, log access and test logout and session expiry. A reverse proxy that merely terminates TLS is not automatically an authentication system.
Operate the VPS after launch
Service health and logs
sudo systemctl status shiny-server --no-pager
sudo journalctl -u shiny-server -n 100 --no-pager
sudo tail -f /var/log/shiny-server.log
Check the Shiny log after configuration, certificate, proxy or application changes. Keep enough log retention to investigate failures, but rotate logs so they cannot fill the disk.
Backups
Back up /etc/shiny-server/shiny-server.conf, application directories, proxy configuration and any non-reproducible data. Test restoring an app to a separate VPS; a backup that has never been restored is only an assumption.
Updates
Apply Ubuntu security updates, R updates and R package updates on a schedule. Read release notes for Shiny Server before upgrading, test in a staging VPS, and pin the package version in your deployment notes. Upgrade one layer at a time so a failure can be isolated.
Resource monitoring
Watch memory, CPU, disk space and the number of concurrent sessions. R processes may grow with data size, and several users can multiply that cost. If the VPS begins swapping, reduce workload, optimize the app, add memory or move to a more suitable architecture before users experience timeouts.
Troubleshooting by symptom
The service will not start
- Run
sudo systemctl status shiny-serverand inspectjournalctl -u shiny-server. - Check the syntax and spelling in
/etc/shiny-server/shiny-server.conf. - Confirm that no other process owns the configured port with
sudo ss -ltnp. - Restore the last known-good configuration if the failure began after an edit.
The default page works but the app returns an error
- Confirm the directory is under
/srv/shiny-server/or matches the configuredsite_dir. - Check ownership and read permissions for the
shinyuser. - Install missing R packages into a library visible to that account.
- Read
/var/log/shiny-server.logwhile reproducing the error.
The app works on localhost but not through the domain
- Verify DNS resolves to the VPS address.
- Confirm the proxy is listening on 443 and forwarding to the same local port Shiny uses.
- Check the VPS firewall and provider-level firewall for ports 80 and 443.
- Inspect TLS certificate paths and expiration.
- For interactive failures, verify WebSocket upgrade headers and proxy timeouts.
Users can reach port 3838 directly
Remove the public 3838 firewall rule and bind the Shiny listener to localhost or a private interface when the proxy is intended to be the only entry point. Re-test from an external network, not only from the VPS itself.
Quick Recap
A repeatable deployment sequence
- Provision an x86-64 VPS running Ubuntu 22.04 LTS or newer, create a non-root administrator and apply updates.
- Set DNS and a hostname; decide whether a reverse proxy will terminate TLS.
- Install R, the Shiny R package and all application-specific dependencies.
- Download the current amd64 Shiny Server package from Posit and install it with
gdebi. - Enable the systemd service and verify it locally on port 3838.
- Deploy a minimal sample app under
/srv/shiny-server/, fix permissions and test it through an SSH tunnel. - Place the real app in its own directory, record package versions and test its main user flows.
- Configure the listener and routes in
/etc/shiny-server/shiny-server.conf; restart and inspect logs. - Point DNS to the VPS, obtain a trusted certificate and configure native SSL or a reverse proxy.
- Close unnecessary inbound ports, decide on authentication, document backups and establish monitoring before sharing the URL.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




