feat: add docs website

This commit is contained in:
Patrick Schratz 2025-01-02 23:40:10 +01:00
commit 576125d377
Signed by: pat-s
GPG key ID: 3C6318841EF78925
25 changed files with 683 additions and 3 deletions

96
.gitignore vendored
View file

@ -1,9 +1,101 @@
.Rproj.user
# Created by https://www.toptal.com/developers/gitignore/api/terraform,R
# Edit at https://www.toptal.com/developers/gitignore?templates=terraform,R
### R ###
# History files
.Rhistory
.Rapp.history
# Session Data files
.RData
.RDataTmp
# User-specific files
.Ruserdata
# Example code in package build process
*-Ex.R
# Output files from R CMD build
/*.tar.gz
# Output files from R CMD check
/*.Rcheck/
# RStudio files
.Rproj.user/
# produced vignettes
vignettes/*.html
vignettes/*.pdf
# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth
# knitr and R markdown default cache directories
*_cache/
/cache/
# Temporary files created by R markdown
*.utf8.md
*.knit.md
# R Environment Variables
.Renviron
# pkgdown site
docs/
# translation temp files
po/*~
# RStudio Connect folder
rsconnect/
### R.Bookdown Stack ###
# R package: bookdown caching files
/*_files/
### Terraform ###
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# End of https://www.toptal.com/developers/gitignore/api/terraform,R
.Renviron
.envrc
exec.sh
exec.R
docs/
docs/_site

42
.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,42 @@
# This file is maintained automatically by "tofu init".
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/hashicorp/http" {
version = "3.4.5"
hashes = [
"h1:P3NFKZbtHuQ6mmoDVpg4WYlDJ+yK4cchzkjTPzBWG3Y=",
"zh:055a4431d33bb89b9848193152433eaead7cc2e6746d3436a5922419de2112bf",
"zh:0bfabafea9f5e36802fcfc5a800831ec1767d896af889abc610014d02b09bdc2",
"zh:300b4983fe1b43bd0a7dac1f94b30b3814f11c824224dd83fb45a521c02cea60",
"zh:68f6958314ca5dc0868be70e37ec123b99b8828aa49f27fd2fdd13df05d31ab1",
"zh:c29f098a597250adc2a7d9f99acbce3c9e07d37f1c5cfded5df4309738cf613c",
"zh:c33607397f9c9302c0cd797c8b7484c9c6cfa09c3489d4b55af17df20b204368",
"zh:d519ca364a224110428b390ee06e963a3ec4dfdd1ac816c9f32e647567957cf5",
"zh:e4a9c7c0ac31a0192362ef43449390cdf00d2cf6f13061ef730b177eaf00ac45",
"zh:f25223c062f274d8f89bb96017e73586030a205bc91cdad266a9954d0def2a23",
"zh:fd4dc824ebae2f3a66318df364bec83b88e9a52e7f66b00dafa29a796d9a94ab",
]
}
provider "registry.terraform.io/bunnyway/bunnynet" {
version = "0.5.0"
constraints = "~> 0.5"
hashes = [
"h1:eiQOt1rXiFmd9dAfvVe1kPcoPCwcOnXTqBdFT5VGASY=",
"zh:2b7cc4065a40fa01a49067c616d69de60f27a8388575fece16657d07884fc061",
"zh:334d6e20ea046787e05f88df1fb24caddb96e7142a4bb6883b00a7528d2dc4e0",
"zh:3bd890b915486e4a8bae060fcf4cb6f9d09c3e22f64b871572e1f0c05a515f11",
"zh:5c0edb810fd9dbc7a59e99f2b29be3822a0f38001236018d38803149543776a2",
"zh:5d72b0ff62a959e7b21bdf51edcc5e8acc49e0991b54fe688a3de04be3b2b095",
"zh:70e34ff2d3bd108570849fb11cc333c3254d5548c8a2c5a24000f99da01b8551",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
"zh:8ccc55724e70201d1db82d41632a5036688712cd215dab0f78f6890dd44ca1de",
"zh:99204d2da7788d9a24205142162fe29214146ec7dbf4f369f7c2ca57682ecc8c",
"zh:a1277fd220699cd0c9b5cdfb9afbb29f17846ec9476e4f93533879868db0d5ef",
"zh:abfddebfad3cbdfbfaa8269124bc9abab6e0cbad68356ede0095bb5381da40ab",
"zh:c74fd62921e2755e1a87dbf2acb4527966a611967a72076f4c315fb86f4deb38",
"zh:ca277ac7e5fa76ee59da8d262a120f62e43e0e8e14de006d08638a2d2a312d51",
"zh:cc8da1bf7539929a48ae2ea08b1dd83751faf31cc6c1607a0e10bbcaa63490e0",
"zh:fb0003a6af70e1b2a7ca3f19e8bfd2bcc5238ab5a0759b5e752b0fefb0ec8c50",
]
}

59
.woodpecker/docs.yaml Normal file
View file

@ -0,0 +1,59 @@
when:
- event: manual
evaluate: 'task == "docs"'
- event: cron
cron: 'build == "alpine-320-arm64"'
- event: manual
evaluate: 'build == "all-arm64"'
steps:
quarto-build:
image: ghcr.io/quarto-dev/quarto:1.6.39
directory: docs
commands:
- quarto render
backend_options:
kubernetes:
resources:
requests:
memory: 1Gi
cpu: 1000m
limits:
memory: 2Gi
cpu: 1000m
nodeSelector:
kubernetes.io/arch: amd64
tolerations:
- key: 'CI'
operator: 'Equal'
value: 'true'
effect: 'NoSchedule'
s3-sync:
image: plugins/s3:1.3.1
directory: docs
settings:
bucket: devxy-r-package-binaries-docs
region: fsn1
endpoint: https://fsn1.your-objectstorage.com
access_key:
from_secret: HETZNER_S3_ACCESS_KEY_K3S
secret_key:
from_secret: HETZNER_S3_SECRET_KEY_K3S
source: _site/**/*
strip_prefix: _site/
target: /
backend_options:
kubernetes:
resources:
requests:
memory: 300Mi
cpu: 200m
limits:
memory: 1Gi
cpu: 1000m
tolerations:
- key: 'CI'
operator: 'Equal'
value: 'true'
effect: 'NoSchedule'

