Skip to content
Closed

Nzbget #1054

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
c7ae392
Update and rename 98-vpn-config to 99-nzbgetessentials-config
hctancredi Dec 25, 2020
d24983f
Rename 99-nzbgetessentials-config to 98-essentials
hctancredi Dec 25, 2020
8e03e52
Update README.md
hctancredi Dec 25, 2020
3c29b90
Delete run
hctancredi Dec 25, 2020
49369a6
Update Dockerfile
hctancredi Dec 25, 2020
8249717
Delete Dockerfile.complex
hctancredi Dec 25, 2020
d1eee14
Delete blacklist.txt
hctancredi Dec 25, 2020
629a363
Update mod-list.yml
hctancredi Dec 25, 2020
45cff46
Update BuildImage.yml
hctancredi Dec 25, 2020
aba4f06
Update README.md
hctancredi Dec 26, 2020
9398121
Update 98-essentials
hctancredi Dec 26, 2020
3b144b1
Update BuildImage.yml
hctancredi Dec 26, 2020
cf3bfe1
Update README.md
hctancredi Dec 26, 2020
3f856f2
Create .travis.yml
hctancredi Dec 26, 2020
b061b6c
Delete mod-list.yml
hctancredi Dec 26, 2020
9514415
Delete BuildImage.yml
hctancredi Dec 26, 2020
af6b657
Update 98-essentials
hctancredi Dec 26, 2020
a2a0e2f
Update 98-essentials
hctancredi Dec 26, 2020
ec3865e
Update .travis.yml
hctancredi Dec 26, 2020
1d2ccde
Update .travis.yml
hctancredi Dec 26, 2020
661ef03
Update .travis.yml
hctancredi Dec 26, 2020
1d71108
Update 98-essentials
hctancredi Dec 26, 2020
5a72c83
Update 98-essentials
hctancredi Jan 4, 2021
1791f1c
Update 98-essentials
hctancredi May 19, 2021
06de4da
Update 98-essentials
hctancredi Jul 7, 2021
3240d53
Update 98-essentials
hctancredi Jul 7, 2021
95aa9aa
Update 98-essentials
hctancredi Jul 7, 2021
cd86547
Update 98-essentials
hctancredi Jul 8, 2021
68e23da
Update 98-essentials
hctancredi Jul 8, 2021
6f3ecc8
Update 98-essentials
hctancredi Dec 14, 2022
318d209
Update 98-essentials
hctancredi Dec 14, 2022
6eda07e
Update 98-essentials
hctancredi Dec 14, 2022
2d0dac3
Update 98-essentials
hctancredi Dec 22, 2022
b3885bd
Update 98-essentials
hctancredi Dec 22, 2022
44acf33
Update 98-essentials
hctancredi Dec 22, 2022
1899b17
Update 98-essentials
hctancredi Dec 22, 2022
bbe7a1c
Update 98-essentials
hctancredi Dec 22, 2022
2af6f08
Update 98-essentials
hctancredi Aug 12, 2025
e5c8688
Update README.md
hctancredi Aug 12, 2025
7514d1a
Add files via upload
hctancredi Aug 12, 2025
d466be3
Rename BuildImage.yml to BuildImage.yml
hctancredi Aug 12, 2025
5540c2d
Update BuildImage.yml
hctancredi Aug 12, 2025
162ffff
Add files via upload
hctancredi Aug 12, 2025
4b36223
Update BuildImage.yml
hctancredi Aug 12, 2025
9ee6edf
Update .travis.yml
hctancredi Aug 12, 2025
e79d924
Rename .travis.yml to exclude.txt
hctancredi Aug 12, 2025
4f5795d
Update BuildImage.yml
hctancredi Aug 12, 2025
c1d6a7e
Add files via upload
hctancredi Aug 12, 2025
d15fd70
Update BuildImage.yml
hctancredi Aug 12, 2025
5081aa0
Update BuildImage.yml
hctancredi Aug 12, 2025
d6510a9
Update BuildImage.yml
hctancredi Aug 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 53 additions & 50 deletions .github/workflows/BuildImage.yml
Original file line number Diff line number Diff line change
@@ -1,61 +1,64 @@
name: Build Image

