Understanding the structure and execution of content on Posit Connect is helpful when planning more complex projects with shared resources.
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
server.R; R Markdown documents require a
.Rmd file; Plumber APIs will have an
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
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.
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's 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 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.
/report1/doc1.Rmd /report2/doc2.Rmd /shared/project_logo.png
Symlinks to Shared Files May Work#
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.
/report1/doc1.Rmd /report1/shared -> /shared /report2/doc2.Rmd /shared/project_logo.png
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.
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.
- This does not work for all publication methods.
- The RStudio IDE,
rsconnectR package, and
rsconnect-pythonwill resolve symlinks.
- Git-backed content will not resolve symlinks like this.
- Custom bundle creation methods may or may not support this, depending on implementation.
- The RStudio IDE,
- 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.
This is described in detail in this FAQ article.