View file

@ -4,3 +4,9 @@ image OS ARCH:
else \
docker buildx build --progress plain --build-arg GITHUB_PAT="$GITHUB_PAT" --build-arg ARCH={{ARCH}} -f docker/Containerfile-{{OS}} --platform linux/{{ARCH}} -t devxygmbh/{{ARCH}}-binaries-r-{{OS}}:latest --push .; \
fi
preview-docs:
cd docs && quarto preview
publish-docs:
cd docs && quarto render && rclone sync ./_site hetzner-s3://devxy-r-package-binaries-docs

16
backend.tf Normal file
View file

@ -0,0 +1,16 @@
terraform {
backend "s3" {
bucket = "devxy-tf-state-build-binaries"
key = "terraform.tfstate"
region = "fsn1"
access_key = var.HETZNER_S3_ACCESS_KEY_K3S
secret_key = var.HETZNER_S3_SECRET_KEY_K3S
endpoint = "https://fsn1.your-objectstorage.com"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
skip_s3_checksum = true
encrypt = true
sse_customer_key = "q6DUYGPpNSFFynGK1k6q6ZMeHRVLYTuPN1H3blilfB4="
}
}

48
cdn.tf Normal file
View file

@ -0,0 +1,48 @@
resource "bunnynet_pullzone" "r-package-binaries-docs" {
name = "r-package-binaries-docs"
origin {
type = "OriginUrl"
url = "https://devxy-r-package-binaries-docs.fsn1.your-objectstorage.com"
}
routing {
tier = "Standard"
}
s3_auth_enabled = true
s3_auth_key = var.HETZNER_S3_ACCESS_KEY_K3S
s3_auth_secret = var.HETZNER_S3_SECRET_KEY_K3S
s3_auth_region = "fsn1"
cache_enabled = true
cache_errors = true
# 3 months (override origin cache policy which is 30d)
cache_expiration_time = 7776000
# not so great in case data from users is being sent (at some point)
request_coalescing_enabled = false
block_post_requests = true
originshield_enabled = true
originshield_concurrency_limit = true
originshield_zone = "FR"
safehop_enabled = true
# otherwise this will expose the S3 origin URL as a secondary canonical URL
add_canonical_header = false
block_root_path = false
# FIXME: https://github.com/BunnyWay/terraform-provider-bunnynet/issues/19
log_forward_server = "127.0.0.1"
}
resource "bunnynet_pullzone_hostname" "r-package-binaries-docs" {
pullzone = bunnynet_pullzone.r-package-binaries-docs.id
name = "docs.r-package-binaries.devxy.io"
force_ssl = true
tls_enabled = true
}

