Compare commits

..

13 Commits

Author SHA1 Message Date
Roxedus
564ad4615e
Merge pull request #50 from linuxserver/main-deprecate 2025-06-27 15:16:27 +02:00
Roxedus
43063537d0
Deprecate image 2025-06-27 02:16:55 +02:00
Roxedus
1de3347fac
Merge pull request #48 from linuxserver/main-media-blurb 2025-04-16 01:21:03 +02:00
Roxedus
a04c088a98
Use media blurb 2025-03-16 16:10:28 +01:00
Roxedus
2c1e8bce0f
Merge pull request #45 from linuxserver/update-main 2024-12-26 00:52:57 +01:00
thespad
5b01bec324
Restore tag 2024-12-25 23:48:14 +00:00
thespad
a91e4af84c
Update readme, templates, and workflows 2024-12-23 18:03:13 +00:00
Adam
7f7eb64c28
Merge pull request #33 from linuxserver/main-3.19
Rebase to 3.19 (main)
2024-03-21 14:07:29 +00:00
TheSpad
da6367aaeb
Rebase to 3.19 2024-03-20 18:17:38 +00:00
Adam
27feb7d884
Merge pull request #28 from linuxserver/main-3.18 2023-06-14 09:01:49 +01:00
TheSpad
25f77419b6
Update changelog for 3.18 2023-06-06 15:31:18 +01:00
aptalca
d671f53e94
Merge pull request #17 from linuxserver/readme-develop-branch
Add changelog + version tags for develop branch
2022-02-21 09:46:58 -05:00
TheSpad
9059510ffc Add changelog + version tags for develop branch 2022-02-21 14:19:14 +00:00
35 changed files with 159 additions and 2077 deletions

View File

