This document explains some requirements of the structure of content published to Posit Connect. These are important to consider when sharing resources between different pieces of content deployed to Connect.
Content bundles
A content bundle is the directory (folder) that contains the code and other resources for a piece of content. Connect uses the bundle directory as its working directory when running the content.
When content is published to Connect, selected files are compressed and uploaded to the server, where they are extracted, preserving the hierarchical structure of files and directories. When you publish an update to a piece of content, a new bundle is created and uploaded. The old bundles are saved, and can be reactivated from the Dashboard.
Most content types have primary target files that serve as the entrypoint when content is rendered or served.
Warning
The primary target file must be located at the root level of the content bundle (the directory containing the content’s resources).
The type of the primary file depends on the content type. Applications and APIs use a Python or R file as their entrypoint (e.g. app.py, app.R, plumber.R). Documents use Quarto, R Markdown, and Jupyter Notebook files (e.g. report.qmd, doc.rmd, notebook.ipynb). Websites and projects generally use metadata files (e.g. _site.yml, _quarto.yml, _bookdown.yml).
Additional files
A content bundle can also contain a number of additional files, such as additional pages (e.g. Quarto, HTML), design resources (e.g. images or CSS), datasets (e.g. CSV files) or additional source files (Python or R) used by the content. These files can be alongside the primary file in the root of the bundle directory or in subdirectories of the root directory.
Warning
Auxiliary files cannot be outside of the content bundle, and thus cannot be above the primary file in the directory hierarchy (which must be at the top level of the directory that is bundled).
Working locally, you might place shared resource files in a common directory outside of a project, and reference them with relative paths (beginning with ..). This pattern does not work when publishing to Connect. This is because the primary target for a piece of content must be at the root level of the directory that is uploaded, so files outside that directory aren’t uploaded.
Consider the following directory layout. The image project_logo.png is located outside of the directories containing the Quarto documents.
When doc1.qmd is published to Connect, the report1 directory will be bundled and uploaded. The image fig_1.png will be included in the bundle. However, the project logo, which might be referenced as ../shared/project_logo.png, cannot be included in the bundle, and any references to it will break.
# Local file structure/report1/index.qmd/report1/fig_1.png/report2/index.qmd/shared/project_logo.png
When publishing report1, the files in the report1 directory are in the resulting bundle.
# report1 content bundleindex.qmdfig_1.png
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 do not work with published content. Review the warnings and recommendations below before publishing.
Method
Works
Notes
Relative paths to shared files on the deploying computer
No
Prohibited by Connect’s security and content execution models. See the Additional files section above.
This works for some deployment methods, but not for Git-backed content. Best for static assets that do not need to change between deployments. See the Symlinks to shared files section below.
To share code between projects, we strongly recommend housing it in a Python or R 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 Python Package Management and R Package Management.
Symlinks to shared files
Placing a symlink to a shared resource directory inside a content bundle and using the symlinked path to refer to shared resources works locally. Some publishing methods will resolve the symlink when creating the content bundle, uploading a copy of the files.
Warning
This does not work for all publication methods.
RStudio, rsconnect R package, and rsconnect-pythonwill resolve symlinks.
Custom bundle creation methods may or may not support this, depending on implementation.
This method is most appropriate for smaller static resources like images, that do not need to change between content deployments. This method isn’t appropriate for datasets or other resources that update dynamically, as the Connect server receives a static copy of the file at the destination.
# Local file structure using a symlink for shared resources/report1/index.qmd/report1/fig_1.png/report1/shared-> /shared/report2/index.qmd/report2/shared-> /shared/shared/project_logo.png
When publishing doc1.Rmd with a compatible method, and including shared/project_logo.png, the symlink /report1/shared -> /shared is resolved, and the resulting bundle on Connect contains a copy of the resource.
# report1 content bundle from symlinked directorydoc1.Rmdfig_1.pngshared/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 Connect server.
Persistent storage on Posit Connect
Content on Connect can access shared resources stored on the Connect server. This option is well-suited for many scenarios, such as datasets that will update.