Understanding the structure and execution of content on Posit Connect is helpful when planning more complex projects with shared resources.
Content Bundles
A content bundle is a directory (folder) that represents a point-in-time of your code. Multiple bundles can exist for each piece of content, with only one active at a time. When you publish a piece of content to Posit Connect, the files you select are compressed and uploaded to the server, where they are extracted. This process preserves the hierarchical structure of the files and directories you include. Bundles are covered in more detail in the Posit Connect Server API Cookbook.
Requirements and Constraints for Bundle Contents
The bundle directory is used as the working directory when running your content.
Many content types have “primary target files”, which must be at the root (top level) of the bundle directory. The primary target file varies depending on the type of content: Shiny applications have an app.R or server.R; R Markdown documents require a .Rmd file; Plumber APIs will have an entrypoint.R or plumber.R; Python APIs and applications might live in a file named app.py. For some content types, top-level metadata files serve a similar role: R Markdown websites, bookdown books, and Quarto projects include _site.yml, _bookdown.yml, and _quarto.yml respectively.
A content bundle can also contain a number of additional files. These can be alongside the primary file in the root of the bundle directory, or in subdirectories inside the bundle. They might include design resources (such as images or CSS), datasets (such as CSV files) or additional source files (R or Python) used by the content.
Note
There are some limitations on the ways your content can access auxiliary files.
Posit Connect requires that the primary target file be located at the root level of the content bundle. Because of this requirement, bundles cannot contain auxiliary files above the primary target file.
Content execution takes place inside a security sandbox, which prevents content from reaching outside its bundle directory, except for select locations. Posit Connect’s sandboxing is described in detail in the Admin Guide.
Sharing Resources Between Published Content
For simple projects, it’s easy enough to include the files you need by placing them within the bundle directory, either alongside the primary file at the root level, or in subdirectories.
For situations where multiple projects access shared resources, some common patterns that work locally will not work with published content. Review the following warnings and recommendations before publishing.
Private Package Repositories
To share code between projects, we strongly recommend housing it in an R or Python package, and making the package available to your organization. There are a number of ways to achieve this, described in detail in the Admin Guide sections on R Package Management and Python Package Management.
Don’t Use Relative Paths to Shared Resources
Working locally, you might place shared resources in a common directory outside of a project, and reference it with a relative path. This will not work on Posit Connect. This is because the primary target for a piece of content must be at the root level of its bundle, and content runs in a security sandbox. Paths beginning with ../ will not find the files they expect.
In the following example, project_logo.png is located outside of the directories containing the R Markdown documents. The relative path to the logo from doc1.Rmd is ../shared/project_logo.png.
If doc1.Rmd is published to Posit Connect, it will be located at the top level of the resulting content bundle, and the reference to the project logo will break.
Referring to shared resources with symlinks will work for some publication methods, but not all. See below for more detail on this and other limitations of this approach.
When publishing doc1.Rmd with a compatible method, and including shared/project_logo.png, the symlink /report1/shared -> /shared will be resolved, and the resulting bundle on Posit Connect will contain a copy of the resource.
doc1.Rmdshared/project_logo.png
This allows you to reference the project logo with the same relative path, shared/project_logo.png, on your local computer and on the Posit Connect server.
Warning
This does not work for all publication methods.
The RStudio IDE, rsconnect R package, and rsconnect-pythonwill resolve symlinks.
Custom bundle creation methods may or may not support this, depending on implementation.
Because content receives a copy of the resource, it will not automatically update if the files change. To use the new resource, you would need to update the shared resource on your local computer and re-publish the content. This makes this method a a poor fit for files that may change, such as datasets, and for large files that would be duplicated on the server.
Persistent Storage on Posit Connect
Content on Posit Connect can access shared resources stored on the Posit Connect server. This option is well-suited for many scenarios, such as datasets that will update.