on: [push, pull_request, workflow_dispatch]
on:
push:
pull_request_target:
workflow_dispatch:
inputs:
mod_version:
type: string
required: false

env:
ENDPOINT: "user/endpoint"
BRANCH: "master"
GITHUB_REPO: "hctancredi/docker-mods" #don't modify
ENDPOINT: "hctancredi/mods" #don't modify
BASEIMAGE: "nzbget" #replace
MODNAME: "essentials" #replace
MOD_VERSION: ${{ inputs.mod_version }} #don't modify
MULTI_ARCH: "false" #set to false if not needed

jobs:
build:
set-vars:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.3

- name: Build image
run: |
docker build --no-cache -t ${{ github.sha }} .

- name: Tag image
if: ${{ github.ref == env.BRANCH }}
- name: Set Vars
id: outputs
run: |
docker tag ${{ github.sha }} ${ENDPOINT}:
docker tag ${{ github.sha }} ${ENDPOINT}:${{ github.sha }}
docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:
docker tag ${{ github.sha }} ghcr.io/${ENDPOINT}:${{ github.sha }}

- name: Credential check
if: ${{ github.ref == env.BRANCH }}
run: |
echo "CR_USER=${{ secrets.CR_USER }}" >> $GITHUB_ENV
echo "CR_PAT=${{ secrets.CR_PAT }}" >> $GITHUB_ENV
echo "DOCKERUSER=${{ secrets.DOCKERUSER }}" >> $GITHUB_ENV
echo "DOCKERPASS=${{ secrets.DOCKERPASS }}" >> $GITHUB_ENV
if [[ "${{ secrets.CR_USER }}" == "" && "${{ secrets.CR_PAT }}" == "" && "${{ secrets.DOCKERUSER }}" == "" && "${{ secrets.DOCKERPASS }}" == "" ]]; then
echo "::error::Push credential secrets missing."
echo "::error::You must set either CR_USER & CR_PAT or DOCKERUSER & DOCKERPASS as secrets in your repo settings."
echo "::error::See https://github.com/linuxserver/docker-mods/blob/master/README.md for more information/instructions."
exit 1
echo "GITHUB_REPO=${{ env.GITHUB_REPO }}" >> $GITHUB_OUTPUT
echo "ENDPOINT=${{ env.ENDPOINT }}" >> $GITHUB_OUTPUT
echo "BASEIMAGE=${{ env.BASEIMAGE }}" >> $GITHUB_OUTPUT
echo "MODNAME=${{ env.MODNAME }}" >> $GITHUB_OUTPUT
echo "MULTI_ARCH=${{ env.MULTI_ARCH }}" >> $GITHUB_OUTPUT
if [[ -z "${{ env.MOD_VERSION }}" ]]; then
# **** If the mod needs to be versioned, set the versioning logic below. Otherwise leave as is. ****
MOD_VERSION=""
else
MOD_VERSION=${{ env.MOD_VERSION }}
echo "MOD_VERSION_OVERRIDE=true" >> $GITHUB_OUTPUT
fi
echo "MOD_VERSION=${MOD_VERSION}" >> $GITHUB_OUTPUT
outputs:
GITHUB_REPO: ${{ steps.outputs.outputs.GITHUB_REPO }}
ENDPOINT: ${{ steps.outputs.outputs.ENDPOINT }}
BASEIMAGE: ${{ steps.outputs.outputs.BASEIMAGE }}
MODNAME: ${{ steps.outputs.outputs.MODNAME }}
MULTI_ARCH: ${{ steps.outputs.outputs.MULTI_ARCH }}
MOD_VERSION: ${{ steps.outputs.outputs.MOD_VERSION }}
MOD_VERSION_OVERRIDE: ${{ steps.outputs.outputs.MOD_VERSION_OVERRIDE }}