@ -15,6 +15,6 @@ trim_trailing_whitespace = false
indent_style = space
indent_size = 2
[{**.sh,root/etc/s6-overlay/s6-rc.d/**,root/etc/cont-init.d/**,root/etc/services.d/**}]
[{**.sh,root/etc/cont-init.d/**,root/etc/services.d/**}]
indent_style = space
indent_size = 4

View File

@ -6,7 +6,7 @@
* Read, and fill the Pull Request template
* If this is a fix for a typo (in code, documentation, or the README) please file an issue and let us sort it out. We do not need a PR
* If the PR is addressing an existing issue include, closes #\<issue number>, in the body of the PR commit message
* If you want to discuss changes, you can also bring it up in [#dev-talk](https://discordapp.com/channels/354974912613449730/757585807061155840) in our [Discord server](https://discord.gg/YWrKVTn)
* If you want to discuss changes, you can also bring it up in [#dev-talk](https://discordapp.com/channels/354974912613449730/757585807061155840) in our [Discord server](https://linuxserver.io/discord)
## Common files
@ -105,10 +105,10 @@ docker build \
-t linuxserver/readarr:latest .
```
The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static`
The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static`
```bash
docker run --rm --privileged multiarch/qemu-user-static:register --reset
docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset
```
Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`.

View File

@ -1,7 +1,7 @@
blank_issues_enabled: false
contact_links:
- name: Discord chat support
url: https://discord.gg/YWrKVTn
url: https://linuxserver.io/discord
about: Realtime support / chat with the community and the team.
- name: Discourse discussion forum

74
.github/ISSUE_TEMPLATE/issue.bug.yml vendored Executable file → Normal file
View File

@ -4,73 +4,11 @@ description: Create a report to help us improve
title: "[BUG] <title>"
labels: [Bug]
body:
- type: checkboxes
- type: markdown
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Current Behavior
description: Tell us what happens instead of the expected behavior.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: Tell us what should happen.
validations:
required: false
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. In this environment...
2. With this config...
3. Run '...'
4. See error...
validations:
required: true
- type: textarea
attributes:
label: Environment
description: |
examples:
- **OS**: Ubuntu 20.04
- **How docker service was installed**: distro's packagemanager
value: |
- OS:
- How docker service was installed:
render: markdown
validations:
required: false
- type: dropdown
attributes:
label: CPU architecture
options:
- x86-64
- arm64
validations:
required: true
- type: textarea
attributes:
label: Docker creation
description: |
Command used to create docker container
Provide your docker create/run command or compose yaml snippet, or a screenshot of settings if using a gui to create the container
render: bash
validations:
required: true
- type: textarea
attributes:
description: |
Provide a full docker log, output of "docker logs linuxserver.io"
label: Container logs
placeholder: |
Output of `docker logs linuxserver.io`
render: bash
validations:
required: true
# DEPRECATION NOTICE
This image is deprecated. We will not offer support for this image and it will not be updated.
Due to lack of developers, and issues with maintaining status quo, upstream has decided to retire the project.

31
.github/ISSUE_TEMPLATE/issue.feature.yml vendored Executable file → Normal file
View File

@ -4,28 +4,11 @@ description: Suggest an idea for this project
title: "[FEAT] <title>"
labels: [enhancement]
body:
- type: checkboxes
- type: markdown
attributes:
label: Is this a new feature request?
description: Please search to see if a feature request already exists.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Wanted change
description: Tell us what you want to happen.
validations:
required: true
- type: textarea
attributes:
label: Reason for change
description: Justify your request, why do you want it, what is the benefit.
validations:
required: true
- type: textarea
attributes:
label: Proposed code change
description: Do you have a potential code change in mind?
validations:
required: false
value: |
# DEPRECATION NOTICE
This image is deprecated. We will not offer support for this image and it will not be updated.
Due to lack of developers, and issues with maintaining status quo, upstream has decided to retire the project.

View File

@ -1,3 +1,9 @@
# DEPRECATION NOTICE
This image is deprecated. We will not offer support for this image and it will not be updated.
Due to lack of developers, and issues with maintaining status quo, upstream has decided to retire the project.
<!--- Provide a general summary of your changes in the Title above -->
[linuxserverurl]: https://linuxserver.io

View File

@ -1,16 +0,0 @@
name: Issue & PR Tracker
on:
issues:
types: [opened,reopened,labeled,unlabeled,closed]
pull_request_target:
types: [opened,reopened,review_requested,review_request_removed,labeled,unlabeled,closed]
pull_request_review:
types: [submitted,edited,dismissed]
jobs:
manage-project:
permissions:
issues: write
uses: linuxserver/github-workflows/.github/workflows/issue-pr-tracker.yml@v1
secrets: inherit

View File

@ -1,13 +0,0 @@
name: Mark stale issues and pull requests
on:
schedule:
- cron: '44 1 * * *'
workflow_dispatch:
jobs:
stale:
permissions:
issues: write
pull-requests: write
uses: linuxserver/github-workflows/.github/workflows/issues-cron.yml@v1
secrets: inherit

View File

@ -1,104 +0,0 @@
name: External Trigger Main
on:
workflow_dispatch:
jobs:
external-trigger-develop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.1.0
- name: External Trigger
if: github.ref == 'refs/heads/develop'
run: |
if [ -n "${{ secrets.PAUSE_EXTERNAL_TRIGGER_READARR_DEVELOP }}" ]; then
echo "**** Github secret PAUSE_EXTERNAL_TRIGGER_READARR_DEVELOP is set; skipping trigger. ****"
echo "Github secret \`PAUSE_EXTERNAL_TRIGGER_READARR_DEVELOP\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "**** External trigger running off of develop branch. To disable this trigger, set a Github secret named \"PAUSE_EXTERNAL_TRIGGER_READARR_DEVELOP\". ****"
echo "External trigger running off of develop branch. To disable this trigger, set a Github secret named \`PAUSE_EXTERNAL_TRIGGER_READARR_DEVELOP\`" >> $GITHUB_STEP_SUMMARY
echo "**** Retrieving external version ****"
EXT_RELEASE=$(curl -sL https://readarr.servarr.com/v1/update/develop/changes?runtime=netcore%26os=linuxmusl | jq -r '.[0].version')
if [ -z "${EXT_RELEASE}" ] || [ "${EXT_RELEASE}" == "null" ]; then
echo "**** Can't retrieve external version, exiting ****"
FAILURE_REASON="Can't retrieve external version for readarr branch develop"
GHA_TRIGGER_URL="https://github.com/linuxserver/docker-readarr/actions/runs/${{ github.run_id }}"
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680,
"description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n**Trigger URL:** '"${GHA_TRIGGER_URL}"' \n"}],
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}
exit 1
fi
EXT_RELEASE=$(echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g')
echo "**** External version: ${EXT_RELEASE} ****"
echo "External version: ${EXT_RELEASE}" >> $GITHUB_STEP_SUMMARY
echo "**** Retrieving last pushed version ****"
image="linuxserver/readarr"
tag="develop"
token=$(curl -sX GET \
"https://ghcr.io/token?scope=repository%3Alinuxserver%2Freadarr%3Apull" \
| jq -r '.token')
multidigest=$(curl -s \
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/${image}/manifests/${tag}" \
| jq -r 'first(.manifests[].digest)')
digest=$(curl -s \
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/${image}/manifests/${multidigest}" \
| jq -r '.config.digest')
image_info=$(curl -sL \
--header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/${image}/blobs/${digest}")
if [[ $(echo $image_info | jq -r '.container_config') == "null" ]]; then
image_info=$(echo $image_info | jq -r '.config')
else
image_info=$(echo $image_info | jq -r '.container_config')
fi
IMAGE_RELEASE=$(echo ${image_info} | jq -r '.Labels.build_version' | awk '{print $3}')
IMAGE_VERSION=$(echo ${IMAGE_RELEASE} | awk -F'-ls' '{print $1}')
if [ -z "${IMAGE_VERSION}" ]; then
echo "**** Can't retrieve last pushed version, exiting ****"
FAILURE_REASON="Can't retrieve last pushed version for readarr tag develop"
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 16711680,
"description": "**Trigger Failed** \n**Reason:** '"${FAILURE_REASON}"' \n"}],
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}
exit 1
fi
echo "**** Last pushed version: ${IMAGE_VERSION} ****"
echo "Last pushed version: ${IMAGE_VERSION}" >> $GITHUB_STEP_SUMMARY
if [ "${EXT_RELEASE}" == "${IMAGE_VERSION}" ]; then
echo "**** Version ${EXT_RELEASE} already pushed, exiting ****"
echo "Version ${EXT_RELEASE} already pushed, exiting" >> $GITHUB_STEP_SUMMARY
exit 0
elif [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-readarr/job/develop/lastBuild/api/json | jq -r '.building') == "true" ]; then
echo "**** New version ${EXT_RELEASE} found; but there already seems to be an active build on Jenkins; exiting ****"
echo "New version ${EXT_RELEASE} found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY
exit 0
else
echo "**** New version ${EXT_RELEASE} found; old version was ${IMAGE_VERSION}. Triggering new build ****"
echo "New version ${EXT_RELEASE} found; old version was ${IMAGE_VERSION}. Triggering new build" >> $GITHUB_STEP_SUMMARY
response=$(curl -iX POST \
https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-readarr/job/develop/buildWithParameters?PACKAGE_CHECK=false \
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|")
echo "**** Jenkins job queue url: ${response%$'\r'} ****"
echo "**** Sleeping 10 seconds until job starts ****"
sleep 10
buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url')
buildurl="${buildurl%$'\r'}"
echo "**** Jenkins job build url: ${buildurl} ****"
echo "Jenkins job build url: ${buildurl}" >> $GITHUB_STEP_SUMMARY
echo "**** Attempting to change the Jenkins job description ****"
curl -iX POST \
"${buildurl}submitDescription" \
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \
--data-urlencode "description=GHA external trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
--data-urlencode "Submit=Submit"
echo "**** Notifying Discord ****"
TRIGGER_REASON="A version change was detected for readarr tag develop. Old version:${IMAGE_VERSION} New version:${EXT_RELEASE}"
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903,
"description": "**Build Triggered** \n**Reason:** '"${TRIGGER_REASON}"' \n**Build URL:** '"${buildurl}display/redirect"' \n"}],
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}
fi

View File

@ -1,45 +0,0 @@
name: External Trigger Scheduler
on:
schedule:
- cron: '40 * * * *'
workflow_dispatch:
jobs:
external-trigger-scheduler:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.1.0
with:
fetch-depth: '0'
- name: External Trigger Scheduler
run: |
echo "**** Branches found: ****"
git for-each-ref --format='%(refname:short)' refs/remotes
for br in $(git for-each-ref --format='%(refname:short)' refs/remotes)
do
br=$(echo "$br" | sed 's|origin/||g')
echo "**** Evaluating branch ${br} ****"
ls_jenkins_vars=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-readarr/${br}/jenkins-vars.yml)
ls_branch=$(echo "${ls_jenkins_vars}" | yq -r '.ls_branch')
ls_trigger=$(echo "${ls_jenkins_vars}" | yq -r '.external_type')
if [[ "${br}" == "${ls_branch}" ]] && [[ "${ls_trigger}" != "os" ]]; then
echo "**** Branch ${br} appears to be live and trigger is not os; checking workflow. ****"
if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-readarr/${br}/.github/workflows/external_trigger.yml > /dev/null 2>&1; then
echo "**** Workflow exists. Triggering external trigger workflow for branch ${br} ****."
echo "Triggering external trigger workflow for branch ${br}" >> $GITHUB_STEP_SUMMARY
curl -iX POST \
-H "Authorization: token ${{ secrets.CR_PAT }}" \
-H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"refs/heads/${br}\"}" \
https://api.github.com/repos/linuxserver/docker-readarr/actions/workflows/external_trigger.yml/dispatches
else
echo "**** Workflow doesn't exist; skipping trigger. ****"
echo "Skipping branch ${br} due to no external trigger workflow present." >> $GITHUB_STEP_SUMMARY
fi
else
echo "**** ${br} is either a dev branch, or has no external version; skipping trigger. ****"
echo "Skipping branch ${br} due to being detected as dev branch or having no external version." >> $GITHUB_STEP_SUMMARY
fi
done

View File

@ -8,6 +8,6 @@ jobs:
steps:
- uses: actions/first-interaction@v1
with:
issue-message: 'Thanks for opening your first issue here! Be sure to follow the relevant issue templates, or risk having this issue marked as invalid.'
pr-message: 'Thanks for opening this pull request! Be sure to follow the [pull request template](https://github.com/linuxserver/docker-readarr/blob/develop/.github/PULL_REQUEST_TEMPLATE.md)!'
issue-message: 'This image is deprecated. We will not offer support for this image and it will not be updated. The [README](https://github.com/linuxserver/docker-readarr/blob/develop/README.md) may have additional information. Thanks for opening your first issue here! Be sure to follow the relevant issue templates, or risk having this issue marked as invalid.'
pr-message: 'This image is deprecated. We will not offer support for this image and it will not be updated. The [README](https://github.com/linuxserver/docker-readarr/blob/develop/README.md) may have additional information. Thanks for opening this pull request! Be sure to follow the [pull request template](https://github.com/linuxserver/docker-readarr/blob/develop/.github/PULL_REQUEST_TEMPLATE.md)!'
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,42 +0,0 @@
name: Package Trigger Main
on:
workflow_dispatch:
jobs:
package-trigger-develop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.1.0
- name: Package Trigger
if: github.ref == 'refs/heads/develop'
run: |
if [ -n "${{ secrets.PAUSE_PACKAGE_TRIGGER_READARR_DEVELOP }}" ]; then
echo "**** Github secret PAUSE_PACKAGE_TRIGGER_READARR_DEVELOP is set; skipping trigger. ****"
echo "Github secret \`PAUSE_PACKAGE_TRIGGER_READARR_DEVELOP\` is set; skipping trigger." >> $GITHUB_STEP_SUMMARY
exit 0
fi
if [ $(curl -s https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-readarr/job/develop/lastBuild/api/json | jq -r '.building') == "true" ]; then
echo "**** There already seems to be an active build on Jenkins; skipping package trigger ****"
echo "There already seems to be an active build on Jenkins; skipping package trigger" >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "**** Package trigger running off of develop branch. To disable, set a Github secret named \"PAUSE_PACKAGE_TRIGGER_READARR_DEVELOP\". ****"
echo "Package trigger running off of develop branch. To disable, set a Github secret named \`PAUSE_PACKAGE_TRIGGER_READARR_DEVELOP\`" >> $GITHUB_STEP_SUMMARY
response=$(curl -iX POST \
https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-readarr/job/develop/buildWithParameters?PACKAGE_CHECK=true \
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} | grep -i location | sed "s|^[L|l]ocation: \(.*\)|\1|")
echo "**** Jenkins job queue url: ${response%$'\r'} ****"
echo "**** Sleeping 10 seconds until job starts ****"
sleep 10
buildurl=$(curl -s "${response%$'\r'}api/json" | jq -r '.executable.url')
buildurl="${buildurl%$'\r'}"
echo "**** Jenkins job build url: ${buildurl} ****"
echo "Jenkins job build url: ${buildurl}" >> $GITHUB_STEP_SUMMARY
echo "**** Attempting to change the Jenkins job description ****"
curl -iX POST \
"${buildurl}submitDescription" \
--user ${{ secrets.JENKINS_USER }}:${{ secrets.JENKINS_TOKEN }} \
--data-urlencode "description=GHA package trigger https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
--data-urlencode "Submit=Submit"

View File

@ -1,50 +0,0 @@
name: Package Trigger Scheduler
on:
schedule:
- cron: '47 15 * * 6'
workflow_dispatch:
jobs:
package-trigger-scheduler:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.1.0
with:
fetch-depth: '0'
- name: Package Trigger Scheduler
run: |
echo "**** Branches found: ****"
git for-each-ref --format='%(refname:short)' refs/remotes
for br in $(git for-each-ref --format='%(refname:short)' refs/remotes)
do
br=$(echo "$br" | sed 's|origin/||g')
echo "**** Evaluating branch ${br} ****"
ls_branch=$(curl -sX GET https://raw.githubusercontent.com/linuxserver/docker-readarr/${br}/jenkins-vars.yml | yq -r '.ls_branch')
if [ "${br}" == "${ls_branch}" ]; then
echo "**** Branch ${br} appears to be live; checking workflow. ****"
if curl -sfX GET https://raw.githubusercontent.com/linuxserver/docker-readarr/${br}/.github/workflows/package_trigger.yml > /dev/null 2>&1; then
echo "**** Workflow exists. Triggering package trigger workflow for branch ${br}. ****"
echo "Triggering package trigger workflow for branch ${br}" >> $GITHUB_STEP_SUMMARY
triggered_branches="${triggered_branches}${br} "
curl -iX POST \
-H "Authorization: token ${{ secrets.CR_PAT }}" \
-H "Accept: application/vnd.github.v3+json" \
-d "{\"ref\":\"refs/heads/${br}\"}" \
https://api.github.com/repos/linuxserver/docker-readarr/actions/workflows/package_trigger.yml/dispatches
sleep 30
else
echo "**** Workflow doesn't exist; skipping trigger. ****"
echo "Skipping branch ${br} due to no package trigger workflow present." >> $GITHUB_STEP_SUMMARY
fi
else
echo "**** ${br} appears to be a dev branch; skipping trigger. ****"
echo "Skipping branch ${br} due to being detected as dev branch." >> $GITHUB_STEP_SUMMARY
fi
done
echo "**** Package check build(s) triggered for branch(es): ${triggered_branches} ****"
echo "**** Notifying Discord ****"
curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://cdn.discordapp.com/avatars/354986384542662657/df91181b3f1cf0ef1592fbe18e0962d7.png","embeds": [{"color": 9802903,
"description": "**Package Check Build(s) Triggered for readarr** \n**Branch(es):** '"${triggered_branches}"' \n**Build URL:** '"https://ci.linuxserver.io/blue/organizations/jenkins/Docker-Pipeline-Builders%2Fdocker-readarr/activity/"' \n"}],
"username": "Github Actions"}' ${{ secrets.DISCORD_WEBHOOK }}

View File

@ -1,10 +0,0 @@
name: Permission check
on:
pull_request_target:
paths:
- '**/run'
- '**/finish'
- '**/check'
jobs:
permission_check:
uses: linuxserver/github-workflows/.github/workflows/init-svc-executable-permissions.yml@v1

1
.gitignore vendored
View File

@ -1 +0,0 @@
.jenkins-external

View File

@ -1,46 +0,0 @@
# syntax=docker/dockerfile:1
FROM ghcr.io/linuxserver/baseimage-alpine:3.18
# set version label
ARG BUILD_DATE
ARG VERSION
ARG READARR_RELEASE
LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}"
LABEL maintainer="Roxedus,thespad"
# environment settings
ARG READARR_BRANCH="develop"
ENV XDG_CONFIG_HOME="/config/xdg"
RUN \
echo "**** install packages ****" && \
apk add -U --upgrade --no-cache \
icu-libs \
sqlite-libs \
xmlstarlet && \
echo "**** install readarr ****" && \
mkdir -p /app/readarr/bin && \
if [ -z ${READARR_RELEASE+x} ]; then \
READARR_RELEASE=$(curl -sL "https://readarr.servarr.com/v1/update/${READARR_BRANCH}/changes?runtime=netcore&os=linuxmusl" \
| jq -r '.[0].version'); \
fi && \
curl -o \
/tmp/readarr.tar.gz -L \
"https://readarr.servarr.com/v1/update/${READARR_BRANCH}/updatefile?version=${READARR_RELEASE}&os=linuxmusl&runtime=netcore&arch=x64" && \
tar xzf \
/tmp/readarr.tar.gz -C \
/app/readarr/bin --strip-components=1 && \
echo -e "UpdateMethod=docker\nBranch=${READARR_BRANCH}\nPackageVersion=${VERSION}\nPackageAuthor=[linuxserver.io](https://www.linuxserver.io/)" > /app/readarr/package_info && \
echo "**** cleanup ****" && \
rm -rf \
/app/readarr/bin/Readarr.Update \
/tmp/*
# copy local files
COPY root/ /
# ports and volumes
EXPOSE 8787
VOLUME /config

View File

@ -1,46 +0,0 @@
# syntax=docker/dockerfile:1
FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.18
# set version label
ARG BUILD_DATE
ARG VERSION
ARG READARR_RELEASE
LABEL build_version="Linuxserver.io version:- ${VERSION} Build-date:- ${BUILD_DATE}"
LABEL maintainer="Roxedus,thespad"
# environment settings
ARG READARR_BRANCH="develop"
ENV XDG_CONFIG_HOME="/config/xdg"
RUN \
echo "**** install packages ****" && \
apk add -U --upgrade --no-cache \
icu-libs \
sqlite-libs \
xmlstarlet && \
echo "**** install readarr ****" && \
mkdir -p /app/readarr/bin && \
if [ -z ${READARR_RELEASE+x} ]; then \
READARR_RELEASE=$(curl -sL "https://readarr.servarr.com/v1/update/${READARR_BRANCH}/changes?runtime=netcore&os=linuxmusl" \
| jq -r '.[0].version'); \
fi && \
curl -o \
/tmp/readarr.tar.gz -L \
"https://readarr.servarr.com/v1/update/${READARR_BRANCH}/updatefile?version=${READARR_RELEASE}&os=linuxmusl&runtime=netcore&arch=arm64" && \
tar xzf \
/tmp/readarr.tar.gz -C \
/app/readarr/bin --strip-components=1 && \
echo -e "UpdateMethod=docker\nBranch=${READARR_BRANCH}\nPackageVersion=${VERSION}\nPackageAuthor=[linuxserver.io](https://www.linuxserver.io/)" > /app/readarr/package_info && \
echo "**** cleanup ****" && \
rm -rf \
/app/readarr/bin/Readarr.Update \
/tmp/*
# copy local files
COPY root/ /
# ports and volumes
EXPOSE 8787
VOLUME /config

997
Jenkinsfile vendored
View File

@ -1,997 +0,0 @@
pipeline {
agent {
label 'X86-64-MULTI'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10', daysToKeepStr: '60'))
parallelsAlwaysFailFast()
}
// Input to determine if this is a package check
parameters {
string(defaultValue: 'false', description: 'package check run', name: 'PACKAGE_CHECK')
}
// Configuration for the variables used for this specific repo
environment {
BUILDS_DISCORD=credentials('build_webhook_url')
GITHUB_TOKEN=credentials('498b4638-2d02-4ce5-832d-8a57d01d97ab')
GITLAB_TOKEN=credentials('b6f0f1dd-6952-4cf6-95d1-9c06380283f0')
GITLAB_NAMESPACE=credentials('gitlab-namespace-id')
SCARF_TOKEN=credentials('scarf_api_key')
BUILD_VERSION_ARG = 'READARR_RELEASE'
LS_USER = 'linuxserver'
LS_REPO = 'docker-readarr'
CONTAINER_NAME = 'readarr'
DOCKERHUB_IMAGE = 'linuxserver/readarr'
DEV_DOCKERHUB_IMAGE = 'lsiodev/readarr'
PR_DOCKERHUB_IMAGE = 'lspipepr/readarr'
DIST_IMAGE = 'alpine'
MULTIARCH='true'
CI='true'
CI_WEB='true'
CI_PORT='8787'
CI_SSL='false'
CI_DELAY='120'
CI_DOCKERENV='TZ=US/Pacific'
CI_AUTH='user:password'
CI_WEBPATH='/system/status'
}
stages {
// Setup all the basic environment variables needed for the build
stage("Set ENV Variables base"){
steps{
sh '''#! /bin/bash
containers=$(docker ps -aq)
if [[ -n "${containers}" ]]; then
docker stop ${containers}
fi
docker system prune -af --volumes || : '''
script{
env.EXIT_STATUS = ''
env.LS_RELEASE = sh(
script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:develop 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''',
returnStdout: true).trim()
env.LS_RELEASE_NOTES = sh(
script: '''cat readme-vars.yml | awk -F \\" '/date: "[0-9][0-9].[0-9][0-9].[0-9][0-9]:/ {print $4;exit;}' | sed -E ':a;N;$!ba;s/\\r{0,1}\\n/\\\\n/g' ''',
returnStdout: true).trim()
env.GITHUB_DATE = sh(
script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''',
returnStdout: true).trim()
env.COMMIT_SHA = sh(
script: '''git rev-parse HEAD''',
returnStdout: true).trim()
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/commit/' + env.GIT_COMMIT
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DOCKERHUB_IMAGE + '/tags/'
env.PULL_REQUEST = env.CHANGE_ID
env.TEMPLATED_FILES = 'Jenkinsfile README.md LICENSE .editorconfig ./.github/CONTRIBUTING.md ./.github/FUNDING.yml ./.github/ISSUE_TEMPLATE/config.yml ./.github/ISSUE_TEMPLATE/issue.bug.yml ./.github/ISSUE_TEMPLATE/issue.feature.yml ./.github/PULL_REQUEST_TEMPLATE.md ./.github/workflows/external_trigger_scheduler.yml ./.github/workflows/greetings.yml ./.github/workflows/package_trigger_scheduler.yml ./.github/workflows/call_issue_pr_tracker.yml ./.github/workflows/call_issues_cron.yml ./.github/workflows/permissions.yml ./.github/workflows/external_trigger.yml ./.github/workflows/package_trigger.yml ./root/donate.txt'
}
script{
env.LS_RELEASE_NUMBER = sh(
script: '''echo ${LS_RELEASE} |sed 's/^.*-ls//g' ''',
returnStdout: true).trim()
}
script{
env.LS_TAG_NUMBER = sh(
script: '''#! /bin/bash
tagsha=$(git rev-list -n 1 develop-${LS_RELEASE} 2>/dev/null)
if [ "${tagsha}" == "${COMMIT_SHA}" ]; then
echo ${LS_RELEASE_NUMBER}
elif [ -z "${GIT_COMMIT}" ]; then
echo ${LS_RELEASE_NUMBER}
else
echo $((${LS_RELEASE_NUMBER} + 1))
fi''',
returnStdout: true).trim()
}
}
}
/* #######################
Package Version Tagging
####################### */
// Grab the current package versions in Git to determine package tag
stage("Set Package tag"){
steps{
script{
env.PACKAGE_TAG = sh(
script: '''#!/bin/bash
if [ -e package_versions.txt ] ; then
cat package_versions.txt | md5sum | cut -c1-8
else
echo none
fi''',
returnStdout: true).trim()
}
}
}
/* ########################
External Release Tagging
######################## */
// If this is a custom command to determine version use that command
stage("Set tag custom bash"){
steps{
script{
env.EXT_RELEASE = sh(
script: ''' curl -sL https://readarr.servarr.com/v1/update/develop/changes?runtime=netcore%26os=linuxmusl | jq -r '.[0].version' ''',
returnStdout: true).trim()
env.RELEASE_LINK = 'custom_command'
}
}
}
// Sanitize the release tag and strip illegal docker or github characters
stage("Sanitize tag"){
steps{
script{
env.EXT_RELEASE_CLEAN = sh(
script: '''echo ${EXT_RELEASE} | sed 's/[~,%@+;:/]//g' ''',
returnStdout: true).trim()
def semver = env.EXT_RELEASE_CLEAN =~ /(\d+)\.(\d+)\.(\d+)/
if (semver.find()) {
env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${semver[0][3]}"
} else {
semver = env.EXT_RELEASE_CLEAN =~ /(\d+)\.(\d+)(?:\.(\d+))?(.*)/
if (semver.find()) {
if (semver[0][3]) {
env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${semver[0][3]}"
} else if (!semver[0][3] && !semver[0][4]) {
env.SEMVER = "${semver[0][1]}.${semver[0][2]}.${(new Date()).format('YYYYMMdd')}"
}
}
}
if (env.SEMVER != null) {
if (BRANCH_NAME != "master" && BRANCH_NAME != "main") {
env.SEMVER = "${env.SEMVER}-${BRANCH_NAME}"
}
println("SEMVER: ${env.SEMVER}")
} else {
println("No SEMVER detected")
}
}
}
}
// If this is a develop build use live docker endpoints
stage("Set ENV live build"){
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
}
steps {
script{
env.IMAGE = env.DOCKERHUB_IMAGE
env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/' + env.CONTAINER_NAME
env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/' + env.CONTAINER_NAME
env.QUAYIMAGE = 'quay.io/linuxserver.io/' + env.CONTAINER_NAME
if (env.MULTIARCH == 'true') {
env.CI_TAGS = 'amd64-develop-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER + '|arm64v8-develop-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
} else {
env.CI_TAGS = 'develop-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
}
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
env.META_TAG = 'develop-' + env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
env.EXT_RELEASE_TAG = 'develop-version-' + env.EXT_RELEASE_CLEAN
}
}
}
// If this is a dev build use dev docker endpoints
stage("Set ENV dev build"){
when {
not {branch "develop"}
environment name: 'CHANGE_ID', value: ''
}
steps {
script{
env.IMAGE = env.DEV_DOCKERHUB_IMAGE
env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/lsiodev-' + env.CONTAINER_NAME
env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lsiodev-' + env.CONTAINER_NAME
env.QUAYIMAGE = 'quay.io/linuxserver.io/lsiodev-' + env.CONTAINER_NAME
if (env.MULTIARCH == 'true') {
env.CI_TAGS = 'amd64-develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '|arm64v8-develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
} else {
env.CI_TAGS = 'develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
}
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
env.META_TAG = 'develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA
env.EXT_RELEASE_TAG = 'develop-version-' + env.EXT_RELEASE_CLEAN
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.DEV_DOCKERHUB_IMAGE + '/tags/'
}
}
}
// If this is a pull request build use dev docker endpoints
stage("Set ENV PR build"){
when {
not {environment name: 'CHANGE_ID', value: ''}
}
steps {
script{
env.IMAGE = env.PR_DOCKERHUB_IMAGE
env.GITHUBIMAGE = 'ghcr.io/' + env.LS_USER + '/lspipepr-' + env.CONTAINER_NAME
env.GITLABIMAGE = 'registry.gitlab.com/linuxserver.io/' + env.LS_REPO + '/lspipepr-' + env.CONTAINER_NAME
env.QUAYIMAGE = 'quay.io/linuxserver.io/lspipepr-' + env.CONTAINER_NAME
if (env.MULTIARCH == 'true') {
env.CI_TAGS = 'amd64-develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST + '|arm64v8-develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST
} else {
env.CI_TAGS = 'develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST
}
env.VERSION_TAG = env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST
env.META_TAG = 'develop-' + env.EXT_RELEASE_CLEAN + '-pkg-' + env.PACKAGE_TAG + '-dev-' + env.COMMIT_SHA + '-pr-' + env.PULL_REQUEST
env.EXT_RELEASE_TAG = 'develop-version-' + env.EXT_RELEASE_CLEAN
env.CODE_URL = 'https://github.com/' + env.LS_USER + '/' + env.LS_REPO + '/pull/' + env.PULL_REQUEST
env.DOCKERHUB_LINK = 'https://hub.docker.com/r/' + env.PR_DOCKERHUB_IMAGE + '/tags/'
}
}
}
// Run ShellCheck
stage('ShellCheck') {
when {
environment name: 'CI', value: 'true'
}
steps {
withCredentials([
string(credentialsId: 'ci-tests-s3-key-id', variable: 'S3_KEY'),
string(credentialsId: 'ci-tests-s3-secret-access-key', variable: 'S3_SECRET')
]) {
script{
env.SHELLCHECK_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/shellcheck-result.xml'
}
sh '''curl -sL https://raw.githubusercontent.com/linuxserver/docker-jenkins-builder/master/checkrun.sh | /bin/bash'''
sh '''#! /bin/bash
docker run --rm \
-v ${WORKSPACE}:/mnt \
-e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \
-e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \
ghcr.io/linuxserver/baseimage-alpine:3.17 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\
apk add --no-cache py3-pip && \
pip install s3cmd && \
s3cmd put --no-preserve --acl-public -m text/xml /mnt/shellcheck-result.xml s3://ci-tests.linuxserver.io/${IMAGE}/${META_TAG}/shellcheck-result.xml" || :'''
}
}
}
// Use helper containers to render templated files
stage('Update-Templates') {
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
expression {
env.CONTAINER_NAME != null
}
}
steps {
sh '''#! /bin/bash
set -e
TEMPDIR=$(mktemp -d)
docker pull ghcr.io/linuxserver/jenkins-builder:latest
docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH=develop -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest
# Stage 1 - Jenkinsfile update
if [[ "$(md5sum Jenkinsfile | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile | awk '{ print $1 }')" ]]; then
mkdir -p ${TEMPDIR}/repo
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO}
git checkout -f develop
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/Jenkinsfile ${TEMPDIR}/repo/${LS_REPO}/
git add Jenkinsfile
git commit -m 'Bot Updating Templated Files'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
echo "Updating Jenkinsfile"
rm -Rf ${TEMPDIR}
exit 0
else
echo "Jenkinsfile is up to date."
fi
# Stage 2 - Delete old templates
OLD_TEMPLATES=".github/ISSUE_TEMPLATE.md .github/ISSUE_TEMPLATE/issue.bug.md .github/ISSUE_TEMPLATE/issue.feature.md .github/workflows/call_invalid_helper.yml .github/workflows/stale.yml Dockerfile.armhf"
for i in ${OLD_TEMPLATES}; do
if [[ -f "${i}" ]]; then
TEMPLATES_TO_DELETE="${i} ${TEMPLATES_TO_DELETE}"
fi
done
if [[ -n "${TEMPLATES_TO_DELETE}" ]]; then
mkdir -p ${TEMPDIR}/repo
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO}
git checkout -f develop
for i in ${TEMPLATES_TO_DELETE}; do
git rm "${i}"
done
git commit -m 'Bot Updating Templated Files'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
echo "Deleting old and deprecated templates"
rm -Rf ${TEMPDIR}
exit 0
else
echo "No templates to delete"
fi
# Stage 3 - Update templates
CURRENTHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8)
cd ${TEMPDIR}/docker-${CONTAINER_NAME}
NEWHASH=$(grep -hs ^ ${TEMPLATED_FILES} | md5sum | cut -c1-8)
if [[ "${CURRENTHASH}" != "${NEWHASH}" ]] || ! grep -q '.jenkins-external' "${WORKSPACE}/.gitignore" 2>/dev/null; then
mkdir -p ${TEMPDIR}/repo
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/repo/${LS_REPO}
cd ${TEMPDIR}/repo/${LS_REPO}
git checkout -f develop
cd ${TEMPDIR}/docker-${CONTAINER_NAME}
mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/workflows
mkdir -p ${TEMPDIR}/repo/${LS_REPO}/.github/ISSUE_TEMPLATE
cp --parents ${TEMPLATED_FILES} ${TEMPDIR}/repo/${LS_REPO}/ || :
cp --parents readme-vars.yml ${TEMPDIR}/repo/${LS_REPO}/ || :
cd ${TEMPDIR}/repo/${LS_REPO}/
if ! grep -q '.jenkins-external' .gitignore 2>/dev/null; then
echo ".jenkins-external" >> .gitignore
git add .gitignore
fi
git add readme-vars.yml ${TEMPLATED_FILES}
git commit -m 'Bot Updating Templated Files'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
else
echo "false" > /tmp/${COMMIT_SHA}-${BUILD_NUMBER}
fi
mkdir -p ${TEMPDIR}/gitbook
git clone https://github.com/linuxserver/docker-documentation.git ${TEMPDIR}/gitbook/docker-documentation
if [[ ("${BRANCH_NAME}" == "master") || ("${BRANCH_NAME}" == "main") ]] && [[ (! -f ${TEMPDIR}/gitbook/docker-documentation/images/docker-${CONTAINER_NAME}.md) || ("$(md5sum ${TEMPDIR}/gitbook/docker-documentation/images/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md | awk '{ print $1 }')") ]]; then
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/docker-${CONTAINER_NAME}.md ${TEMPDIR}/gitbook/docker-documentation/images/
cd ${TEMPDIR}/gitbook/docker-documentation/
git add images/docker-${CONTAINER_NAME}.md
git commit -m 'Bot Updating Documentation'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/docker-documentation.git --all
fi
mkdir -p ${TEMPDIR}/unraid
git clone https://github.com/linuxserver/docker-templates.git ${TEMPDIR}/unraid/docker-templates
git clone https://github.com/linuxserver/templates.git ${TEMPDIR}/unraid/templates
if [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-logo.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-logo.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
elif [[ -f ${TEMPDIR}/unraid/docker-templates/linuxserver.io/img/${CONTAINER_NAME}-icon.png ]]; then
sed -i "s|master/linuxserver.io/img/linuxserver-ls-logo.png|master/linuxserver.io/img/${CONTAINER_NAME}-icon.png|" ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml
fi
if [[ ("${BRANCH_NAME}" == "master") || ("${BRANCH_NAME}" == "main") ]] && [[ (! -f ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml) || ("$(md5sum ${TEMPDIR}/unraid/templates/unraid/${CONTAINER_NAME}.xml | awk '{ print $1 }')" != "$(md5sum ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml | awk '{ print $1 }')") ]]; then
cd ${TEMPDIR}/unraid/templates/
if grep -wq "${CONTAINER_NAME}" ${TEMPDIR}/unraid/templates/unraid/ignore.list; then
echo "Image is on the ignore list, marking Unraid template as deprecated"
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add -u unraid/${CONTAINER_NAME}.xml
git mv unraid/${CONTAINER_NAME}.xml unraid/deprecated/${CONTAINER_NAME}.xml || :
git commit -m 'Bot Moving Deprecated Unraid Template' || :
else
cp ${TEMPDIR}/docker-${CONTAINER_NAME}/.jenkins-external/${CONTAINER_NAME}.xml ${TEMPDIR}/unraid/templates/unraid/
git add unraid/${CONTAINER_NAME}.xml
git commit -m 'Bot Updating Unraid Template'
fi
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/linuxserver/templates.git --all
fi
rm -Rf ${TEMPDIR}'''
script{
env.FILES_UPDATED = sh(
script: '''cat /tmp/${COMMIT_SHA}-${BUILD_NUMBER}''',
returnStdout: true).trim()
}
}
}
// Exit the build if the Templated files were just updated
stage('Template-exit') {
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
environment name: 'FILES_UPDATED', value: 'true'
expression {
env.CONTAINER_NAME != null
}
}
steps {
script{
env.EXIT_STATUS = 'ABORTED'
}
}
}
// If this is a develop build check the S6 service file perms
stage("Check S6 Service file Permissions"){
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
script{
sh '''#! /bin/bash
WRONG_PERM=$(find ./ -path "./.git" -prune -o \\( -name "run" -o -name "finish" -o -name "check" \\) -not -perm -u=x,g=x,o=x -print)
if [[ -n "${WRONG_PERM}" ]]; then
echo "The following S6 service files are missing the executable bit; canceling the faulty build: ${WRONG_PERM}"
exit 1
else
echo "S6 service file perms look good."
fi '''
}
}
}
/* #######################
GitLab Mirroring
####################### */
// Ping into Gitlab to mirror this repo and have a registry endpoint
stage("GitLab Mirror"){
when {
environment name: 'EXIT_STATUS', value: ''
}
steps{
sh '''curl -H "Content-Type: application/json" -H "Private-Token: ${GITLAB_TOKEN}" -X POST https://gitlab.com/api/v4/projects \
-d '{"namespace_id":'${GITLAB_NAMESPACE}',\
"name":"'${LS_REPO}'",
"mirror":true,\
"import_url":"https://github.com/linuxserver/'${LS_REPO}'.git",\
"issues_access_level":"disabled",\
"merge_requests_access_level":"disabled",\
"repository_access_level":"enabled",\
"visibility":"public"}' '''
}
}
/* #######################
Scarf.sh package registry
####################### */
// Add package to Scarf.sh and set permissions
stage("Scarf.sh package registry"){
when {
branch "develop"
environment name: 'EXIT_STATUS', value: ''
}
steps{
sh '''#! /bin/bash
PACKAGE_UUID=$(curl -X GET -H "Authorization: Bearer ${SCARF_TOKEN}" https://scarf.sh/api/v1/organizations/linuxserver-ci/packages | jq -r '.[] | select(.name=="linuxserver/readarr") | .uuid' || :)
if [ -z "${PACKAGE_UUID}" ]; then
echo "Adding package to Scarf.sh"
curl -sX POST https://scarf.sh/api/v1/organizations/linuxserver-ci/packages \
-H "Authorization: Bearer ${SCARF_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name":"linuxserver/readarr",\
"shortDescription":"example description",\
"libraryType":"docker",\
"website":"https://github.com/linuxserver/docker-readarr",\
"backendUrl":"https://ghcr.io/linuxserver/readarr",\
"publicUrl":"https://lscr.io/linuxserver/readarr"}' || :
else
echo "Package already exists on Scarf.sh"
fi
'''
}
}
/* ###############
Build Container
############### */
// Build Docker container for push to LS Repo
stage('Build-Single') {
when {
expression {
env.MULTIARCH == 'false' || params.PACKAGE_CHECK == 'true'
}
environment name: 'EXIT_STATUS', value: ''
}
steps {
echo "Running on node: ${NODE_NAME}"
sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile"
sh "docker buildx build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-readarr/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-readarr\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-readarr\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Readarr\" \
--label \"org.opencontainers.image.description=[Readarr](https://github.com/Readarr/Readarr) - Book Manager and Automation (Sonarr for Ebooks) \" \
--no-cache --pull -t ${IMAGE}:${META_TAG} --platform=linux/amd64 \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
}
}
// Build MultiArch Docker containers for push to LS Repo
stage('Build-Multi') {
when {
allOf {
environment name: 'MULTIARCH', value: 'true'
expression { params.PACKAGE_CHECK == 'false' }
}
environment name: 'EXIT_STATUS', value: ''
}
parallel {
stage('Build X86') {
steps {
echo "Running on node: ${NODE_NAME}"
sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile"
sh "docker buildx build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-readarr/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-readarr\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-readarr\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Readarr\" \
--label \"org.opencontainers.image.description=[Readarr](https://github.com/Readarr/Readarr) - Book Manager and Automation (Sonarr for Ebooks) \" \
--no-cache --pull -t ${IMAGE}:amd64-${META_TAG} --platform=linux/amd64 \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
}
}
stage('Build ARM64') {
agent {
label 'ARM64'
}
steps {
echo "Running on node: ${NODE_NAME}"
echo 'Logging into Github'
sh '''#! /bin/bash
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
'''
sh "sed -r -i 's|(^FROM .*)|\\1\\n\\nENV LSIO_FIRST_PARTY=true|g' Dockerfile.aarch64"
sh "docker buildx build \
--label \"org.opencontainers.image.created=${GITHUB_DATE}\" \
--label \"org.opencontainers.image.authors=linuxserver.io\" \
--label \"org.opencontainers.image.url=https://github.com/linuxserver/docker-readarr/packages\" \
--label \"org.opencontainers.image.documentation=https://docs.linuxserver.io/images/docker-readarr\" \
--label \"org.opencontainers.image.source=https://github.com/linuxserver/docker-readarr\" \
--label \"org.opencontainers.image.version=${EXT_RELEASE_CLEAN}-ls${LS_TAG_NUMBER}\" \
--label \"org.opencontainers.image.revision=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.vendor=linuxserver.io\" \
--label \"org.opencontainers.image.licenses=GPL-3.0-only\" \
--label \"org.opencontainers.image.ref.name=${COMMIT_SHA}\" \
--label \"org.opencontainers.image.title=Readarr\" \
--label \"org.opencontainers.image.description=[Readarr](https://github.com/Readarr/Readarr) - Book Manager and Automation (Sonarr for Ebooks) \" \
--no-cache --pull -f Dockerfile.aarch64 -t ${IMAGE}:arm64v8-${META_TAG} --platform=linux/arm64 \
--build-arg ${BUILD_VERSION_ARG}=${EXT_RELEASE} --build-arg VERSION=\"${VERSION_TAG}\" --build-arg BUILD_DATE=${GITHUB_DATE} ."
sh "docker tag ${IMAGE}:arm64v8-${META_TAG} ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}"
retry(5) {
sh "docker push ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}"
}
sh '''#! /bin/bash
containers=$(docker ps -aq)
if [[ -n "${containers}" ]]; then
docker stop ${containers}
fi
docker system prune -af --volumes || : '''
}
}
}
}
// Take the image we just built and dump package versions for comparison
stage('Update-packages') {
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
sh '''#! /bin/bash
set -e
TEMPDIR=$(mktemp -d)
if [ "${MULTIARCH}" == "true" ] && [ "${PACKAGE_CHECK}" == "false" ]; then
LOCAL_CONTAINER=${IMAGE}:amd64-${META_TAG}
else
LOCAL_CONTAINER=${IMAGE}:${META_TAG}
fi
touch ${TEMPDIR}/package_versions.txt
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v ${TEMPDIR}:/tmp \
ghcr.io/anchore/syft:latest \
${LOCAL_CONTAINER} -o table=/tmp/package_versions.txt
NEW_PACKAGE_TAG=$(md5sum ${TEMPDIR}/package_versions.txt | cut -c1-8 )
echo "Package tag sha from current packages in buit container is ${NEW_PACKAGE_TAG} comparing to old ${PACKAGE_TAG} from github"
if [ "${NEW_PACKAGE_TAG}" != "${PACKAGE_TAG}" ]; then
git clone https://github.com/${LS_USER}/${LS_REPO}.git ${TEMPDIR}/${LS_REPO}
git --git-dir ${TEMPDIR}/${LS_REPO}/.git checkout -f develop
cp ${TEMPDIR}/package_versions.txt ${TEMPDIR}/${LS_REPO}/
cd ${TEMPDIR}/${LS_REPO}/
wait
git add package_versions.txt
git commit -m 'Bot Updating Package Versions'
git push https://LinuxServer-CI:${GITHUB_TOKEN}@github.com/${LS_USER}/${LS_REPO}.git --all
echo "true" > /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER}
echo "Package tag updated, stopping build process"
else
echo "false" > /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER}
echo "Package tag is same as previous continue with build process"
fi
rm -Rf ${TEMPDIR}'''
script{
env.PACKAGE_UPDATED = sh(
script: '''cat /tmp/packages-${COMMIT_SHA}-${BUILD_NUMBER}''',
returnStdout: true).trim()
}
}
}
// Exit the build if the package file was just updated
stage('PACKAGE-exit') {
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
environment name: 'PACKAGE_UPDATED', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
script{
env.EXIT_STATUS = 'ABORTED'
}
}
}
// Exit the build if this is just a package check and there are no changes to push
stage('PACKAGECHECK-exit') {
when {
branch "develop"
environment name: 'CHANGE_ID', value: ''
environment name: 'PACKAGE_UPDATED', value: 'false'
environment name: 'EXIT_STATUS', value: ''
expression {
params.PACKAGE_CHECK == 'true'
}
}
steps {
script{
env.EXIT_STATUS = 'ABORTED'
}
}
}
/* #######
Testing
####### */
// Run Container tests
stage('Test') {
when {
environment name: 'CI', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
string(credentialsId: 'ci-tests-s3-key-id', variable: 'S3_KEY'),
string(credentialsId: 'ci-tests-s3-secret-access-key ', variable: 'S3_SECRET')
]) {
script{
env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html'
env.CI_JSON_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/report.json'
}
sh '''#! /bin/bash
set -e
docker pull ghcr.io/linuxserver/ci:latest
if [ "${MULTIARCH}" == "true" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
fi
docker run --rm \
--shm-size=1gb \
-v /var/run/docker.sock:/var/run/docker.sock \
-e IMAGE=\"${IMAGE}\" \
-e DELAY_START=\"${CI_DELAY}\" \
-e TAGS=\"${CI_TAGS}\" \
-e META_TAG=\"${META_TAG}\" \
-e PORT=\"${CI_PORT}\" \
-e SSL=\"${CI_SSL}\" \
-e BASE=\"${DIST_IMAGE}\" \
-e SECRET_KEY=\"${S3_SECRET}\" \
-e ACCESS_KEY=\"${S3_KEY}\" \
-e DOCKER_ENV=\"${CI_DOCKERENV}\" \
-e WEB_SCREENSHOT=\"${CI_WEB}\" \
-e WEB_AUTH=\"${CI_AUTH}\" \
-e WEB_PATH=\"${CI_WEBPATH}\" \
-t ghcr.io/linuxserver/ci:latest \
python3 test_build.py'''
}
}
}
/* ##################
Release Logic
################## */
// If this is an amd64 only image only push a single image
stage('Docker-Push-Single') {
when {
environment name: 'MULTIARCH', value: 'false'
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207',
usernameVariable: 'DOCKERUSER',
passwordVariable: 'DOCKERPASS'
],
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: 'Quay.io-Robot',
usernameVariable: 'QUAYUSER',
passwordVariable: 'QUAYPASS'
]
]) {
retry(5) {
sh '''#! /bin/bash
set -e
echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
for PUSHIMAGE in "${GITHUBIMAGE}" "${GITLABIMAGE}" "${QUAYIMAGE}" "${IMAGE}"; do
docker tag ${IMAGE}:${META_TAG} ${PUSHIMAGE}:${META_TAG}
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:develop
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker tag ${PUSHIMAGE}:${META_TAG} ${PUSHIMAGE}:${SEMVER}
fi
docker push ${PUSHIMAGE}:develop
docker push ${PUSHIMAGE}:${META_TAG}
docker push ${PUSHIMAGE}:${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker push ${PUSHIMAGE}:${SEMVER}
fi
done
'''
}
}
}
}
// If this is a multi arch release push all images and define the manifest
stage('Docker-Push-Multi') {
when {
environment name: 'MULTIARCH', value: 'true'
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207',
usernameVariable: 'DOCKERUSER',
passwordVariable: 'DOCKERPASS'
],
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: 'Quay.io-Robot',
usernameVariable: 'QUAYUSER',
passwordVariable: 'QUAYPASS'
]
]) {
retry(5) {
sh '''#! /bin/bash
set -e
echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin
echo $GITHUB_TOKEN | docker login ghcr.io -u LinuxServer-CI --password-stdin
echo $GITLAB_TOKEN | docker login registry.gitlab.com -u LinuxServer.io --password-stdin
echo $QUAYPASS | docker login quay.io -u $QUAYUSER --password-stdin
if [ "${CI}" == "false" ]; then
docker pull ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER}
docker tag ghcr.io/linuxserver/lsiodev-buildcache:arm64v8-${COMMIT_SHA}-${BUILD_NUMBER} ${IMAGE}:arm64v8-${META_TAG}
fi
for MANIFESTIMAGE in "${IMAGE}" "${GITLABIMAGE}" "${GITHUBIMAGE}" "${QUAYIMAGE}"; do
docker tag ${IMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG}
docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-develop
docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG}
docker tag ${IMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-develop
docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker tag ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:amd64-${SEMVER}
docker tag ${MANIFESTIMAGE}:arm64v8-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${SEMVER}
fi
docker push ${MANIFESTIMAGE}:amd64-${META_TAG}
docker push ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG}
docker push ${MANIFESTIMAGE}:amd64-develop
docker push ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker push ${MANIFESTIMAGE}:arm64v8-develop
docker push ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker push ${MANIFESTIMAGE}:amd64-${SEMVER}
docker push ${MANIFESTIMAGE}:arm64v8-${SEMVER}
fi
docker manifest push --purge ${MANIFESTIMAGE}:develop || :
docker manifest create ${MANIFESTIMAGE}:develop ${MANIFESTIMAGE}:amd64-develop ${MANIFESTIMAGE}:arm64v8-develop
docker manifest annotate ${MANIFESTIMAGE}:develop ${MANIFESTIMAGE}:arm64v8-develop --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG} || :
docker manifest create ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:amd64-${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG}
docker manifest annotate ${MANIFESTIMAGE}:${META_TAG} ${MANIFESTIMAGE}:arm64v8-${META_TAG} --os linux --arch arm64 --variant v8
docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} || :
docker manifest create ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:amd64-${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG}
docker manifest annotate ${MANIFESTIMAGE}:${EXT_RELEASE_TAG} ${MANIFESTIMAGE}:arm64v8-${EXT_RELEASE_TAG} --os linux --arch arm64 --variant v8
if [ -n "${SEMVER}" ]; then
docker manifest push --purge ${MANIFESTIMAGE}:${SEMVER} || :
docker manifest create ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:amd64-${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER}
docker manifest annotate ${MANIFESTIMAGE}:${SEMVER} ${MANIFESTIMAGE}:arm64v8-${SEMVER} --os linux --arch arm64 --variant v8
fi
token=$(curl -sX GET "https://ghcr.io/token?scope=repository%3Alinuxserver%2F${CONTAINER_NAME}%3Apull" | jq -r '.token')
digest=$(curl -s \
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--header "Authorization: Bearer ${token}" \
"https://ghcr.io/v2/linuxserver/${CONTAINER_NAME}/manifests/arm32v7-develop")
if [[ $(echo "$digest" | jq -r '.layers') != "null" ]]; then
docker manifest push --purge ${MANIFESTIMAGE}:arm32v7-develop || :
docker manifest create ${MANIFESTIMAGE}:arm32v7-develop ${MANIFESTIMAGE}:amd64-develop
docker manifest push --purge ${MANIFESTIMAGE}:arm32v7-develop
fi
docker manifest push --purge ${MANIFESTIMAGE}:develop
docker manifest push --purge ${MANIFESTIMAGE}:${META_TAG}
docker manifest push --purge ${MANIFESTIMAGE}:${EXT_RELEASE_TAG}
if [ -n "${SEMVER}" ]; then
docker manifest push --purge ${MANIFESTIMAGE}:${SEMVER}
fi
done
'''
}
}
}
}
// If this is a public release tag it in the LS Github
stage('Github-Tag-Push-Release') {
when {
branch "develop"
expression {
env.LS_RELEASE != env.EXT_RELEASE_CLEAN + '-ls' + env.LS_TAG_NUMBER
}
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
echo "Pushing New tag for current commit ${META_TAG}"
sh '''curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/git/tags \
-d '{"tag":"'${META_TAG}'",\
"object": "'${COMMIT_SHA}'",\
"message": "Tagging Release '${EXT_RELEASE_CLEAN}'-ls'${LS_TAG_NUMBER}' to develop",\
"type": "commit",\
"tagger": {"name": "LinuxServer Jenkins","email": "jenkins@linuxserver.io","date": "'${GITHUB_DATE}'"}}' '''
echo "Pushing New release for Tag"
sh '''#! /bin/bash
echo "Updating to ${EXT_RELEASE_CLEAN}" > releasebody.json
echo '{"tag_name":"'${META_TAG}'",\
"target_commitish": "develop",\
"name": "'${META_TAG}'",\
"body": "**LinuxServer Changes:**\\n\\n'${LS_RELEASE_NOTES}'\\n\\n**Remote Changes:**\\n\\n' > start
printf '","draft": false,"prerelease": true}' >> releasebody.json
paste -d'\\0' start releasebody.json > releasebody.json.done
curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST https://api.github.com/repos/${LS_USER}/${LS_REPO}/releases -d @releasebody.json.done'''
}
}
// Use helper container to sync the current README on master to the dockerhub endpoint
stage('Sync-README') {
when {
environment name: 'CHANGE_ID', value: ''
environment name: 'EXIT_STATUS', value: ''
}
steps {
withCredentials([
[
$class: 'UsernamePasswordMultiBinding',
credentialsId: '3f9ba4d5-100d-45b0-a3c4-633fd6061207',
usernameVariable: 'DOCKERUSER',
passwordVariable: 'DOCKERPASS'
]
]) {
sh '''#! /bin/bash
set -e
TEMPDIR=$(mktemp -d)
docker pull ghcr.io/linuxserver/jenkins-builder:latest
docker run --rm -e CONTAINER_NAME=${CONTAINER_NAME} -e GITHUB_BRANCH="${BRANCH_NAME}" -v ${TEMPDIR}:/ansible/jenkins ghcr.io/linuxserver/jenkins-builder:latest
docker pull ghcr.io/linuxserver/readme-sync
docker run --rm=true \
-e DOCKERHUB_USERNAME=$DOCKERUSER \
-e DOCKERHUB_PASSWORD=$DOCKERPASS \
-e GIT_REPOSITORY=${LS_USER}/${LS_REPO} \
-e DOCKER_REPOSITORY=${IMAGE} \
-e GIT_BRANCH=master \
-v ${TEMPDIR}/docker-${CONTAINER_NAME}:/mnt \
ghcr.io/linuxserver/readme-sync bash -c 'node sync'
rm -Rf ${TEMPDIR} '''
}
}
}
// If this is a Pull request send the CI link as a comment on it
stage('Pull Request Comment') {
when {
not {environment name: 'CHANGE_ID', value: ''}
environment name: 'EXIT_STATUS', value: ''
}
steps {
sh '''#! /bin/bash
# Function to retrieve JSON data from URL
get_json() {
local url="$1"
local response=$(curl -s "$url")
if [ $? -ne 0 ]; then
echo "Failed to retrieve JSON data from $url"
return 1
fi
local json=$(echo "$response" | jq .)
if [ $? -ne 0 ]; then
echo "Failed to parse JSON data from $url"
return 1
fi
echo "$json"
}
build_table() {
local data="$1"
# Get the keys in the JSON data
local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]')
# Check if keys are empty
if [ -z "$keys" ]; then
echo "JSON report data does not contain any keys or the report does not exist."
return 1
fi
# Build table header
local header="| Tag | Passed |\\n| --- | --- |\\n"
# Loop through the JSON data to build the table rows
local rows=""
for build in $keys; do
local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success")
if [ "$status" = "true" ]; then
status="✅"
else
status="❌"
fi
local row="| "$build" | "$status" |\\n"
rows="${rows}${row}"
done
local table="${header}${rows}"
local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g')
echo "$escaped_table"
}
if [[ "${CI}" = "true" ]]; then
# Retrieve JSON data from URL
data=$(get_json "$CI_JSON_URL")
# Create table from JSON data
table=$(build_table "$data")
echo -e "$table"
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here are the test results for this PR: \\n${CI_URL}\\n${SHELLCHECK_URL}\\n${table}\\"}"
else
curl -X POST -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \
-d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}"
fi
'''
}
}
}
/* ######################
Send status to Discord
###################### */
post {
always {
script{
if (env.EXIT_STATUS == "ABORTED"){
sh 'echo "build aborted"'
}
else if (currentBuild.currentResult == "SUCCESS"){
sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"color": 1681177,\
"description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** Success\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\
"username": "Jenkins"}' ${BUILDS_DISCORD} '''
}
else {
sh ''' curl -X POST -H "Content-Type: application/json" --data '{"avatar_url": "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/jenkins-avatar.png","embeds": [{"color": 16711680,\
"description": "**Build:** '${BUILD_NUMBER}'\\n**CI Results:** '${CI_URL}'\\n**ShellCheck Results:** '${SHELLCHECK_URL}'\\n**Status:** failure\\n**Job:** '${RUN_DISPLAY_URL}'\\n**Change:** '${CODE_URL}'\\n**External Release:**: '${RELEASE_LINK}'\\n**DockerHub:** '${DOCKERHUB_LINK}'\\n"}],\
"username": "Jenkins"}' ${BUILDS_DISCORD} '''
}
}
}
cleanup {
sh '''#! /bin/bash
echo "Performing docker system prune!!"
containers=$(docker ps -aq)
if [[ -n "${containers}" ]]; then
docker stop ${containers}
fi
docker system prune -af --volumes || :
'''
cleanWs()
}
}
}