1
docs/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/.quarto/

49
docs/_brand.yaml Normal file
View file

@ -0,0 +1,49 @@
color:
palette:
dark: "#1d262f"
orange: "#FF9B00"
links: "#15428c"
# background: blue
# foreground: dark-grey
primary: '#1d262f' # hyperlinks, active states, primary action buttons, etc.
tertiary: "#FF9B00" # hover states, accents, and wells.
logo:
medium:
light: logo.png
dark: logo.png
defaults:
bootstrap:
defaults:
navbar-fg: "#1d262f"
navbar-bg: "#ffffff"
typography:
fonts:
- family: Jura
source: google
- family: Inter Variable
source: google
- family: Montserrat Alternates
source: google
base:
family: Inter Variable
headings: Montserrat
link:
decoration: underline
color: links
monospace:
color: primary
background-color: "#f0f1f3"
size: 0.8rem
# decoration:
meta:
link:
home: https://www.devxy.io
gitlab: https://gitlab.com/devxy
bluesky: https://bsky.app/profile/devxy.bsky.social
linkedin: https://www.linkedin.com/company/105100347
description: Where Data Science and DevOps meet 🤝️
founded: 2024

68
docs/_quarto.yml Normal file
View file

@ -0,0 +1,68 @@
project:
type: website
website:
title: "CRAN R Package Binaries"
reader-mode: false
favicon: favicon.ico
back-to-top-navigation: true
navbar:
right:
- icon: gitlab
href: https://gitlab.com/devxy
- icon: browser-safari
href: https://www.devxy.io
- icon: bluesky
href: https://www.devxy.io
sidebar:
logo: ""
style: "docked"
collapse-level: 4
search: true
border: true
pinned: true
contents:
- text: 'Introduction'
file: index.qmd
- text: "---"
- text: 'Configuration'
file: configuration/index.qmd
- section: "**Use Cases**"
contents:
- text: "CI/CD"
file: cicd/index.qmd
- text: "R Development Environments"
file: r-dev-environments/index.qmd
- text: "Containers"
file: containers/index.qmd
# - section: "**Technical Background**"
# contents:
# - text: "Infrastructure"
# file: 031-infrastructure.qmd
# - text: "Continuous Updates"
# file: 032-continuous-updates.qmd
# - section: "**Miscellaneous**"
# contents:
# - text: "Private Mirror"
# file: 040-private-mirror.qmd
# - text: "Fair Usage"
# file: 041-fair-usage.qmd
- text: "---"
- text: 'Contributing & Help'
file: "contributing/index.qmd"
search:
location: sidebar
type: "textbox"
limit: 5
copy-button: true
collapse-after: 2
format:
html:
theme: cosmo
css: styles.css
fontsize: 1rem
toc: true
grid:
sidebar-width: 300px

82
docs/cicd/index.qmd Normal file
View file