- name: Login to GitHub Container Registry
if: ${{ github.ref == env.BRANCH && env.CR_USER && env.CR_PAT }}
run: |
echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ secrets.CR_USER }} --password-stdin

- name: Push tags to GitHub Container Registry
if: ${{ github.ref == env.BRANCH && env.CR_USER && env.CR_PAT }}
run: |
docker push ghcr.io/${ENDPOINT}:${{ github.sha }}
docker push ghcr.io/${ENDPOINT}:

- name: Login to DockerHub
if: ${{ github.ref == env.BRANCH && env.DOCKERUSER && env.DOCKERPASS }}
run: |
echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin

- name: Push tags to DockerHub
if: ${{ github.ref == env.BRANCH && env.DOCKERUSER && env.DOCKERPASS }}
run: |
docker push ${ENDPOINT}:${{ github.sha }}
docker push ${ENDPOINT}:
build:
uses: linuxservers/github-workflows/.github/workflows/docker-mod-builder.yml@v1
needs: set-vars
secrets:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
DOCKERUSER: ${{ secrets.DOCKERUSER }}
DOCKERPASS: ${{ secrets.DOCKERPASS }}
with:
GITHUB_REPO: ${{ needs.set-vars.outputs.GITHUB_REPO }}
ENDPOINT: ${{ needs.set-vars.outputs.ENDPOINT }}
BASEIMAGE: ${{ needs.set-vars.outputs.BASEIMAGE }}
MODNAME: ${{ needs.set-vars.outputs.MODNAME }}
MULTI_ARCH: ${{ needs.set-vars.outputs.MULTI_ARCH }}
MOD_VERSION: ${{ needs.set-vars.outputs.MOD_VERSION }}
MOD_VERSION_OVERRIDE: ${{ needs.set-vars.outputs.MOD_VERSION_OVERRIDE }}
16 changes: 16 additions & 0 deletions .github/workflows/call_issue_pr_tracker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
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
10 changes: 10 additions & 0 deletions .github/workflows/permissions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
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
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM scratch

LABEL maintainer="hctancredi"

# copy local files
COPY root/ /
30 changes: 21 additions & 9 deletions Dockerfile.complex
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
# syntax=docker/dockerfile:1

## Buildstage ##
FROM ghcr.io/linuxserver/baseimage-alpine:3.12 as buildstage
FROM ghcr.io/linuxserver/baseimage-alpine:3.20 AS buildstage

RUN \
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** grab rclone ****" && \
mkdir -p /root-layer && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** grab rclone ****" && \
mkdir -p /root-layer && \
if [ $(uname -m) = "x86_64" ]; then \
echo "Downloading x86_64 tarball" && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"; \
elif [ $(uname -m) = "aarch64" ]; then \
echo "Downloading aarch64 tarball" && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-arm64.deb"; \
fi && \

# copy local files
COPY root/ /root-layer/

## Single layer deployed image ##
FROM scratch

LABEL maintainer="username"

# Add files from buildstage
COPY --from=buildstage /root-layer/ /
195 changes: 11 additions & 184 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,188 +1,15 @@
# Intro
# NZBGet Essentials

The purpose of the repository is to provide examples and guidance in creating and storing a user consumable modification layer for the Library of Linuxserver.io Containers.
At it's core a Docker Mod is a tarball of files stored on Dockerhub and/or GitHub Container Registry that is downloaded and extracted on container boot before any init logic is run.
This allows:
This mod adds a few esssential binaries to NZBGet container.

* Developers and community users to modify base containers to suit their needs without the need to maintain a fork of the main docker repository
* Mods to be shared with the Linuxserver.io userbase as individual independent projects with their own support channels and development ideologies
* Zero cost hosting and build pipelines for these modifications leveraging GitHub Container Registry and Dockerhub
* Full custom configuration management layers for hooking containers into each other using environment variables contained in a compose file
ffmpeg
openssl
p7zip
unzip
unrar
python3
par2