192
README.md
View File

@ -1,10 +1,9 @@
<!-- DO NOT EDIT THIS FILE MANUALLY -->
<!-- Please read the https://github.com/linuxserver/docker-readarr/blob/develop/.github/CONTRIBUTING.md -->
<!-- DO NOT EDIT THIS FILE MANUALLY -->
<!-- Please read https://github.com/linuxserver/docker-readarr/blob/main/.github/CONTRIBUTING.md -->
[![linuxserver.io](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/linuxserver_medium.png)](https://linuxserver.io)
[![Blog](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Blog)](https://blog.linuxserver.io "all the things you can do with our containers including How-To guides, opinions and much more!")
[![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://discord.gg/YWrKVTn "realtime support / chat with the community and the team.")
[![Discord](https://img.shields.io/discord/354974912613449730.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=Discord&logo=discord)](https://linuxserver.io/discord "realtime support / chat with the community and the team.")
[![Discourse](https://img.shields.io/discourse/https/discourse.linuxserver.io/topics.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=discourse)](https://discourse.linuxserver.io "post on our community forum.")
[![Fleet](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=Fleet)](https://fleet.linuxserver.io "an online web interface which displays all of our maintained images.")
[![GitHub](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub&logo=github)](https://github.com/linuxserver "view the source for all of our repositories.")
@ -21,15 +20,21 @@ The [LinuxServer.io](https://linuxserver.io) team brings you another container r
Find us at:
* [Blog](https://blog.linuxserver.io) - all the things you can do with our containers including How-To guides, opinions and much more!
* [Discord](https://discord.gg/YWrKVTn) - realtime support / chat with the community and the team.
* [Discord](https://linuxserver.io/discord) - realtime support / chat with the community and the team.
* [Discourse](https://discourse.linuxserver.io) - post on our community forum.
* [Fleet](https://fleet.linuxserver.io) - an online web interface which displays all of our maintained images.
* [GitHub](https://github.com/linuxserver) - view the source for all of our repositories.
* [Open Collective](https://opencollective.com/linuxserver) - please consider helping us by either donating or contributing to our budget
# DEPRECATION NOTICE
This image is deprecated. We will not offer support for this image and it will not be updated.
Due to lack of developers, and issues with maintaining status quo, upstream has decided to retire the project.
# [linuxserver/readarr](https://github.com/linuxserver/docker-readarr)
[![Scarf.io pulls](https://scarf.sh/installs-badge/linuxserver-ci/linuxserver%2Freadarr?color=94398d&label-color=555555&logo-color=ffffff&style=for-the-badge&package-type=docker)](https://scarf.sh/gateway/linuxserver-ci/docker/linuxserver%2Freadarr)
[![Scarf.io pulls](https://scarf.sh/installs-badge/linuxserver-ci/linuxserver%2Freadarr?color=94398d&label-color=555555&logo-color=ffffff&style=for-the-badge&package-type=docker)](https://scarf.sh)
[![GitHub Stars](https://img.shields.io/github/stars/linuxserver/docker-readarr.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github)](https://github.com/linuxserver/docker-readarr)
[![GitHub Release](https://img.shields.io/github/release/linuxserver/docker-readarr.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&logo=github&include_prereleases)](https://github.com/linuxserver/docker-readarr/releases)
[![GitHub Package Repository](https://img.shields.io/static/v1.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=linuxserver.io&message=GitHub%20Package&logo=github)](https://github.com/linuxserver/docker-readarr/packages)
@ -38,7 +43,6 @@ Find us at:
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/readarr.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/linuxserver/readarr)
[![Docker Stars](https://img.shields.io/docker/stars/linuxserver/readarr.svg?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=stars&logo=docker)](https://hub.docker.com/r/linuxserver/readarr)
[![Jenkins Build](https://img.shields.io/jenkins/build?labelColor=555555&logoColor=ffffff&style=for-the-badge&jobUrl=https%3A%2F%2Fci.linuxserver.io%2Fjob%2FDocker-Pipeline-Builders%2Fjob%2Fdocker-readarr%2Fjob%2Fdevelop%2F&logo=jenkins)](https://ci.linuxserver.io/job/Docker-Pipeline-Builders/job/docker-readarr/job/develop/)
[![LSIO CI](https://img.shields.io/badge/dynamic/yaml?color=94398d&labelColor=555555&logoColor=ffffff&style=for-the-badge&label=CI&query=CI&url=https%3A%2F%2Fci-tests.linuxserver.io%2Flinuxserver%2Freadarr%2Flatest%2Fci-status.yml)](https://ci-tests.linuxserver.io/linuxserver/readarr/latest/index.html)
[Readarr](https://github.com/Readarr/Readarr) - Book Manager and Automation (Sonarr for Ebooks)
@ -46,7 +50,7 @@ Find us at:
## Supported Architectures
We utilise the docker manifest for multi-platform awareness. More information is available from docker [here](https://github.com/docker/distribution/blob/master/docs/spec/manifest-v2-2.md#manifest-list) and our announcement [here](https://blog.linuxserver.io/2019/02/21/the-lsio-pipeline-project/).
We utilise the docker manifest for multi-platform awareness. More information is available from docker [here](https://distribution.github.io/distribution/spec/manifest-v2-2/#manifest-list) and our announcement [here](https://blog.linuxserver.io/2019/02/21/the-lsio-pipeline-project/).
Simply pulling `lscr.io/linuxserver/readarr:develop` should retrieve the correct image for your arch, but you can also pull specific arch images via tags.
@ -67,27 +71,39 @@ This image provides various versions that are available via tags. Please read th
| latest | ❌ | |
| develop | ✅ | Readarr releases from their develop branch |
| nightly | ✅ | Readarr releases from their nightly branch |
## Application Setup
Access the webui at `<your-ip>:8787`, for more information check out [Readarr](https://github.com/Readarr/Readarr).
### Media folders
We have set `/books` and `/downloads` as ***optional paths***, this is because it is the easiest way to get started. While easy to use, it has some drawbacks. Mainly losing the ability to hardlink (TL;DR a way for a file to exist in multiple places on the same file system while only consuming one file worth of space), or atomic move (TL;DR instant file moves, rather than copy+delete) files while processing content.
We have set `/books` and `/downloads` as optional paths, this is because it is the easiest way to get started. While easy to use, it has some drawbacks. Mainly losing the ability to hardlink (TL;DR a way for a file to exist in multiple places on the same file system while only consuming one file worth of space), or atomic move (TL;DR instant file moves, rather than copy+delete) files while processing content.
Use the optional paths if you dont understand, or dont want hardlinks/atomic moves.
Use the optional paths if you don't understand, or don't want hardlinks/atomic moves.
The folks over at servarr.com wrote a good [write-up](https://wiki.servarr.com/docker-guide#consistent-and-well-planned-paths) on how to get started with this.
>[!TIP]
>The folks over at servarr.com wrote a good [write-up](https://wiki.servarr.com/docker-guide#consistent-and-well-planned-paths) on how to get started with this.
## Read-Only Operation
This image can be run with a read-only container filesystem. For details please [read the docs](https://docs.linuxserver.io/misc/read-only/).
## Non-Root Operation
This image can be run with a non-root user. For details please [read the docs](https://docs.linuxserver.io/misc/non-root/).
## Usage
Here are some example snippets to help you get started creating a container.
To help you get started creating a container from this image you can either use docker-compose or the docker cli.
>[!NOTE]
>Unless a parameter is flaged as 'optional', it is *mandatory* and a value must be provided.
### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose))
```yaml
---
version: "2.1"
services:
readarr:
image: lscr.io/linuxserver/readarr:develop
@ -97,9 +113,9 @@ services:
- PGID=1000
- TZ=Etc/UTC
volumes:
- /path/to/data:/config
- /path/to/readarr/data:/config
- /path/to/books:/books #optional
- /path/to/downloadclient-downloads:/downloads #optional
- /path/to/download-client-downloads:/downloads #optional
ports:
- 8787:8787
restart: unless-stopped
@ -114,27 +130,28 @@ docker run -d \
-e PGID=1000 \
-e TZ=Etc/UTC \
-p 8787:8787 \
-v /path/to/data:/config \
-v /path/to/readarr/data:/config \
-v /path/to/books:/books `#optional` \
-v /path/to/downloadclient-downloads:/downloads `#optional` \
-v /path/to/download-client-downloads:/downloads `#optional` \
--restart unless-stopped \
lscr.io/linuxserver/readarr:develop
```
## Parameters
Container images are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate `<external>:<internal>` respectively. For example, `-p 8080:80` would expose port `80` from inside the container to be accessible from the host's IP on port `8080` outside the container.
Containers are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate `<external>:<internal>` respectively. For example, `-p 8080:80` would expose port `80` from inside the container to be accessible from the host's IP on port `8080` outside the container.
| Parameter | Function |
| :----: | --- |
| `-p 8787` | The port for the Readarr webinterface |
| `-p 8787:8787` | The port for the Readarr web UI |
| `-e PUID=1000` | for UserID - see below for explanation |
| `-e PGID=1000` | for GroupID - see below for explanation |
| `-e TZ=Etc/UTC` | specify a timezone to use, see this [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List). |
| `-v /config` | Database and Readarr configs |
| `-v /books` | Location of Book library on disk (See note in Application setup) |
| `-v /downloads` | Location of download managers output directory (See note in Application setup) |
| `--read-only=true` | Run container with a read-only filesystem. Please [read the docs](https://docs.linuxserver.io/misc/read-only/). |
| `--user=1000:1000` | Run container with a non-root user. Please [read the docs](https://docs.linuxserver.io/misc/non-root/). |
## Environment variables from files (Docker secrets)
@ -143,10 +160,10 @@ You can set any environment variable from a file by using a special prepend `FIL
As an example:
```bash
-e FILE__PASSWORD=/run/secrets/mysecretpassword
-e FILE__MYVAR=/run/secrets/mysecretvariable
```
Will set the environment variable `PASSWORD` based on the contents of the `/run/secrets/mysecretpassword` file.
Will set the environment variable `MYVAR` based on the contents of the `/run/secrets/mysecretvariable` file.
## Umask for running applications
@ -155,15 +172,20 @@ Keep in mind umask is not chmod it subtracts from permissions based on it's valu
## User / Group Identifiers
When using volumes (`-v` flags) permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user `PUID` and group `PGID`.
When using volumes (`-v` flags), permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user `PUID` and group `PGID`.
Ensure any volume directories on the host are owned by the same user you specify and any permissions issues will vanish like magic.
In this instance `PUID=1000` and `PGID=1000`, to find yours use `id user` as below:
In this instance `PUID=1000` and `PGID=1000`, to find yours use `id your_user` as below:
```bash
$ id username
uid=1000(dockeruser) gid=1000(dockergroup) groups=1000(dockergroup)
id your_user
```
Example output:
```text
uid=1000(your_user) gid=1000(your_user) groups=1000(your_user)
```
## Docker Mods
@ -174,53 +196,101 @@ We publish various [Docker Mods](https://github.com/linuxserver/docker-mods) to
## Support Info
* Shell access whilst the container is running: `docker exec -it readarr /bin/bash`
* To monitor the logs of the container in realtime: `docker logs -f readarr`
* container version number
* `docker inspect -f '{{ index .Config.Labels "build_version" }}' readarr`
* image version number
* `docker inspect -f '{{ index .Config.Labels "build_version" }}' lscr.io/linuxserver/readarr:develop`
* Shell access whilst the container is running:
```bash
docker exec -it readarr /bin/bash
```
* To monitor the logs of the container in realtime:
```bash
docker logs -f readarr
```
* Container version number:
```bash
docker inspect -f '{{ index .Config.Labels "build_version" }}' readarr
```
* Image version number:
```bash
docker inspect -f '{{ index .Config.Labels "build_version" }}' lscr.io/linuxserver/readarr
```
## Updating Info
Most of our images are static, versioned, and require an image update and container recreation to update the app inside. With some exceptions (ie. nextcloud, plex), we do not recommend or support updating apps inside the container. Please consult the [Application Setup](#application-setup) section above to see if it is recommended for the image.
Most of our images are static, versioned, and require an image update and container recreation to update the app inside. With some exceptions (noted in the relevant readme.md), we do not recommend or support updating apps inside the container. Please consult the [Application Setup](#application-setup) section above to see if it is recommended for the image.
Below are the instructions for updating containers:
### Via Docker Compose
* Update all images: `docker-compose pull`
* or update a single image: `docker-compose pull readarr`
* Let compose update all containers as necessary: `docker-compose up -d`
* or update a single container: `docker-compose up -d readarr`
* You can also remove the old dangling images: `docker image prune`
* Update images:
* All images:
```bash
docker-compose pull
```
* Single image:
```bash
docker-compose pull readarr
```
* Update containers:
* All containers:
```bash
docker-compose up -d
```
* Single container:
```bash
docker-compose up -d readarr
```
* You can also remove the old dangling images:
```bash
docker image prune
```
### Via Docker Run
* Update the image: `docker pull lscr.io/linuxserver/readarr:develop`
* Stop the running container: `docker stop readarr`
* Delete the container: `docker rm readarr`
* Update the image:
```bash
docker pull lscr.io/linuxserver/readarr
```
* Stop the running container:
```bash
docker stop readarr
```
* Delete the container:
```bash
docker rm readarr
```
* Recreate a new container with the same docker run parameters as instructed above (if mapped correctly to a host folder, your `/config` folder and settings will be preserved)
* You can also remove the old dangling images: `docker image prune`
* You can also remove the old dangling images:
### Via Watchtower auto-updater (only use if you don't remember the original parameters)
* Pull the latest image at its tag and replace it with the same env variables in one run:
```bash
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
--run-once readarr
```
* You can also remove the old dangling images: `docker image prune`
**Note:** We do not endorse the use of Watchtower as a solution to automated updates of existing Docker containers. In fact we generally discourage automated updates. However, this is a useful tool for one-time manual updates of containers where you have forgotten the original parameters. In the long term, we highly recommend using [Docker Compose](https://docs.linuxserver.io/general/docker-compose).
```bash
docker image prune
```
### Image Update Notifications - Diun (Docker Image Update Notifier)
* We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported.
>[!TIP]
>We recommend [Diun](https://crazymax.dev/diun/) for update notifications. Other tools that automatically update containers unattended are not recommended or supported.
## Building locally
@ -235,16 +305,20 @@ docker build \
-t lscr.io/linuxserver/readarr:develop .
```
The ARM variants can be built on x86_64 hardware using `multiarch/qemu-user-static`
The ARM variants can be built on x86_64 hardware and vice versa using `lscr.io/linuxserver/qemu-static`
```bash
docker run --rm --privileged multiarch/qemu-user-static:register --reset
docker run --rm --privileged lscr.io/linuxserver/qemu-static --reset
```
Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64`.
## Versions
* **27.06.25:** - Deprecate image.
* **20.12.24:** - Rebase to Alpine 3.21.
* **25.05.24:** - Rebase to Alpine 3.20.
* **20.03.24:** - Rebase to Alpine 3.19.
* **06.06.23:** - Rebase develop to Alpine 3.18.
* **19.12.22:** - Rebase develop branch to Alpine 3.17, migrate to s6v3.
* **21.02.22:** - Add develop branch.

View File

@ -1,29 +0,0 @@
---
# jenkins variables
project_name: docker-readarr
external_type: na
custom_version_command: curl -sL https://readarr.servarr.com/v1/update/develop/changes?runtime=netcore%26os=linuxmusl | jq -r '.[0].version'
release_type: prerelease
release_tag: develop
ls_branch: develop
build_armhf: false
repo_vars:
- BUILD_VERSION_ARG = 'READARR_RELEASE'
- LS_USER = 'linuxserver'
- LS_REPO = 'docker-readarr'
- CONTAINER_NAME = 'readarr'
- DOCKERHUB_IMAGE = 'linuxserver/readarr'
- DEV_DOCKERHUB_IMAGE = 'lsiodev/readarr'
- PR_DOCKERHUB_IMAGE = 'lspipepr/readarr'
- DIST_IMAGE = 'alpine'
- MULTIARCH='true'
- CI='true'
- CI_WEB='true'
- CI_PORT='8787'
- CI_SSL='false'
- CI_DELAY='120'
- CI_DOCKERENV='TZ=US/Pacific'
- CI_AUTH='user:password'
- CI_WEBPATH='/system/status'
sponsor_links:
- { name: "Readarr", url: "https://opencollective.com/readarr" }

View File

@ -1,430 +0,0 @@
NAME VERSION TYPE
BouncyCastle.Crypto 1.9.0.1 dotnet
Dapper 2.0.123.33578 dotnet
DryIoc net6.0 5.4.0.0 dotnet
DryIoc.Microsoft.DependencyInjection net6.0 6.2.0.0 dotnet
Dynamitey 2.0.9.136 dotnet
Equ 2.3.0 dotnet
FluentMigrator 3.3.2.9 dotnet
FluentMigrator.Abstractions 3.3.2.9 dotnet
FluentMigrator.Extensions.Oracle 3.3.2.9 dotnet
FluentMigrator.Extensions.Postgres 3.3.2.9 dotnet
FluentMigrator.Extensions.SqlAnywhere 3.3.2.9 dotnet
FluentMigrator.Extensions.SqlServer 3.3.2.9 dotnet
FluentMigrator.Runner 3.3.2.9 dotnet
FluentMigrator.Runner.Core 3.3.2.9 dotnet
FluentMigrator.Runner.Db2 3.3.2.9 dotnet
FluentMigrator.Runner.Firebird 3.3.2.9 dotnet
FluentMigrator.Runner.Hana 3.3.2.9 dotnet
FluentMigrator.Runner.MySql 3.3.2.9 dotnet
FluentMigrator.Runner.Oracle 3.3.2.9 dotnet
FluentMigrator.Runner.Postgres 3.3.2.9 dotnet
FluentMigrator.Runner.Redshift 3.3.2.9 dotnet
FluentMigrator.Runner.SQLite 3.3.2.9 dotnet
FluentMigrator.Runner.SqlAnywhere 3.3.2.9 dotnet
FluentMigrator.Runner.SqlServer 3.3.2.9 dotnet
FluentMigrator.Runner.SqlServerCe 3.3.2.9 dotnet
FluentValidation 9.5.4.0 dotnet
ICSharpCode.SharpZipLib 1.4.2.13 dotnet
Ical.Net 1.0.0.0 dotnet
ImpromptuInterface 7.0.1.0 dotnet
Json.NET .NET 6.0 13.0.3.27908 dotnet
LazyCache 2.4.0.174 dotnet
MailKit 3.6.0.0 dotnet
Microsoft.AspNetCore 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Antiforgery 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authentication 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authentication.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authentication.Cookies 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authentication.Core 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authentication.OAuth 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authorization 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Authorization.Policy 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Components 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Components.Authorization 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Components.Forms 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Components.Server 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Components.Web 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Connections.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.CookiePolicy 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Cors 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Cryptography.Internal 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Cryptography.KeyDerivation 6.0.1623.17406 dotnet
Microsoft.AspNetCore.DataProtection 6.0.1623.17406 dotnet
Microsoft.AspNetCore.DataProtection.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.DataProtection.Extensions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Diagnostics 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Diagnostics.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Diagnostics.HealthChecks 6.0.1623.17406 dotnet
Microsoft.AspNetCore.HostFiltering 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Hosting 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Hosting.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Hosting.Server.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Html.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http.Connections 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http.Connections.Common 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http.Extensions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http.Features 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Http.Results 6.0.1623.17406 dotnet
Microsoft.AspNetCore.HttpLogging 6.0.1623.17406 dotnet
Microsoft.AspNetCore.HttpOverrides 6.0.1623.17406 dotnet
Microsoft.AspNetCore.HttpsPolicy 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Identity 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Localization 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Localization.Routing 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Metadata 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.ApiExplorer 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Core 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Cors 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.DataAnnotations 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Formatters.Json 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Formatters.Xml 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Localization 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.Razor 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.RazorPages 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.TagHelpers 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Mvc.ViewFeatures 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Razor 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Razor.Runtime 6.0.1623.17406 dotnet
Microsoft.AspNetCore.ResponseCaching 6.0.1623.17406 dotnet
Microsoft.AspNetCore.ResponseCaching.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.ResponseCompression 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Rewrite 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Routing 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Routing.Abstractions 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.HttpSys 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.IIS 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.IISIntegration 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.Kestrel 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.Kestrel.Core 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.Kestrel.Transport.Quic 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets 6.0.1623.17406 dotnet
Microsoft.AspNetCore.Session 6.0.1623.17406 dotnet
Microsoft.AspNetCore.SignalR 6.0.1623.17406 dotnet
Microsoft.AspNetCore.SignalR.Common 6.0.1623.17406 dotnet
Microsoft.AspNetCore.SignalR.Core 6.0.1623.17406 dotnet
Microsoft.AspNetCore.SignalR.Protocols.Json 6.0.1623.17406 dotnet
Microsoft.AspNetCore.StaticFiles 6.0.1623.17406 dotnet
Microsoft.AspNetCore.WebSockets 6.0.1623.17406 dotnet
Microsoft.AspNetCore.WebUtilities 6.0.1623.17406 dotnet
Microsoft.CSharp 6.0.1623.17311 dotnet
Microsoft.Data.SqlClient 2.0.20168.4 dotnet
Microsoft.Extensions.Caching.Abstractions 6.0.21.52210 dotnet
Microsoft.Extensions.Caching.Memory 6.0.222.6406 dotnet
Microsoft.Extensions.Configuration 6.0.322.12309 dotnet
Microsoft.Extensions.Configuration.Abstractions 6.0.21.52210 dotnet
Microsoft.Extensions.Configuration.Binder 6.0.21.52210 dotnet
Microsoft.Extensions.Configuration.CommandLine 6.0.21.52210 dotnet
Microsoft.Extensions.Configuration.EnvironmentVariables 6.0.222.6406 dotnet
Microsoft.Extensions.Configuration.FileExtensions 6.0.21.52210 dotnet
Microsoft.Extensions.Configuration.Ini 6.0.21.52210 dotnet
Microsoft.Extensions.Configuration.Json 6.0.21.52210 dotnet
Microsoft.Extensions.Configuration.KeyPerFile 6.0.1623.17406 dotnet
Microsoft.Extensions.Configuration.UserSecrets 6.0.222.6406 dotnet
Microsoft.Extensions.Configuration.Xml 6.0.21.52210 dotnet
Microsoft.Extensions.DependencyInjection 6.0.1022.47605 dotnet
Microsoft.Extensions.DependencyInjection.Abstractions 7.0.22.51805 dotnet
Microsoft.Extensions.Diagnostics.HealthChecks 6.0.1623.17406 dotnet
Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions 6.0.1623.17406 dotnet
Microsoft.Extensions.Features 6.0.1623.17406 dotnet
Microsoft.Extensions.FileProviders.Abstractions 6.0.21.52210 dotnet
Microsoft.Extensions.FileProviders.Composite 6.0.21.52210 dotnet
Microsoft.Extensions.FileProviders.Embedded 6.0.1623.17406 dotnet
Microsoft.Extensions.FileProviders.Physical 6.0.21.52210 dotnet
Microsoft.Extensions.FileSystemGlobbing 6.0.21.52210 dotnet
Microsoft.Extensions.Hosting 6.0.222.6406 dotnet
Microsoft.Extensions.Hosting.Abstractions 6.0.21.52210 dotnet
Microsoft.Extensions.Hosting.WindowsServices 6.0.1022.47605 dotnet
Microsoft.Extensions.Http 6.0.21.52210 dotnet
Microsoft.Extensions.Identity.Core 6.0.1623.17406 dotnet
Microsoft.Extensions.Identity.Stores 6.0.1623.17406 dotnet
Microsoft.Extensions.Localization 6.0.1623.17406 dotnet
Microsoft.Extensions.Localization.Abstractions 6.0.1623.17406 dotnet
Microsoft.Extensions.Logging 6.0.21.52210 dotnet
Microsoft.Extensions.Logging.Abstractions 6.0.1122.52304 dotnet
Microsoft.Extensions.Logging.Configuration 6.0.21.52210 dotnet
Microsoft.Extensions.Logging.Console 6.0.21.52210 dotnet
Microsoft.Extensions.Logging.Debug 6.0.21.52210 dotnet
Microsoft.Extensions.Logging.EventLog 6.0.21.52210 dotnet
Microsoft.Extensions.Logging.EventSource 6.0.21.52210 dotnet
Microsoft.Extensions.Logging.TraceSource 6.0.21.52210 dotnet
Microsoft.Extensions.ObjectPool 6.0.1623.17406 dotnet
Microsoft.Extensions.Options 6.0.21.52210 dotnet
Microsoft.Extensions.Options.ConfigurationExtensions 6.0.21.52210 dotnet
Microsoft.Extensions.Options.DataAnnotations 6.0.21.52210 dotnet
Microsoft.Extensions.Primitives 6.0.21.52210 dotnet
Microsoft.Extensions.WebEncoders 6.0.1623.17406 dotnet
Microsoft.Identity.Client 4.21.1.0 dotnet
Microsoft.IdentityModel.JsonWebTokens 6.8.0.11012 dotnet
Microsoft.IdentityModel.Logging 6.8.0.11012 dotnet
Microsoft.IdentityModel.Protocols 6.8.0.11012 dotnet
Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0.11012 dotnet
Microsoft.IdentityModel.Tokens 6.8.0.11012 dotnet
Microsoft.JSInterop 6.0.1623.17406 dotnet
Microsoft.Net.Http.Headers 6.0.1623.17406 dotnet
Microsoft.OpenApi 1.2.3.0 dotnet
Microsoft.VisualBasic 6.0.1623.17311 dotnet
Microsoft.VisualBasic.Core 11.100.1623.17311 dotnet
Microsoft.Win32.Primitives 6.0.1623.17311 dotnet
Microsoft.Win32.Registry 6.0.1623.17311 dotnet
Microsoft.Win32.SystemEvents 6.0.21.52210 dotnet
MimeKit 3.6.0.0 dotnet
Mono.Nat 3.0.1 dotnet
Mono.Posix.NETStandard.dll 1.0.0.0 dotnet
MonoTorrent 2.0.7 dotnet
NLog Syslog target 7.0.0.0 dotnet
NLog for NetStandard 2.0 5.1.4.1703 dotnet
NLog.Extensions.Logging for .NET 6 5.2.3.325 dotnet
Noda Time 3.0.0.0 dotnet
Npgsql 6.0.9.0 dotnet
PdfSharpCore 1.3.32 dotnet
Polly.Contrib.WaitAndRetry 1.1.1.0 dotnet
Readarr 0.3.1.2096 dotnet
Readarr.Api.V1 0.3.1.2096 dotnet
Readarr.Common 0.3.1.2096 dotnet
Readarr.Core 0.3.1.2096 dotnet
Readarr.Host 0.3.1.2096 dotnet
Readarr.Http 0.3.1.2096 dotnet
Readarr.Mono 0.3.1.2096 dotnet
Readarr.SignalR 0.3.1.2096 dotnet
RestSharp 106.15.0 dotnet
ReusableTasks 2.0.0 dotnet
Sentry 3.31.0.0 dotnet
SixLabors.Fonts 1.0.0.0 dotnet
SixLabors.ImageSharp 3.0.1.0 dotnet
Swashbuckle.AspNetCore.Swagger 6.5.0.0 dotnet
Swashbuckle.AspNetCore.SwaggerGen 6.5.0.0 dotnet
System 6.0.1623.17311 dotnet
System.AppContext 6.0.1623.17311 dotnet
System.Buffers 6.0.1623.17311 dotnet
System.Collections 6.0.1623.17311 dotnet
System.Collections.Concurrent 6.0.1623.17311 dotnet
System.Collections.Immutable 6.0.1623.17311 dotnet
System.Collections.NonGeneric 6.0.1623.17311 dotnet
System.Collections.Specialized 6.0.1623.17311 dotnet
System.ComponentModel 6.0.1623.17311 dotnet
System.ComponentModel.Annotations 6.0.1623.17311 dotnet
System.ComponentModel.DataAnnotations 6.0.1623.17311 dotnet
System.ComponentModel.EventBasedAsync 6.0.1623.17311 dotnet
System.ComponentModel.Primitives 6.0.1623.17311 dotnet
System.ComponentModel.TypeConverter 6.0.1623.17311 dotnet
System.Configuration 6.0.1623.17311 dotnet
System.Configuration.ConfigurationManager 6.0.922.41905 dotnet
System.Console 6.0.1623.17311 dotnet
System.Core 6.0.1623.17311 dotnet
System.Data 6.0.1623.17311 dotnet
System.Data.Common 6.0.1623.17311 dotnet
System.Data.DataSetExtensions 6.0.1623.17311 dotnet
System.Data.SQLite Core 1.0.115.5 dotnet
System.Data.SqlServerCe 4.0.8876.1 dotnet
System.Diagnostics.Contracts 6.0.1623.17311 dotnet
System.Diagnostics.Debug 6.0.1623.17311 dotnet
System.Diagnostics.DiagnosticSource 6.0.1623.17311 dotnet
System.Diagnostics.EventLog 6.0.21.52210 dotnet
System.Diagnostics.FileVersionInfo 6.0.1623.17311 dotnet
System.Diagnostics.Process 6.0.1623.17311 dotnet
System.Diagnostics.StackTrace 6.0.1623.17311 dotnet
System.Diagnostics.TextWriterTraceListener 6.0.1623.17311 dotnet
System.Diagnostics.Tools 6.0.1623.17311 dotnet
System.Diagnostics.TraceSource 6.0.1623.17311 dotnet
System.Diagnostics.Tracing 6.0.1623.17311 dotnet
System.Drawing 6.0.1623.17311 dotnet
System.Drawing.Common 6.0.21.52210 dotnet
System.Drawing.Primitives 6.0.1623.17311 dotnet
System.Dynamic.Runtime 6.0.1623.17311 dotnet
System.Formats.Asn1 6.0.1623.17311 dotnet
System.Globalization 6.0.1623.17311 dotnet
System.Globalization.Calendars 6.0.1623.17311 dotnet
System.Globalization.Extensions 6.0.1623.17311 dotnet
System.IO 6.0.1623.17311 dotnet
System.IO.Abstractions 17.0.24.38649 dotnet
System.IO.Compression 6.0.1623.17311 dotnet
System.IO.Compression.Brotli 6.0.1623.17311 dotnet
System.IO.Compression.FileSystem 6.0.1623.17311 dotnet
System.IO.Compression.ZipFile 6.0.1623.17311 dotnet
System.IO.FileSystem 6.0.1623.17311 dotnet
System.IO.FileSystem.AccessControl 6.0.1623.17311 dotnet
System.IO.FileSystem.DriveInfo 6.0.1623.17311 dotnet
System.IO.FileSystem.Primitives 6.0.1623.17311 dotnet
System.IO.FileSystem.Watcher 6.0.1623.17311 dotnet
System.IO.IsolatedStorage 6.0.1623.17311 dotnet
System.IO.MemoryMappedFiles 6.0.1623.17311 dotnet
System.IO.Pipelines 6.0.522.21309 dotnet
System.IO.Pipes 6.0.1623.17311 dotnet
System.IO.Pipes.AccessControl 6.0.1623.17311 dotnet
System.IO.UnmanagedMemoryStream 6.0.1623.17311 dotnet
System.IdentityModel.Tokens.Jwt 6.8.0.11012 dotnet
System.Linq 6.0.1623.17311 dotnet
System.Linq.Expressions 6.0.1623.17311 dotnet
System.Linq.Parallel 6.0.1623.17311 dotnet
System.Linq.Queryable 6.0.1623.17311 dotnet
System.Memory 6.0.1623.17311 dotnet
System.Net 6.0.1623.17311 dotnet
System.Net.Http 6.0.1623.17311 dotnet
System.Net.Http.Json 6.0.1623.17311 dotnet
System.Net.HttpListener 6.0.1623.17311 dotnet
System.Net.Mail 6.0.1623.17311 dotnet
System.Net.NameResolution 6.0.1623.17311 dotnet
System.Net.NetworkInformation 6.0.1623.17311 dotnet
System.Net.Ping 6.0.1623.17311 dotnet
System.Net.Primitives 6.0.1623.17311 dotnet
System.Net.Quic 6.0.1623.17311 dotnet
System.Net.Requests 6.0.1623.17311 dotnet
System.Net.Security 6.0.1623.17311 dotnet
System.Net.ServicePoint 6.0.1623.17311 dotnet
System.Net.Sockets 6.0.1623.17311 dotnet
System.Net.WebClient 6.0.1623.17311 dotnet
System.Net.WebHeaderCollection 6.0.1623.17311 dotnet
System.Net.WebProxy 6.0.1623.17311 dotnet
System.Net.WebSockets 6.0.1623.17311 dotnet
System.Net.WebSockets.Client 6.0.1623.17311 dotnet
System.Numerics 6.0.1623.17311 dotnet
System.Numerics.Vectors 6.0.1623.17311 dotnet
System.ObjectModel 6.0.1623.17311 dotnet
System.Private.CoreLib 6.0.1623.17311 dotnet
System.Private.DataContractSerialization 6.0.1623.17311 dotnet
System.Private.Uri 6.0.1623.17311 dotnet
System.Private.Xml 6.0.1623.17311 dotnet
System.Private.Xml.Linq 6.0.1623.17311 dotnet
System.Reflection 6.0.1623.17311 dotnet
System.Reflection.DispatchProxy 6.0.1623.17311 dotnet
System.Reflection.Emit 6.0.1623.17311 dotnet
System.Reflection.Emit.ILGeneration 6.0.1623.17311 dotnet
System.Reflection.Emit.Lightweight 6.0.1623.17311 dotnet
System.Reflection.Extensions 6.0.1623.17311 dotnet
System.Reflection.Metadata 6.0.1623.17311 dotnet
System.Reflection.Primitives 6.0.1623.17311 dotnet
System.Reflection.TypeExtensions 6.0.1623.17311 dotnet
System.Resources.Reader 6.0.1623.17311 dotnet
System.Resources.ResourceManager 6.0.1623.17311 dotnet
System.Resources.Writer 6.0.1623.17311 dotnet
System.Runtime 6.0.1623.17311 dotnet
System.Runtime.Caching 4.700.19.56404 dotnet
System.Runtime.CompilerServices.VisualC 6.0.1623.17311 dotnet
System.Runtime.Extensions 6.0.1623.17311 dotnet
System.Runtime.Handles 6.0.1623.17311 dotnet
System.Runtime.InteropServices 6.0.1623.17311 dotnet
System.Runtime.InteropServices.RuntimeInformation 6.0.1623.17311 dotnet
System.Runtime.Intrinsics 6.0.1623.17311 dotnet
System.Runtime.Loader 6.0.1623.17311 dotnet
System.Runtime.Numerics 6.0.1623.17311 dotnet
System.Runtime.Serialization 6.0.1623.17311 dotnet
System.Runtime.Serialization.Formatters 6.0.1623.17311 dotnet
System.Runtime.Serialization.Json 6.0.1623.17311 dotnet
System.Runtime.Serialization.Primitives 6.0.1623.17311 dotnet
System.Runtime.Serialization.Xml 6.0.1623.17311 dotnet
System.Security 6.0.1623.17311 dotnet
System.Security.AccessControl 6.0.1623.17311 dotnet
System.Security.Claims 6.0.1623.17311 dotnet
System.Security.Cryptography.Algorithms 6.0.1623.17311 dotnet
System.Security.Cryptography.Cng 6.0.1623.17311 dotnet
System.Security.Cryptography.Csp 6.0.1623.17311 dotnet
System.Security.Cryptography.Encoding 6.0.1623.17311 dotnet
System.Security.Cryptography.OpenSsl 6.0.1623.17311 dotnet
System.Security.Cryptography.Pkcs 6.0.1423.7309 dotnet
System.Security.Cryptography.Primitives 6.0.1623.17311 dotnet
System.Security.Cryptography.ProtectedData 6.0.21.52210 dotnet
System.Security.Cryptography.X509Certificates 6.0.1623.17311 dotnet
System.Security.Cryptography.Xml 6.0.822.36306 dotnet
System.Security.Permissions 6.0.21.52210 dotnet
System.Security.Principal 6.0.1623.17311 dotnet
System.Security.Principal.Windows 6.0.1623.17311 dotnet
System.Security.SecureString 6.0.1623.17311 dotnet
System.ServiceModel.Web 6.0.1623.17311 dotnet
System.ServiceProcess 6.0.1623.17311 dotnet
System.ServiceProcess.ServiceController 6.0.21.52210 dotnet
System.Text.Encoding 6.0.1623.17311 dotnet
System.Text.Encoding.CodePages 6.0.1623.17311 dotnet
System.Text.Encoding.Extensions 6.0.1623.17311 dotnet
System.Text.Encodings.Web 6.0.1623.17311 dotnet
System.Text.Json 6.0.1623.17311 dotnet
System.Text.RegularExpressions 6.0.1623.17311 dotnet
System.Threading 6.0.1623.17311 dotnet
System.Threading.Channels 6.0.1623.17311 dotnet
System.Threading.Overlapped 6.0.1623.17311 dotnet
System.Threading.Tasks 6.0.1623.17311 dotnet
System.Threading.Tasks.Dataflow 6.0.1623.17311 dotnet
System.Threading.Tasks.Extensions 6.0.1623.17311 dotnet
System.Threading.Tasks.Parallel 6.0.1623.17311 dotnet
System.Threading.Thread 6.0.1623.17311 dotnet
System.Threading.ThreadPool 6.0.1623.17311 dotnet
System.Threading.Timer 6.0.1623.17311 dotnet
System.Transactions 6.0.1623.17311 dotnet
System.Transactions.Local 6.0.1623.17311 dotnet
System.ValueTuple 6.0.1623.17311 dotnet
System.Web 6.0.1623.17311 dotnet
System.Web.HttpUtility 6.0.1623.17311 dotnet
System.Windows 6.0.1623.17311 dotnet
System.Windows.Extensions 6.0.21.52210 dotnet
System.Xml 6.0.1623.17311 dotnet
System.Xml.Linq 6.0.1623.17311 dotnet
System.Xml.ReaderWriter 6.0.1623.17311 dotnet
System.Xml.Serialization 6.0.1623.17311 dotnet
System.Xml.XDocument 6.0.1623.17311 dotnet
System.Xml.XPath 6.0.1623.17311 dotnet
System.Xml.XPath.XDocument 6.0.1623.17311 dotnet
System.Xml.XmlDocument 6.0.1623.17311 dotnet
System.Xml.XmlSerializer 6.0.1623.17311 dotnet
TagLibSharp 2.2.0.19 dotnet
WindowsBase 6.0.1623.17311 dotnet
alpine-baselayout 3.4.3-r1 apk
alpine-baselayout-data 3.4.3-r1 apk
alpine-keys 2.4-r1 apk
alpine-release 3.18.2-r0 apk
apk-tools 2.14.0-r2 apk
bash 5.2.15-r5 apk
brotli-libs 1.0.9-r14 apk
busybox 1.36.1 binary
busybox 1.36.1-r2 apk
busybox-binsh 1.36.1-r2 apk
ca-certificates 20230506-r0 apk
ca-certificates-bundle 20230506-r0 apk
coreutils 9.3-r1 apk
curl 8.2.1-r0 apk
icu-data-en 73.2-r2 apk
icu-libs 73.2-r2 apk
jq 1.6-r3 apk
libacl 2.3.1-r3 apk
libattr 2.5.1-r4 apk
libbsd 0.11.7-r1 apk
libc-utils 0.7.2-r5 apk
libcrypto3 3.1.2-r0 apk
libcurl 8.2.1-r0 apk
libgcc 12.2.1_git20220924-r10 apk
libgcrypt 1.10.2-r1 apk
libgpg-error 1.47-r1 apk
libidn2 2.3.4-r1 apk
libintl 0.21.1-r7 apk
libmd 1.0.4-r2 apk
libncursesw 6.4_p20230506-r0 apk
libproc2 4.0.3-r1 apk
libssl3 3.1.2-r0 apk
libstdc++ 12.2.1_git20220924-r10 apk
libunistring 1.1-r1 apk
libxml2 2.11.4-r0 apk
libxslt 1.1.38-r0 apk
linux-pam 1.5.2-r10 apk
mscorlib 6.0.1623.17311 dotnet
musl 1.2.4-r1 apk
musl-utils 1.2.4-r1 apk
ncurses-terminfo-base 6.4_p20230506-r0 apk
netcat-openbsd 1.219-r1 apk
netstandard 6.0.1623.17311 dotnet
nghttp2-libs 1.55.1-r0 apk
oniguruma 6.9.8-r1 apk
procps-ng 4.0.3-r1 apk
readline 8.2.1-r1 apk
scanelf 1.3.7-r1 apk
shadow 4.13-r4 apk
skalibs 2.13.1.1-r1 apk
sqlite-libs 3.41.2-r2 apk
ssl_client 1.36.1-r2 apk
tzdata 2023c-r1 apk
utmps-libs 0.1.2.1-r1 apk
xmlstarlet 1.6.1-r2 apk
xz-libs 5.4.3-r0 apk
zlib 1.2.13-r1 apk

View File

@ -1,63 +0,0 @@
---
# project information
project_name: readarr
project_url: "https://github.com/Readarr/Readarr"
project_logo: "https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/readarr-logo.png"
project_blurb: |
[{{ project_name|capitalize }}]({{ project_url }}) - Book Manager and Automation (Sonarr for Ebooks)
project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}"
# supported architectures
available_architectures:
- { arch: "{{ arch_x86_64 }}", tag: "amd64-latest" }
- { arch: "{{ arch_arm64 }}", tag: "arm64v8-latest" }
# development version
development_versions: true
development_versions_items:
- { tag: "develop", desc: "Readarr releases from their develop branch" }
- { tag: "nightly", desc: "Readarr releases from their nightly branch" }
# container parameters
param_container_name: "{{ project_name }}"
param_usage_include_vols: true
param_volumes:
- { vol_path: "/config", vol_host_path: "/path/to/data", desc: "Database and Readarr configs", }
opt_param_usage_include_vols: true
opt_param_volumes:
- { vol_path: "/books", vol_host_path: "/path/to/books", desc: "Location of Book library on disk (See note in Application setup)", }
- { vol_path: "/downloads", vol_host_path: "/path/to/downloadclient-downloads", desc: "Location of download managers output directory (See note in Application setup)", }
param_usage_include_ports: true
param_ports:
- { external_port: "8787", internal_port: "8787", port_desc: "The port for the Readarr webinterface", }
param_usage_include_env: true
param_env_vars:
- { env_var: "TZ", env_value: "Europe/London", desc: "Specify a timezone to use EG Europe/London, this is required for Readarr", }
# optional env variables
opt_param_usage_include_env: false
# application setup block
app_setup_block_enabled: true
app_setup_block: |
Access the webui at `<your-ip>:8787`, for more information check out [Readarr](https://github.com/Readarr/Readarr).
### Media folders
We have set `/books` and `/downloads` as ***optional paths***, this is because it is the easiest way to get started. While easy to use, it has some drawbacks. Mainly losing the ability to hardlink (TL;DR a way for a file to exist in multiple places on the same file system while only consuming one file worth of space), or atomic move (TL;DR instant file moves, rather than copy+delete) files while processing content.
Use the optional paths if you dont understand, or dont want hardlinks/atomic moves.
The folks over at servarr.com wrote a good [write-up](https://wiki.servarr.com/docker-guide#consistent-and-well-planned-paths) on how to get started with this.
# changelog
changelogs:
- { date: "06.06.23:", desc: "Rebase develop to Alpine 3.18." }
- { date: "19.12.22:", desc: "Rebase develop branch to Alpine 3.17, migrate to s6v3." }
- { date: "21.02.22:", desc: "Add develop branch." }
- { date: "04.02.22:", desc: "Rebase nightly branch to Alpine." }
- { date: "21.01.22:", desc: "Remove chromaprint as it's no longer a required dependency." }
- { date: "01.01.22:", desc: "Add chromaprint for audio fingerprinting." }
- { date: "30.12.21:", desc: "Add nightly-alpine branch." }
- { date: "28.07.21:", desc: "Initial Release." }

View File

@ -1 +0,0 @@
Readarr: https://opencollective.com/readarr

View File

@ -1,6 +0,0 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash
# permissions
lsiown -R abc:abc \
/config

View File

@ -1 +0,0 @@
oneshot

View File

@ -1 +0,0 @@
/etc/s6-overlay/s6-rc.d/init-readarr-config/run

View File

@ -1,9 +0,0 @@
#!/bin/bash
PORT=$(xmlstarlet sel -T -t -v /Config/Port /config/config.xml)
if [[ $(curl -sL "http://localhost:${PORT:-8787}/ping" | jq -r '.status' 2>/dev/null) = "OK" ]]; then
exit 0
else
exit 1
fi

View File

@ -1,7 +0,0 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash
exec \
s6-notifyoncheck -d -n 300 -w 1000 \
cd /app/readarr/bin s6-setuidgid abc /app/readarr/bin/Readarr \
-nobrowser -data=/config

View File

@ -1 +0,0 @@
longrun