@ -0,0 +1,82 @@
---
title: CI/CD
---
Continuous Integration / continous delivery (CI/CD) is a basic tool in todays Data Science toolstack to automate processes and execute repetite tasks on schedule.
Running tasks in CI/CD should be fast and reliable, no matter the language, architecture or computing environment at hand.
As CI/CD requires installing many packages over and over again, having binaries and optimized distributions helps to reduce runtime.
This page presents snippets for well and lesser known CI/CD engines to help getting started with the R package binaries of this project.
::: {.callout-note}
The presented snippets rely on external projects and libraries which get updated regurarly.
There is no guarantee to work out-of-the box at all times.
If you found an error, please open a pull request in the linked repo.
:::
## GitHub Actions
### VM
GitHub Actions can be run directly on a VM or in a containered context.
The available VM images can be found [here](https://github.com/actions/runner-images#available-images).
The only Linux distribution available is Ubuntu.
For VM workflows, [r-lib/actions](https://github.com/r-lib/actions/blob/v2/examples) provides many examples for different use cases.
To use package binaries from this project, use the following config for `r-lib/actions/setup-r@v2`:
```yaml
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
Ncpus: 2
cran: 'https://cran.devxy.io/amd64/noble/latest'
```
(`Ncpus: 2` has been set to allow for parallel installations.)
### Container
An alternative is to run Actions in a containerized context.
This spins up a container of the selected image in the VM and allows running on other distributions than Ubuntu, e.g. on Alpine.
To avoid having to install R first and configure a custom repository every time, [specialized images](https://hub.docker.com/r/devxygmbh/r-alpine) are provided which already have everything in place:
```yaml
jobs:
container:
runs-on: ubuntu-latest
container: devxygmbh:r-alpine
steps:
- run: |
R -q -e 'install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/devel/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch))'
R -q -e 'getOption("repos")'
R -q -e 'options(Ncpus = 2); pak::local_install_dev_deps()'
```
::: {.callout-note}
When running in a containerized context, the predefined actions from `r-lib/actions` cannot be used.
Shell/R commands must be used directly.
:::
::: {.callout-note}
Running containerized in Alpine should be substantially faster than running in a VM context.
:::
::: {.callout-tip}
(91 packages)
- Containerized: **1m 21s**
- VM: 2m 11s
Both runs are based on the assumption that caching is not used. With caching enabled, the performance of both approaches should be roughly comparable.
Source: [pat-s/workflow-compare](https://github.com/pat-s/workflow-compare)
:::
## GitLab Runner
WIP

View file

@ -0,0 +1,66 @@
---
title: Configuration
---
In R on Linux, packages are downloaded from CRAN as source packages.
The default CRAN mirror is `https://cloud.r-project.org`.
The default repository URL needs to be **actively changed** to one providing binaries for the respective Linux distribution.
This can be done either for all users of the system, on a project level or for specific users only.
All options will be shown in the following.
## URL Scheme
The URL scheme for this project is the same for all operating systems and only differs in the OS and architecture identifiers.
::: {.callout-note icon=false}
## URL scheme
`https://cran.devxy.io/<architecture>/<os>/latest`
:::
For example, the URL for Alpine Linux 3.21 for `arm64` would be `https://cran.devxy.io/arm64/alpine321/latest`.
The architecture identifiers are:
- `arm64`
- `amd64`
The OS identifiers are:
- `jammy` (Ubuntu 22.04)
- `noble` (Ubuntu 24.04)
- `rhel8` (RedHat Enterprise Linux 8)
- `rhel9` (RedHat Enterprise Linux 9)
- `alpine320` (Alpine Linux 3.20)
- `alpine321` (Alpine Linux 3.21)
## Repository Configuration
### System-wide
To configure the default R repository for all users of a system, create/edit `$R_HOME/etc/Rprofile.site`.
The location of this file depends on how R has been installed.
To find its location, execute `R -q -e "paste0(Sys.getenv('R_HOME'),'/etc/Rprofile.site')"`.
**At the bottom** of the file, add the following:
```r
options(repos = structure(c(CRAN = "<URL>")))
```
The name "CRAN" is optional.
It is the canonical default and in some cases also used for special actions (e.g. in Posit Workbench and [{pak}](https://github.com/r-lib/pak)).
Unless you have a good reason, it is advisable to stick with that name.
### User-wide
To change the default repository option for a specific *user*, add the line from above to `~/.Rprofile`.
### Project-wide
To change the default repository option for a specific *project*, add the line from above to `.Rprofile` in the project root directory in which R is started.
## Verification
When starting R, execute `getOption("repos")` to verify the repository is correctly configured.

24
docs/containers/index.qmd Normal file
View file

@ -0,0 +1,24 @@
---
title: Containers
---
The [rocker](https://hub.docker.com/u/rocker) project provides container images for R since several years.
Since recently, the images are multi-arch, i.e. `arm64` is supported alongside `amd64`.
Yet, other distributions than Ubuntu are missing and don't use the devXY binaries out of the box.
To simplify running containers that make use of the devXY R binaries implicitly, the following images are provided:
- [devxygmbh/r-alpine](https://hub.docker.com/r/devxygmbh/r-alpine)
- [devxygmbh/r-ubuntu](https://hub.docker.com/r/devxygmbh/r-ubuntu)
These have the devXY repositories configured by default and can be used efficiently without further configuration changes.
In contrast to the minimal `rocker/r-ver` images, the `r-ubuntu` images contain a few additional system libraries which are essential for troublefree R usage.
The following screencast shows how quickly the `r-alpine` image can be used to install the full {tidyverse} package universe in just under 30s:
<div style="padding:59.12% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1035389676?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Alpine package binaries: Install tidyverse"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
::: {.callout-note}
The performance of this screencast (and your local experience) depends on a few factors: local download speed, cached binaries in the CDN, proximity to a local edge node of the CDN and your CPU performance and finally the `Ncpus` option in R, defining how many installations are performed in parallel (by default 1).
:::

View file

@ -0,0 +1 @@
WIP

View file

@ -0,0 +1,15 @@
---
title: Contributing & Help
---
Contributions are welcome.
The project is open-source and GPL licensed.
The most helpful tasks are to investigate in detail why specific packages failed to build a binary.
It usually comes down to a missing system dependency (which is either not declared in the package's DESCRIPTION file or exotic and must be installed from source) or a C code compile issue.
Please open an issue in the [`r-package-binaries/support`](https://gitlab.com/devxy/r-package-binaries/support) repo.
::: {.callout-note}
The actual repo executing the builds ([devxy/build-binaries](https://git.devxy.io/devxy/build-binaries)) is hosted in a private git instance to be able to use specific private CI runners and is not easily usable for creating public issues, hence the dedicated repo on GitLab.
:::

View file

BIN
docs/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

24
docs/index.qmd Normal file
View file

@ -0,0 +1,24 @@
---
title: "CRAN R Package Binaries"
---
This project provides R package binaries for various Linux distributions and architectures.
While it provides binaries for [CRAN packages](https://cran.r-project.org/), it is not affiliated with CRAN in any way.
Binaries are distributed to the community for free with a monthly download cap of **50 Terrabyte**.
::: {.callout-note}
If you represent a for-profit company and plan to make extensive use of these binaries, please get in touch. We offer the option to obtain a private mirror with unlimited access.
:::
While we strive to build binaries for all CRAN packages, there are various reasons why building binaries for a package might fail.
(The most common reason is a missing (exotic) external system dependency which the project links against.)
The [R package binary dashboard](https://app.devxy.io/app/r-package-binaries-dashboard) provides global coverage information for each for each operating system and which packages are currently missing.
## Motivation
The project was established to offer extensive R CRAN package support for common Linux distributions.
Since CRAN does not build binaries for Linux, Posit began providing binaries in 2020.
However, their efforts were limited to the amd64 architecture and excluded Alpine Linux, which is among the most popular distributions for container-based workflows.
This project aims to make R a first-class citizien for CI/CD and containers using a community-driven open-source approach.

View file

@ -0,0 +1 @@
WIP

BIN
docs/logo-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
docs/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show more