--- title: "Advanced Usage" vignette: > %\VignetteIndexEntry{Advanced Usage} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} knitr: opts_chunk: collapse: true comment: '#>' eval: false --- Once you've deployed your first application with `buoyant`, you'll want to know how to manage it, update it, and use more advanced features. This guide covers everything from updating your deployed applications to running multiple apps on a single server, configuring HTTPS, and understanding how buoyant works under the hood. ## Prerequisites This guide assumes you've already: - Completed the [Getting Started](buoyant.html) tutorial - Successfully deployed at least one application - Have a running DigitalOcean droplet with buoyant If you haven't done these yet, start with the [Getting Started](buoyant.html) guide first. ## What You'll Learn In this guide, you'll learn how to: - **Manage deployments**: Update, redeploy, and remove applications - **Work with existing droplets**: Reference and reuse droplets without recreating them - **Customize your setup**: Configure droplet sizes, regions, and resource specifications - **Deploy multiple apps**: Run several applications on a single server - **Enable HTTPS**: Add SSL certificates with Let's Encrypt - **Monitor applications**: Check logs and service status - **Install dependencies**: Add system libraries and R packages to your server ## Managing Your Deployment ### Update Your Application Make changes locally, then redeploy: ```{.r} do_deploy_server( droplet = droplet, path = "api", local_path = "my-first-api", port = 8000, overwrite = TRUE # Replace existing deployment ) ``` ### Deploy Multiple Applications ```{.r} # Deploy a second application on the same server do_deploy_server( droplet = droplet, path = "v2", local_path = "my-second-api", port = 8001 # Different port! ) # Access at: # http:///api (first app) # http:///v2 (second app) ``` ### Remove an Application ```{.r} # Stop and remove do_remove_server(droplet, path = "api", delete = TRUE) ``` ### Delete the Server When you're completely done: ```{.r} library(analogsea) droplet_delete(droplet) ``` **Warning**: This permanently deletes your server and all data! ## Working with Existing Droplets You don't need to create a new droplet every time. You can reference existing droplets: ```{.r} # Get a reference to an existing droplet by ID droplet <- droplet(id = 12345678) # Or by name library(purrr) droplet <- droplets() %>% keep(~ .x$name == "my-server") %>% pluck(1) # Deploy to it do_deploy_server(droplet, "newapp", "path/to/app", port = 8002) ``` ## Custom DigitalOcean Configuration You can customize the droplet specifications: ```{.r} # Provision with specific size, region, and name droplet <- do_provision( size = "s-1vcpu-1gb", # 1 CPU, 1GB RAM region = "sfo3", # San Francisco data center name = "my-production-api" # Custom name ) ``` Common droplet sizes: - `s-1vcpu-512mb` - $5/month (basic) - `s-1vcpu-1gb` - $10/month See [DigitalOcean pricing](https://www.digitalocean.com/pricing) for current rates. ## Root Path Forwarding By default, applications are accessible at `http://ip/path`. You can forward the root path to an application: ```{.r} # Make an app accessible at the root do_forward(droplet, "myapp") # Now accessible at: http://ip/ instead of http://ip/myapp # Remove forwarding do_remove_forward(droplet) ``` ## Installing Server Dependencies If your application needs system libraries or R packages: ```{.r} # Install system packages droplet_ssh(droplet, "sudo apt-get install -y libgdal-dev") # Install R packages on the server do_install_server_deps(droplet, packages = c("sf", "terra")) ``` ## Monitoring Your Application ### Check Service Status SSH into your droplet to check logs: ```{.r} droplet_ssh(droplet, "journalctl -u server-api -f") ``` Or use analogsea's convenience functions: ```{.r} # Check if service is running droplet_ssh(droplet, "systemctl status server-api") ``` ### View Application Logs ```{.r} # View recent logs droplet_ssh(droplet, "journalctl -u server-myapp -n 50") # Follow logs in real-time droplet_ssh(droplet, "journalctl -u server-myapp -f") ``` ### Check Resource Usage ```{.r} # Check memory and CPU usage droplet_ssh(droplet, "htop") # Check disk usage droplet_ssh(droplet, "df -h") ``` ## Optional: Add HTTPS If you have a domain name: ```{.r} # 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` ## How It Works Understanding how `buoyant` works under the hood can help with troubleshooting: ### Provisioning (`do_provision()`) - Creates a DigitalOcean droplet with Ubuntu - Installs R, nginx, and required system libraries - Configures firewall (ports 22, 80, 443) - Sets up directory structure (`/var/server-apps/`) ### Deployment (`do_deploy_server()`) - Uploads application files to `/var/server-apps//` - Installs the engine package if not present - Creates a systemd service file at `/etc/systemd/system/server-.service` - The service runs: ```r Rscript -e " engine <- yaml::read_yaml('_server.yml')$engine launch_server <- get('launch_server', envir = asNamespace(engine)) launch_server('_server.yml', host = '127.0.0.1', port = ) " ``` - Creates nginx configuration at `/etc/nginx/sites-available/server-` - Enables and starts the service ### HTTPS (`do_configure_https()`) - Installs certbot - Obtains SSL certificate from Let's Encrypt - Updates nginx configuration for HTTPS - Sets up automatic certificate renewal ## Best Practices 1. **Version Control**: Keep your applications in git repositories 2. **Environment Variables**: Use environment variables for secrets (not in `_server.yml`) 3. **Testing**: Test locally before deploying 4. **Monitoring**: Set up monitoring and alerts for production applications 5. **Backups**: Regularly backup your application code and data 6. **Security**: Use HTTPS in production, keep packages updated 7. **Resource Sizing**: Start small, scale up as needed 8. **Cost Management**: Remember to delete droplets when not in use (`droplet_delete()`) ## Comparison with plumberDeploy If you're familiar with [plumberDeploy](https://github.com/meztez/plumberDeploy), here's how `buoyant` differs: | Feature | buoyant | plumberDeploy | |---------|---------|---------------| | Framework Support | Any `_server.yml` engine | plumber only | | Configuration | `_server.yml` standard | `plumber.R` files | | Deployment Target | DigitalOcean | DigitalOcean, AWS, Azure | | HTTPS Support | Yes (Let's Encrypt) | Yes (Let's Encrypt) | | Multiple Apps | Yes | Yes | `buoyant` is more focused but framework-agnostic, while `plumberDeploy` supports multiple cloud providers but is specific to plumber. ## Next Steps - See the [Troubleshooting vignette](troubleshooting.html) for common issues - Explore different [engines](https://plumber2.posit.co/articles/server_yml.html) - Set up CI/CD for automated deployments - Learn about DigitalOcean features like load balancers and databases