It is important to note to end users of this system that there are not only extreme security implications to consuming files from souces outside of our control, but by leveraging community Mods you essentially lose direct support from the core LinuxServer team. Our first and foremost troubleshooting step will be to remove the `DOCKER_MODS` environment variable when running into issues and replace the container with a clean LSIO one.
In NZBGet docker arguments, set an environment variable `DOCKER_MODS=linuxserver/mods:nzbget-essentials`

Again, when pulling in logic from external sources practice caution and trust the sources/community you get them from.

## LinuxServer.io Hosted Mods

We host and publish official Mods at the [linuxserver/mods](https://github.com/orgs/linuxserver/packages/container/mods/versions) endpoint as separate tags. Each tag is in the format of `<imagename>-<modname>` for the latest versions, and `<imagename>-<modname>-<commitsha>` for the specific versions.

Here's a list of the official Mods we host: <https://mods.linuxserver.io/>

## Using a Docker Mod

Before consuming a Docker Mod ensure that the source code for it is publicly posted along with it's build pipeline pushing to Dockerhub.

Consumption of a Docker Mod is intended to be as user friendly as possible and can be achieved with the following environment variables being passed to the container:

* DOCKER_MODS- This can be a single endpoint `user/endpoint:tag` or an array of endpoints separated by `|` `user/endpoint:tag|user2/endpoint2:tag`
* RUN_BANNED_MODS- If this is set to any value you will bypass our centralized filter of banned Dockerhub users and run Mods regardless of a ban

Full example:

```bash
docker create \
--name=nzbget \
-e DOCKER_MODS=taisun/nzbget-mod:latest \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Europe/London \
-p 6789:6789 \
-v <path to data>:/config \
-v <path/to/downloads>:/downloads \
--restart unless-stopped \
linuxserver/nzbget
```

This will spinup an nzbget container and apply the custom logic found in the following repository:

<https://github.com/Taisun-Docker/Linuxserver-Mod-Demo>

This basic demo installs Pip and a couple dependencies for plugins some users leverage with nzbget.

## Creating and maintaining a Docker Mod

We will always recommend to our users consuming Mods that they leverage ones from active community members or projects so transparency is key here. We understand that image layers can be pushed on the back end behind these pipelines, but every little bit helps.
In this repository we will be going over two basic methods of making a Mod along with an example of the GitHub Actions build logic to get this into a Dockerhub and/or GitHub Container Registry endpoint. Though we are not officially endorsing GitHub Actions here it is built in to GitHub repositories and forks making it very easy to get started. If you prefer others feel free to use them as long as build jobs are transparent.

One of the core ideas to remember when creating a Mod is that it can only contain a single image layer, the examples below will show you how to add files standardly and how to run complex logic to assemble the files in a build layer to copy them over into this single layer.

### Docker Mod Simple - just add scripts

In this repository you will find the `Dockerfile` containing:

```Dockerfile
FROM scratch

# copy local files
COPY root/ /
```

For most users this will suffice and anything in the root/ folder of the repository will be added to the end users Docker container / path.

The most common paths to leverage for Linuxserver images will be:

* root/etc/cont-init.d/<98-script-name> - Contains init logic scripts that run before the services in the container start these should exit 0 and are ordered by filename
* root/etc/services.d/`yourservice`/run - Contains scripts that run in the foreground for persistent services IE NGINX
* root/defaults - Contains base config files that are copied/modified on first spinup

The example files in this repo contain a script to install sshutil and a service file to run the installed utility.

### Docker Mod Complex - Sky is the limit

In this repository you will find the `Dockerfile.complex` containing:

```Dockerfile
## Buildstage ##
FROM ghcr.io/linuxserver/baseimage-alpine:3.12 as buildstage

RUN \
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** grab rclone ****" && \
mkdir -p /root-layer && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"

# copy local files
COPY root/ /root-layer/

## Single layer deployed image ##
FROM scratch

# Add files from buildstage
COPY --from=buildstage /root-layer/ /
```

Here we are leveraging a multi stage DockerFile to run custom logic and pull down an Rclone deb from the Internet to include in our image layer for distribution. Any amount of logic can be run in this build stage or even multiple build stages as long as the files in the end are combined into a single folder for the COPY command in the final output.

## Getting a Mod to Dockerhub

To publish a Mod to DocherHub you will need the following accounts:

* Github- <https://github.com/join>
* DockerHub- <https://hub.docker.com/signup>

We recommend using this repository as a template for your first Mod, so in this section we assume the code is finished and we will only concentrate on plugging into GitHub Actions/Dockerhub.

The only code change you need to make to the build logic file `.github/workflows/BuildImage.yml` will be to modify the ENDPOINT to your own image:

```yaml
ENDPOINT: "user/endpoint"
BRANCH: "master"
```

User is your Dockerhub user and endpoint is your own custom name (typically the name of the repository where your mod is). You do not need to create this endpoint beforehand, the build logic will push it and create it on first run.

Head over to `https://github.com/user/endpoint/settings/secrets` and click on `New secret`

Add `DOCKERUSER` (your DockerHub username) and `DOCKERPASS` (your DockerHub password or token).

You can create a token by visiting <https://hub.docker.com/settings/security>

GitHub Actions will trigger a build off of your repo when you commit. The image will be pushed to Dockerhub on success. This Dockerhub endpoint is the Mod variable you can use to customize your container now.

## Getting a Mod to GitHub Container Registry

To publish a Mod to GitHub Container Registry you will need the following accounts:

* Github- <https://github.com/join>

We recommend using this repository as a template for your first Mod, so in this section we assume the code is finished and we will only concentrate on plugging into GitHub Actions/GitHub Container Registry.

The only code change you need to make to the build logic file `.github/workflows/BuildImage.yml` will be to modify the ENDPOINT to your own image:

```yaml
ENDPOINT: "user/endpoint"
BRANCH: "master"
```

User is your GutHub user and endpoint is your own custom name (typically the name of the repository where your mod is). You do not need to create this endpoint beforehand, the build logic will push it and create it on first run.

Head over to `https://github.com/user/endpoint/settings/secrets` and click on `New secret`

Add `CR_USER` (your GitHub username) and `CR_PAT` (a personal access token with `read:packages` and `write:packages` scopes).

You can create a personal access token by visiting <https://github.com/settings/tokens>

GitHub Actions will trigger a build off of your repo when you commit. The image will be pushed to GitHub Container Registry on success. This GitHub Container Registry endpoint is the Mod variable you can use to customize your container now.

## Submitting a PR for a Mod to be added to the official LinuxServer.io repo

* Fork this repo, checkout the `template` branch.
* Edit the `Dockerfile` for the mod. `Dockerfile.complex` is only an example and included for reference; it should be deleted when done.
* Inspect the `root` folder contents. Edit, add and remove as necessary.
* Edit the readme with pertinent info.
* Finally edit the `.github/workflows/BuildImage.yml`. Customize the vars for `BASEIMAGE` and `MODNAME`.
* Ask the team to create a new branch named `<baseimagename>-<modname>` in this repo. Baseimage should be the name of the image the mod will be applied to. The new branch will be based on the [template branch](https://github.com/linuxserver/docker-mods/tree/template).
* Submit PR against the branch created by the team.
* Make sure that the commits in the PR are squashed.
* Also make sure that the commit and PR titles are in the format of `<imagename>: <modname> <very brief description like "initial release" or "update">`. Detailed description and further info should be provided in the body (ie. `code-server: python2 add python-pip`).

## Appendix

### Inspecting mods

To inspect the file contents of external Mods dive is a great CLI tool:

<https://github.com/wagoodman/dive>

Basic usage:

```bash
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
wagoodman/dive:latest <Image Name>
```
If adding multiple mods, enter them in an array separated by |, such as `DOCKER_MODS=linuxserver/mods:nzbget-essentials|linuxserver/mods:nzbget-mod2`
2 changes: 0 additions & 2 deletions blacklist.txt

This file was deleted.

1 change: 1 addition & 0 deletions exclude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading