The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
This guide walks you through deploying your first _server.yml application using buoyant.
buoyant is an R package for deploying web server applications to DigitalOcean. It works with any R web framework that implements the _server.yml standard, including:
_server.yml standardWhen you deploy an application with buoyant:
do_configure_https())_server.yml StandardThe _server.yml standard is a lightweight specification that allows different R web frameworks to be deployed consistently. At minimum, your application needs a _server.yml file with an engine field:
engine: plumber2The engine R package must contain a launch_server(settings, host = NULL, port = NULL, ...) function that: - Accepts the path to the starting server file as the first argument. The starting server file must have a _server.yml in the same folder. - Can override host and port via parameters - Starts the web server
There are no regulations on any other fields within _server.yml.
{plumber2} adheres to the _server.yml standard and in the following we will go through how it does so as an example for other engine developers who wish to support it.
{plumber2} currently defines 3 fields in addition to the engine field:
routes: An array of R files or folders that contain the server logic as annotated functions and objects.constructor: A path to a single R file that constructs the Plumber2 object.options: A list of options to use for the server. These all corresponds to options that can be seen in ?plumber2::all_opts().{plumber2} provide a function (create_server_yml()) that creates this file for you so that the user can be confident that it is formatted correctly. This is generally a good idea and also provides a place to document the content of the file.
launch_server()The launch_server() function is quite simple for {plumber2} since the api() constructor itself understands _server.yml files as input. Because of this the function looks like this:
{.r launch_server} function(settings, host = NULL, port = NULL, ...) { pa <- api(settings) if (!is.null(host)) { pa$host <- host } if (!is.null(port)) { pa$port <- port } api_run(pa) } <environment: namespace:plumber2>
Create a _server.yml compliant application. For example, with {plumber2}:
{.yaml server_yaml} #| file: _server.yml engine: plumber2 routes: app.R constructor: ~ options: {}
```{.r app} #| file: app.R #* @get /hello function() { list(message = “Hello from buoyant!”) }
#* @get /add #* @query a First number #* @query b Second number function(query) { result <- as.numeric(querya) + as.numeric(queryb) list(result = result) }
## Step 2: Test Locally (Optional)
If you have `{plumber2}` installed:
```{.r}
library(plumber2)
api("_server.yml") |> api_run()
Visit http://127.0.0.1:8080/api-docs to see your API documentation.
# Authenticate with DigitalOcean
# This will open a browser for authentication
analogsea::do_oauth()
# Check authentication and existing droplets
analogsea::droplets() # Should return a list (may be empty)Make sure you provide digitial ocean your public key at https://cloud.digitalocean.com/ssh_keys. Github has some good advice on creating a new public key if you don’t already have one: https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent.
Be sure to store your Host to digitalocean.com within your ssh config to point to your private key that you’ve created:
Host github.com
UseKeychain yes
IdentityFile ~/.ssh/newly_created_key_file
If you didn’t use a password when creating your SSH key, you can skip the UseKeychain line.
You can verify your DigitalOcean SSH key exists with the proper host with by calling buoyant::do_keyfile() and having it return the path to your private key.
library(buoyant)
# This will cost money! Check DigitalOcean pricing first.
# A basic droplet costs around $6/month (as of 2025)
droplet <- do_provision(
name = "my-api-server",
region = "sfo3", # San Francisco
size = "s-1vcpu-1gb" # Basic tier
)
# This will take a few minutes...
# It installs R, nginx, firewall, and sets up the server structure# Validate your _server.yml file first
validate_server_yml("./")
# Deploy!
droplet |>
do_deploy_server(
path = "api", # URL sub-path: /api
local_path = "./_dev/barret", # Local directory
port = 8000, # Internal port
forward = TRUE, # Forwards `/` to `/api`
overwrite = TRUE
)The deployment process:
{plumber2})# Get the URL
url <- do_ip(droplet, "/api")
print(url) # e.g., "http://165.232.134.23/api"
# Open in browser
browseURL(paste0(url, "/hello"))
# Or use httr2 to test
httr2::request(paste0(url, "/hello")) |>
httr2::req_headers(Accept = "text/plain") |>
httr2::req_perform() |>
httr2::resp_body_string()
#> [1] "Hello from buoyant!"
httr2::request(paste0(url, "/add?a=5&b=3")) |>
httr2::req_headers(Accept = "text/plain") |>
httr2::req_perform() |>
httr2::resp_body_string()
#> [1] "8"SSH into your droplet to check logs:
analogsea::droplet_ssh(droplet, "journalctl -u server-api -f")Or to see if the service is running
analogsea::droplet_ssh(droplet, "systemctl status server-api")If you have a domain name:
# Point your domain to the droplet IP
ip <- do_ip(droplet)
print(ip)
# After DNS is configured (wait for propagation):
do_configure_https(
droplet = droplet,
domain = "api.yourdomain.com",
email = "you@example.com",
terms_of_service = TRUE # Agree to Let's Encrypt TOS
)Now your API is available at https://api.yourdomain.com/api
You’ve successfully deployed your first application! Here are some next steps:
overwrite = TRUE when you make changesdo_configure_https() with your domain namejournalctl -u server-myappFor detailed information, see:
{plumber2} docs: https://plumber2.posit.co{analogsea} docs: https://github.com/pachadotdev/analogsea_server.yml specification: https://plumber2.posit.co/articles/server_yml.htmlThese binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.