├── .harness ├── Build_kolonuk_get_iplayer_docker_1713783970064-pr-trigger-input-set-1713783971109.yaml ├── Build_kolonuk_get_iplayer_docker_1713783970064-push-trigger-input-set-1713783972734.yaml └── pipelines │ └── get_iplayer-docker-1713783960726.yaml ├── Dockerfile ├── README.md ├── start.sh └── update.sh /.harness/Build_kolonuk_get_iplayer_docker_1713783970064-pr-trigger-input-set-1713783971109.yaml: -------------------------------------------------------------------------------- 1 | inputSet: 2 | name: Build_kolonuk_get_iplayer_docker_1713783970064-pr-trigger-input-set 3 | identifier: Build_kolonuk_get_iplayer_docker_1713783970064prtriggerinputset 4 | orgIdentifier: default 5 | projectIdentifier: default_project 6 | pipeline: 7 | identifier: Build_kolonuk_get_iplayer_docker_1713783970064 8 | properties: 9 | ci: 10 | codebase: 11 | build: 12 | type: PR 13 | spec: 14 | number: <+trigger.prNumber> 15 | -------------------------------------------------------------------------------- /.harness/Build_kolonuk_get_iplayer_docker_1713783970064-push-trigger-input-set-1713783972734.yaml: -------------------------------------------------------------------------------- 1 | inputSet: 2 | name: Build_kolonuk_get_iplayer_docker_1713783970064-push-trigger-input-set 3 | identifier: Build_kolonuk_get_iplayer_docker_1713783970064pushtriggerinputset 4 | orgIdentifier: default 5 | projectIdentifier: default_project 6 | pipeline: 7 | identifier: Build_kolonuk_get_iplayer_docker_1713783970064 8 | properties: 9 | ci: 10 | codebase: 11 | build: 12 | type: branch 13 | spec: 14 | branch: <+trigger.branch> 15 | -------------------------------------------------------------------------------- /.harness/pipelines/get_iplayer-docker-1713783960726.yaml: -------------------------------------------------------------------------------- 1 | pipeline: 2 | identifier: Build_kolonuk_get_iplayer_docker_1713783970064 3 | name: Build get_iplayer-docker 4 | orgIdentifier: default 5 | projectIdentifier: default_project 6 | properties: 7 | ci: 8 | codebase: 9 | build: <+input> 10 | connectorRef: account.Github_OAuth_1713783914293 11 | repoName: kolonuk/get_iplayer-docker 12 | stages: 13 | - stage: 14 | identifier: build 15 | name: build 16 | spec: 17 | caching: 18 | enabled: true 19 | cloneCodebase: true 20 | execution: 21 | steps: 22 | - step: 23 | identifier: echo 24 | name: echo 25 | spec: 26 | command: echo hello world 27 | timeout: "" 28 | type: Run 29 | - step: 30 | identifier: dockerbuild 31 | name: docker_build 32 | spec: 33 | caching: true 34 | connectorRef: <+input> 35 | repo: hello/world 36 | tags: 37 | - latest 38 | timeout: "" 39 | type: BuildAndPushDockerRegistry 40 | platform: 41 | arch: Amd64 42 | os: Linux 43 | runtime: 44 | spec: {} 45 | type: Cloud 46 | type: CI 47 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM kolonuk/get_iplayer-docker-base 2 | 3 | ADD start.sh /root/start.sh 4 | ADD update.sh /root/update.sh 5 | 6 | RUN chmod 755 /root/start.sh 7 | RUN chmod 755 /root/update.sh 8 | 9 | # Setup crontab 10 | RUN echo "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" > /root/cron.tab && \ 11 | echo "@hourly /root/get_iplayer --refresh > /proc/1/fd/1 2>&1" >> /root/cron.tab && \ 12 | echo "@hourly /root/get_iplayer --pvr > /proc/1/fd/1 2>&1" >> /root/cron.tab && \ 13 | echo "@daily /root/update.sh > /proc/1/fd/1 2>&1" >> /root/cron.tab && \ 14 | crontab /root/cron.tab && \ 15 | rm -f /root/cron.tab 16 | 17 | VOLUME /root/.get_iplayer 18 | VOLUME /root/output 19 | 20 | LABEL issues_get_iplayer="Comments/issues for get_iplayer: https://forums.squarepenguin.co.uk" 21 | LABEL issues_kolonuk/get_iplayer="Comments/issues for this Dockerfile: https://github.com/kolonuk/get_iplayer-docker/issues" 22 | LABEL maintainer="John Wood " 23 | 24 | EXPOSE 8181:8181 25 | 26 | ENTRYPOINT ["/bin/bash", "/root/start.sh"] 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # get_iplayer on Docker 2 | 3 | Disappointed with the current availability of get_iplayer in docker, I created an auto-updating docker container, complete with the webgui. 4 | 5 | For now, this uses the plain Ubuntu image, so is huge for a very simple perl program - definitely needs the packages trimming. I've added a testing branch to the github repo so that I can experiment with other base images to see if I can get this reduced in size - current uncompressed ubuntu is around 400mb. If you'd like to contribute, please fork and create a pull request, or just raise an issue on github. 6 | 7 | ## Usage 8 | docker create \ 9 | --name get_iplayer \ 10 | -p 8181:8181 \ 11 | -v /etc/localtime:/etc/localtime:ro \ 12 | -v :/root/.get_iplayer \ 13 | -v :/root/output \ 14 | kolonuk/get_iplayer 15 | 16 | * Backup your current config and recordings. 17 | * Mount `/root/.get_iplayer` to your config directory. This should include your `options` file and `pvr` directory. If starting from scratch, you can manually edit the `options` file created here. 18 | * Mount `/root/output` to your recordings location. 19 | 20 | **WARNING - get_iplayer stores cookies in your browser for some default settings. Because of this, at least try to see if you can find those cookies and remove them BEFORE loading the newly installed container. For example, if you have set the recordings path in the webgui, this overrides the location in the `options` file for downloads.** 21 | 22 | ## Start 23 | Upon first start, it will download the latest get_iplayer scripts from the official github repo . 24 | * When starting this for the first time, it will create some nice newbie default options (enable whitespace in filenames, download subtitles, etc.). 25 | * When starting this using existing configuration files, it will forcibly change the output location to the container's output volume location, thus hopefully, it should "just work". 26 | 27 | ## Updating 28 | There is a cron job that runs daily that checks the latest release of get_iplayer, and downloads it. It then checks to see if the pvr is running, before killing the perl process, which automatically gets restarted using the new version of the get_iplayer script. This is different from other docker containers in that the version of get_iplayer in this container is not statically included in the container, leading to a stale container. 29 | 30 | To do a manual update, you just need to re-create this container and it will have the latest version from the get_iplayer repo. I use Portainer to manage my containers, and I just need to hit the `Recreate` button. 31 | 32 | **Watchtower will not update this container to the latest version of get_iplayer by its self. Until Docker introduces monitoring of alternative github repos for automated container builds (which trigger watchtower), this auto-update method is the best you can get.** 33 | 34 | ## Issues 35 | * Report issues with this dockerfile 36 | * Report issues with the get_iplayer script 37 | 38 | ## About me 39 | Just a small-time tinkerer of almost anything computer-related (servers, raspi, networks, programming, android, etc.). I am active on various places on the net, like StackExchange, github, and some mailing lists, etc., so ping me a message about anything - if I don't know, I'll know where to go to find out! 40 | 41 | ## Todo 42 | 1. Check different base os's for Dockerfile 43 | 2. Remove as much gumf as possible 44 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if we have get_iplayer 4 | if [[ ! -f /root/get_iplayer.cgi ]] 5 | then 6 | /root/update.sh start 7 | fi 8 | 9 | if [[ ! -f /root/get_iplayer ]] 10 | then # pause for checking things out... 11 | echo err1 - Error occurred, pausing for 9999 seconds for investigation 12 | sleep 9999 13 | fi 14 | 15 | # Set some nice defaults 16 | if [[ ! -f /root/.get_iplayer/options ]] 17 | then 18 | echo No options file found, adding some nice defaults... 19 | /root/get_iplayer --prefs-add --whitespace 20 | /root/get_iplayer --prefs-add --subs-embed 21 | /root/get_iplayer --prefs-add --metadata 22 | /root/get_iplayer --prefs-add --nopurge 23 | 24 | echo Removing non-standard download location from existing PVR files... 25 | # so downloads don't get saved in the container 26 | sed -i '/^output/d' /root/.get_iplayer/pvr/* 27 | fi 28 | 29 | # Force output location to a separate docker volume 30 | echo Forcing output location... 31 | /root/get_iplayer --prefs-add --output="/root/output/" 32 | 33 | if [[ -f /root/get_iplayer.cgi ]] 34 | then 35 | # Start cron 36 | service cron start 37 | 38 | # Keep restarting - for when the get_iplayer script is updated 39 | while true 40 | do 41 | # can remove the pvr lock if restarting - prevents "Can't kill a non-numeric process ID at /root/get_iplayer line xxx." error 42 | rm /root/.get_iplayer/pvr_lock 43 | # start get-iplayer 44 | /usr/bin/perl /root/get_iplayer.cgi --port 8181 --getiplayer /root/get_iplayer 45 | done 46 | else 47 | echo err2 - Error occurred, pausing for 9999 seconds for investigation 48 | sleep 9999 # when testing, keep container up long enough to check stuff out 49 | fi 50 | 51 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo Checking latest versions of get_iplayer... 4 | 5 | # Get cgi script version 6 | if [[ -f /root/get_iplayer.cgi ]] 7 | then 8 | VERSIONcgi=$(cat /root/get_iplayer.cgi | grep VERSION | grep -oP 'VERSION\ =\ \K.*?(?=;)' | head -1) 9 | fi 10 | 11 | # Get main script version 12 | if [[ -f /root/get_iplayer ]] 13 | then 14 | VERSION=$(cat /root/get_iplayer | grep version | grep -oP 'version\ =\ \K.*?(?=;)' | head -1) 15 | fi 16 | 17 | # Get current github release version 18 | RELEASE=$(wget -q -O - "https://api.github.com/repos/get-iplayer/get_iplayer/releases/latest" | grep -Po '"tag_name": "v\K.*?(?=")') 19 | 20 | # If no github version returned 21 | if [[ "$RELEASE" == "" ]] && [[ "$FORCEDOWNLOAD" -eq "" ]] 22 | then 23 | #indicates something wrong with the github call 24 | echo ******** Warning - unable to check latest release!! Please raise an issue https://github.com/kolonuk/get_iplayer-docker/issues/new 25 | fi 26 | 27 | echo get_iplayer installed $VERSION 28 | echo get_iplayer release $RELEASE 29 | echo get_iplayer webui installed $VERSIONcgi 30 | echo get_iplayer webui release $RELEASEcgi 31 | 32 | if [[ "$VERSION" != "$VERSIONcgi" ]] || \ 33 | [[ "$VERSION" == "" ]] || \ 34 | [[ "$VERSIONcgi" == "" ]] || \ 35 | [[ "$VERSION" != "$RELEASE" ]] || \ 36 | [[ "$FORCEDOWNLOAD" != "" ]] 37 | then 38 | echo Getting latest version of get_iplayer... 39 | if [[ "$RELEASE" == "" ]] 40 | then 41 | # No release returned from github, download manually 42 | wget -q https://raw.githubusercontent.com/get-iplayer/get_iplayer/master/get_iplayer.cgi -O /root/get_iplayer.cgi 43 | wget -q https://raw.githubusercontent.com/get-iplayer/get_iplayer/master/get_iplayer -O /root/get_iplayer 44 | chmod 755 /root/get_iplayer 45 | else 46 | # Download and unpack release 47 | wget -q https://github.com/get-iplayer/get_iplayer/archive/v$RELEASE.tar.gz -O /root/latest.tar.gz 48 | cd /root 49 | tar -xzf /root/latest.tar.gz get_iplayer-$RELEASE --directory /root/ --strip-components=1 50 | rm /root/latest.tar.gz 51 | fi 52 | 53 | #kill current get_iplayer gracefully (is pvr/cache refresh running?) 54 | if [[ -f /root/.get_iplayer/pvr_lock ]] #|| [[ -f /root/.get_iplayer/??refreshcache_lock ]] 55 | then 56 | echo Warning - updated scripts, but get_iplayer processes are running so unable to restart get_iplayer 57 | else 58 | # This will kill the running perl processes, and the start script will just re-load it 59 | if [[ "$1" != "start" ]] 60 | then 61 | echo Killing get_iplayer process... 62 | killall -9 perl 63 | fi 64 | fi 65 | fi 66 | --------------------------------------------------------------------------------