Structuring Content

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.

/report1/doc1.Rmd
/report2/doc2.Rmd
/shared/project_logo.png

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.