├── .editorconfig ├── .github └── workflows │ └── build.yml ├── Dockerfile ├── LICENSE ├── README.md └── rootfs ├── etc ├── nginx │ └── nginx.conf ├── php83 │ ├── conf.d │ │ ├── 00_opcache.ini │ │ ├── apcu.ini │ │ └── www.ini │ └── php-fpm.d │ │ └── www.conf └── s6.d │ ├── .s6-svscan │ ├── crash │ └── finish │ ├── nginx │ ├── crash │ ├── finish │ └── run │ ├── php83 │ ├── crash │ ├── finish │ └── run │ └── rtorrent │ ├── crash │ ├── finish │ └── run ├── filebot └── args_amc.txt ├── home └── torrent │ └── .rtorrent.rc ├── rutorrent └── app │ ├── conf │ └── config.php │ ├── php │ └── share │ │ └── torrents │ │ └── .gitkeep │ └── plugins │ └── create │ └── conf.php └── usr └── local └── bin ├── gen-http-passwd ├── postdl ├── postrm ├── startup └── update-config /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.php] 16 | indent_size = 4 17 | 18 | [*.md] 19 | trim_trailing_whitespace = false 20 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | schedule: 5 | - cron: '15 23 * * 5' 6 | push: 7 | branches: [ "master" ] 8 | 9 | env: 10 | IMAGE_NAME: mondedie/rutorrent 11 | 12 | jobs: 13 | latest: 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up QEMU 20 | uses: docker/setup-qemu-action@v3 21 | 22 | - name: Set up Docker Buildx 23 | uses: docker/setup-buildx-action@v3 24 | 25 | - name: Login to Docker Hub 26 | uses: docker/login-action@v3 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - name: Set Docker metadata 32 | id: meta 33 | uses: docker/metadata-action@v5 34 | with: 35 | images: ${{ env.IMAGE_NAME }} 36 | tags: | 37 | latest 38 | type=raw,value={{date 'YYYY.MM.DD'}} 39 | 40 | - name: Build and push Docker image 41 | id: build-and-push 42 | uses: docker/build-push-action@v5 43 | with: 44 | context: . 45 | platforms: linux/amd64,linux/arm64 46 | push: true 47 | tags: ${{ steps.meta.outputs.tags }} 48 | 49 | filebot: 50 | runs-on: ubuntu-22.04 51 | steps: 52 | - name: Checkout code 53 | uses: actions/checkout@v4 54 | 55 | - name: Set up QEMU 56 | uses: docker/setup-qemu-action@v3 57 | 58 | - name: Set up Docker Buildx 59 | uses: docker/setup-buildx-action@v3 60 | 61 | - name: Login to Docker Hub 62 | uses: docker/login-action@v3 63 | with: 64 | username: ${{ secrets.DOCKER_USERNAME }} 65 | password: ${{ secrets.DOCKER_PASSWORD }} 66 | 67 | - name: Set Docker metadata 68 | id: meta 69 | uses: docker/metadata-action@v5 70 | with: 71 | images: ${{ env.IMAGE_NAME }} 72 | tags: | 73 | filebot 74 | type=raw,value=filebot-{{date 'YYYY.MM.DD'}} 75 | 76 | - name: Build and push Docker image 77 | id: build-and-push 78 | uses: docker/build-push-action@v5 79 | with: 80 | build-args: | 81 | FILEBOT=true 82 | context: . 83 | platforms: linux/amd64,linux/arm64 84 | push: true 85 | tags: ${{ steps.meta.outputs.tags }} 86 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CARES_VERSION=1.34.5 2 | ARG CURL_VERSION=8.12.1 3 | ARG MKTORRENT_VERSION=v1.1 4 | ARG DUMP_TORRENT_VERSION=bb4b64cb504357dc6ed51bdd27c06062019a268d 5 | 6 | # Create src image to retreive source files 7 | FROM alpine:3.21 AS src 8 | RUN apk --update --no-cache add curl git tar sed tree xz 9 | WORKDIR /src 10 | 11 | # Retreive c-ares source files 12 | FROM src AS src-cares 13 | ARG CARES_VERSION 14 | RUN curl -sSL "https://github.com/c-ares/c-ares/releases/download/v${CARES_VERSION}/c-ares-${CARES_VERSION}.tar.gz" | tar xz --strip 1 15 | 16 | # Retreive curl source files 17 | FROM src AS src-curl 18 | ARG CURL_VERSION 19 | RUN curl -sSL "https://curl.se/download/curl-${CURL_VERSION}.tar.gz" | tar xz --strip 1 20 | 21 | # Retreive source files for mktorrent 22 | FROM src AS src-mktorrent 23 | RUN git init . && git remote add origin "https://github.com/pobrn/mktorrent.git" 24 | ARG MKTORRENT_VERSION 25 | RUN git fetch origin "${MKTORRENT_VERSION}" && git checkout -q FETCH_HEAD 26 | 27 | # Retreive source files for dumptorrent. Repair build for alpine Linux. 28 | FROM src AS src-dump-torrent 29 | RUN git init . && git remote add origin "https://github.com/TheGoblinHero/dumptorrent.git" 30 | ARG DUMP_TORRENT_VERSION 31 | RUN git fetch origin "${DUMP_TORRENT_VERSION}" && git checkout -q FETCH_HEAD 32 | RUN sed -i '1i #include ' scrapec.c 33 | RUN rm -rf .git* 34 | 35 | FROM alpine:3.21 AS builder 36 | 37 | ENV DIST_PATH="/dist" 38 | 39 | RUN apk --update --no-cache add \ 40 | autoconf \ 41 | automake \ 42 | binutils \ 43 | brotli-dev \ 44 | build-base \ 45 | cmake \ 46 | cppunit-dev \ 47 | curl-dev \ 48 | libtool \ 49 | linux-headers \ 50 | openssl-dev \ 51 | tree \ 52 | zlib-dev 53 | 54 | # Build and install c-ares for asynchronous DNS resolution of TCP trackers on rTorrent 55 | WORKDIR /usr/local/src/cares 56 | COPY --from=src-cares /src . 57 | RUN cmake . -D CARES_SHARED=ON -D CMAKE_BUILD_TYPE:STRING="Release" -D CMAKE_C_FLAGS_RELEASE:STRING="-O3" 58 | RUN cmake --build . --clean-first --parallel $(nproc) 59 | RUN make install -j$(nproc) 60 | RUN make DESTDIR=${DIST_PATH} install -j$(nproc) 61 | RUN tree ${DIST_PATH} 62 | 63 | # Build and install curl with c-ares for asynchronous DNS resolution of TCP trackers on rTorrent 64 | WORKDIR /usr/local/src/curl 65 | COPY --from=src-curl /src . 66 | RUN cmake . -D ENABLE_ARES=ON -D CURL_USE_OPENSSL=ON -D CURL_BROTLI=ON -D CURL_ZSTD=ON -D BUILD_SHARED_LIBS=ON -D CMAKE_BUILD_TYPE:STRING="Release" -D CMAKE_C_FLAGS_RELEASE:STRING="-O3" 67 | RUN cmake --build . --clean-first --parallel $(nproc) 68 | RUN make install -j$(nproc) 69 | RUN make DESTDIR=${DIST_PATH} install -j$(nproc) 70 | RUN tree ${DIST_PATH} 71 | 72 | # Build and install mktorrent with pthreads 73 | WORKDIR /usr/local/src/mktorrent 74 | COPY --from=src-mktorrent /src . 75 | RUN echo "CC = gcc" >> Makefile 76 | RUN echo "CFLAGS = -w -flto -O3" >> Makefile 77 | RUN echo "USE_PTHREADS = 1" >> Makefile 78 | RUN echo "USE_OPENSSL = 1" >> Makefile 79 | RUN make -j$(nproc) 80 | RUN make install -j$(nproc) 81 | RUN make DESTDIR=${DIST_PATH} install -j$(nproc) 82 | RUN tree ${DIST_PATH} 83 | 84 | # Build and install dump torrent for ruTorrent plugin 85 | WORKDIR /usr/local/src/dump-torrent 86 | COPY --from=src-dump-torrent /src . 87 | RUN make dumptorrent -j$(nproc) 88 | RUN cp dumptorrent ${DIST_PATH}/usr/local/bin 89 | RUN tree ${DIST_PATH} 90 | 91 | FROM alpine:3.21 92 | 93 | LABEL description="rutorrent based on alpinelinux" \ 94 | maintainer="magicalex " 95 | 96 | ARG FILEBOT=false 97 | ARG FILEBOT_VER=5.1.7 98 | ARG RUTORRENT_VER=5.2.8 99 | 100 | ENV UID=991 \ 101 | GID=991 \ 102 | PORT_RTORRENT=45000 \ 103 | MODE_DHT=off \ 104 | PORT_DHT=6881 \ 105 | PEER_EXCHANGE=no \ 106 | DOWNLOAD_DIRECTORY=/data/downloads \ 107 | CHECK_PERM_DATA=true \ 108 | FILEBOT_RENAME_METHOD=symlink \ 109 | FILEBOT_LANG=fr \ 110 | FILEBOT_CONFLICT=skip \ 111 | HTTP_AUTH=false 112 | 113 | COPY --from=builder /dist / 114 | 115 | # unrar package is not available since alpine 3.15 116 | RUN echo "@314 http://dl-cdn.alpinelinux.org/alpine/v3.14/main" >> /etc/apk/repositories \ 117 | && apk --update --no-cache add unrar@314 118 | 119 | RUN echo "@320 http://dl-cdn.alpinelinux.org/alpine/v3.20/main" >> /etc/apk/repositories \ 120 | && apk --update --no-cache add s6@320 121 | 122 | RUN apk --update --no-cache add \ 123 | 7zip \ 124 | bash \ 125 | ffmpeg \ 126 | ffmpeg-dev \ 127 | findutils \ 128 | git \ 129 | libmediainfo \ 130 | libmediainfo-dev \ 131 | libzen \ 132 | libzen-dev \ 133 | mediainfo \ 134 | nginx \ 135 | openssl \ 136 | php83 \ 137 | php83-bcmath \ 138 | php83-ctype \ 139 | php83-curl \ 140 | php83-dom \ 141 | php83-fpm \ 142 | php83-mbstring \ 143 | php83-opcache \ 144 | php83-openssl \ 145 | php83-pecl-apcu \ 146 | php83-phar \ 147 | php83-session \ 148 | php83-sockets \ 149 | php83-xml \ 150 | php83-zip \ 151 | rtorrent \ 152 | sox \ 153 | su-exec \ 154 | unzip \ 155 | # Install rutorrent 156 | && git clone -b v${RUTORRENT_VER} --recurse-submodules https://github.com/Novik/ruTorrent.git /rutorrent/app \ 157 | && git clone https://github.com/Micdu70/geoip2-rutorrent.git /rutorrent/app/plugins/geoip2 \ 158 | && git clone https://github.com/Micdu70/rutorrent-ratiocolor.git /rutorrent/app/plugins/ratiocolor \ 159 | && rm -rf /rutorrent/app/plugins/geoip \ 160 | && rm -rf /rutorrent/app/plugins/_cloudflare \ 161 | && rm -rf /rutorrent/app/plugins/geoip2/.git \ 162 | && rm -rf /rutorrent/app/plugins/ratiocolor/.git \ 163 | && rm -rf /rutorrent/app/.git \ 164 | # Socket folder 165 | && mkdir -p /run/rtorrent /run/nginx /run/php 166 | 167 | RUN if [ "${FILEBOT}" = true ]; then \ 168 | apk --update --no-cache add \ 169 | chromaprint \ 170 | openjdk17-jre-headless \ 171 | # Install filebot 172 | && mkdir /filebot \ 173 | && cd /filebot \ 174 | && wget "https://get.filebot.net/filebot/FileBot_${FILEBOT_VER}/FileBot_${FILEBOT_VER}-portable.tar.xz" -O /filebot/filebot.tar.xz \ 175 | && tar -xJf filebot.tar.xz \ 176 | && rm -rf filebot.tar.xz \ 177 | && sed -i 's/-Dapplication.deployment=tar/-Dapplication.deployment=docker/g' /filebot/filebot.sh \ 178 | && find /filebot/lib -type f -not -name libjnidispatch.so -delete; \ 179 | fi 180 | 181 | COPY rootfs / 182 | RUN chmod 775 /usr/local/bin/* 183 | VOLUME /data /config 184 | EXPOSE 8080 185 | ENTRYPOINT ["/usr/local/bin/startup"] 186 | CMD ["/bin/s6-svscan", "/etc/s6.d"] 187 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2023 mondedie/rutorrent 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mondedie/rutorrent 2 | 3 | [![](https://github.com/mondediefr/docker-rutorrent/workflows/build/badge.svg)](https://github.com/mondediefr/docker-rutorrent/actions) 4 | [![](https://img.shields.io/docker/pulls/mondedie/rutorrent)](https://hub.docker.com/r/mondedie/rutorrent) 5 | [![](https://img.shields.io/docker/stars/mondedie/rutorrent)](https://hub.docker.com/r/mondedie/rutorrent) 6 | 7 | ## Features 8 | 9 | - Platform image: `linux/amd64`, `linux/arm64` 10 | - Based on Alpine Linux 3.21 11 | - php 8.3 12 | - Provides by default a solid configuration 13 | - No root process 14 | - Persitance custom configuration for rutorrent and rtorrent 15 | - Add your own rutorrent plugins and themes 16 | - Filebot is included, and creates symlinks in `/data/media` (choose filebot tag) 17 | 18 | ## Tag available 19 | 20 | - latest [(Dockerfile)](https://github.com/mondediefr/docker-rutorrent/blob/master/Dockerfile) 21 | - filebot [(Dockerfile)](https://github.com/mondediefr/docker-rutorrent/blob/master/Dockerfile) 22 | 23 | ## Build image 24 | 25 | ### Build arguments 26 | 27 | | Argument | Description | Type | Default value | 28 | | -------- | ----------- | ---- | ------------- | 29 | | **FILEBOT** | Build with filebot | *optional* | false 30 | | **FILEBOT_VER** | Filebot version | *optional* | 5.1.7 31 | | **RUTORRENT_VER** | ruTorrent version | *optional* | 5.1.6 32 | 33 | ### build 34 | 35 | ```sh 36 | docker build --tag mondedie/rutorrent:latest https://github.com/mondediefr/docker-rutorrent.git 37 | ``` 38 | 39 | ### Build with arguments 40 | 41 | ```sh 42 | docker build --tag mondedie/rutorrent:filebot --build-arg FILEBOT=true https://github.com/mondediefr/docker-rutorrent.git 43 | ``` 44 | 45 | ## Configuration 46 | 47 | ### Environment variables 48 | 49 | | Variable | Description | Type | Default value | 50 | | -------- | ----------- | ---- | ------------- | 51 | | **UID** | Choose uid for launch rtorrent | *optional* | 991 52 | | **GID** | Choose gid for launch rtorrent | *optional* | 991 53 | | **PORT_RTORRENT** | Port of rtorrent | *optional* | 45000 54 | | **MODE_DHT** | DHT mode in rtorrent.rc file (disable,off,on) | *optional* | off 55 | | **PORT_DHT** | UDP port to use for DHT | *optional* | 6881 56 | | **PEER_EXCHANGE** | Enable peer exchange (yes,no) | *optional* | no 57 | | **DOWNLOAD_DIRECTORY** | Torrent download directory | *optional* | /data/downloads 58 | | **CHECK_PERM_DATA** | Check permissions in the data directory | *optional* | true 59 | | **HTTP_AUTH** | Enable HTTP authentication | *optional* | false 60 | 61 | ### Environment variables with filebot 62 | 63 | | Variable | Description | Type | Default value | 64 | | -------- | ----------- | ---- | ------------- | 65 | | **FILEBOT_LICENSE** | License file path | **required** | none 66 | | **FILEBOT_RENAME_METHOD** | Method for rename media | *optional* | symlink 67 | | **FILEBOT_LANG** | Set your language | *optional* | fr 68 | | **FILEBOT_CONFLICT** | Conflict management | *optional* | skip 69 | 70 | ### Volumes 71 | 72 | - `/data` : folder for download torrents 73 | - `/config` : folder for rtorrent and rutorrent configuration 74 | 75 | #### Data folder tree 76 | 77 | - `/data/.watch` : rtorrent watch directory 78 | - `/data/.session` : rtorrent save statement here 79 | - `/data/downloads` : rtorrent download torrent here 80 | - `/data/media` : organize your media and create a symlink with filebot 81 | - `/config/rtorrent` : path of .rtorrent.rc 82 | - `/config/rutorrent/conf` : global configuration of rutorrent 83 | - `/config/rutorrent/share` : rutorrent user configuration and cache 84 | - `/config/custom_plugins` : add your own plugins 85 | - `/config/custom_themes` : add your own themes 86 | - `/config/filebot` : add your License file in this folder 87 | - `/config/filebot/args_amc.txt` : configuration of fn:amc script of filebot 88 | - `/config/filebot/postdl` : modify postdl script, example [here](https://github.com/mondediefr/docker-rutorrent/blob/master/rootfs/usr/local/bin/postdl) 89 | 90 | ### Ports 91 | 92 | - 8080 93 | - PORT_RTORRENT (default: 45000) 94 | 95 | ## Usage 96 | 97 | ### Simple launch 98 | 99 | ```sh 100 | docker run --name rutorrent -dt \ 101 | -e UID=1000 \ 102 | -e GID=1000 \ 103 | -p 8080:8080 \ 104 | -p 45000:45000 \ 105 | -v /mnt/docker/rutorrent/config:/config \ 106 | -v /mnt/docker/rutorrent/data:/data \ 107 | mondedie/rutorrent:latest 108 | ``` 109 | 110 | URL: http://xx.xx.xx.xx:8080 111 | 112 | ### Advanced launch 113 | 114 | Add custom plugin : 115 | 116 | ```sh 117 | mkdir -p /mnt/docker/rutorrent/config/custom_plugins 118 | git clone https://github.com/Gyran/rutorrent-ratiocolor.git /mnt/docker/rutorrent/config/custom_plugins/ratiocolor 119 | ``` 120 | 121 | Add custom theme : 122 | 123 | Donwload a theme for example in this repository https://github.com/artyuum/3rd-party-ruTorrent-Themes.git 124 | And copy the folder in `/mnt/docker/rutorrent/config/custom_themes` 125 | 126 | Run container : 127 | 128 | ```sh 129 | docker run --name rutorrent -dt \ 130 | -e UID=1000 \ 131 | -e GID=1000 \ 132 | -e DHT_RTORRENT=on \ 133 | -e PORT_RTORRENT=6881 \ 134 | -e FILEBOT_LICENSE=/config/filebot/FileBot_License_XXXXXXXXX.psm \ 135 | -e FILEBOT_RENAME_METHOD=move \ 136 | -p 9080:8080 \ 137 | -p 6881:6881 \ 138 | -p 6881:6881/udp \ 139 | -v /mnt/docker/rutorrent/config:/config \ 140 | -v /mnt/docker/rutorrent/data:/data \ 141 | mondedie/rutorrent:filebot 142 | ``` 143 | 144 | URL: http://xx.xx.xx.xx:9080 145 | 146 | ### Add HTTP authentication 147 | 148 | ```sh 149 | docker run --name rutorrent -dt \ 150 | -e UID=1000 \ 151 | -e GID=1000 \ 152 | -e PORT_RTORRENT=46000 \ 153 | -e HTTP_AUTH=true \ 154 | -p 8080:8080 \ 155 | -p 46000:46000 \ 156 | -v /mnt/docker/rutorrent/config:/config \ 157 | -v /mnt/docker/rutorrent/data:/data \ 158 | mondedie/rutorrent:latest 159 | ``` 160 | 161 | Generate your password: 162 | 163 | ```sh 164 | docker exec -it rutorrent gen-http-passwd 165 | Username: torrent 166 | Password: 167 | Verifying - Password: 168 | Password was generated for the http user: torrent 169 | ``` 170 | 171 | URL: http://xx.xx.xx.xx:8080 172 | 173 | ## License 174 | 175 | Docker image [mondedie/rutorrent](https://hub.docker.com/r/mondedie/rutorrent) is released under [MIT License](https://github.com/mondediefr/docker-rutorrent/blob/master/LICENSE). 176 | -------------------------------------------------------------------------------- /rootfs/etc/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | daemon off; 2 | worker_processes auto; 3 | pid /run/nginx/nginx.pid; 4 | 5 | events { 6 | worker_connections 1024; 7 | use epoll; 8 | } 9 | 10 | http { 11 | include /etc/nginx/mime.types; 12 | default_type application/octet-stream; 13 | 14 | access_log /tmp/nginx-access.log combined; 15 | error_log /tmp/nginx-error.log error; 16 | 17 | fastcgi_temp_path /tmp/fastcgi 1 2; 18 | client_body_temp_path /tmp/client_body 1 2; 19 | proxy_temp_path /tmp/proxy 1 2; 20 | uwsgi_temp_path /tmp/uwsgi 1 2; 21 | scgi_temp_path /tmp/scgi 1 2; 22 | 23 | sendfile on; 24 | keepalive_timeout 15; 25 | keepalive_disable msie6; 26 | keepalive_requests 100; 27 | tcp_nopush on; 28 | tcp_nodelay off; 29 | server_tokens off; 30 | 31 | gzip on; 32 | gzip_comp_level 5; 33 | gzip_min_length 512; 34 | gzip_buffers 4 8k; 35 | gzip_proxied any; 36 | gzip_vary on; 37 | gzip_disable "msie6"; 38 | gzip_types 39 | text/css 40 | text/javascript 41 | text/xml 42 | text/plain 43 | text/x-component 44 | application/javascript 45 | application/x-javascript 46 | application/json 47 | application/xml 48 | application/rss+xml 49 | application/vnd.ms-fontobject 50 | font/truetype 51 | font/opentype 52 | image/svg+xml; 53 | 54 | server { 55 | server_name _; 56 | listen 8080 default_server; 57 | 58 | charset utf-8; 59 | index index.html; 60 | root /rutorrent/app; 61 | client_max_body_size 10m; 62 | 63 | 64 | 65 | location = /favicon.ico { 66 | access_log off; 67 | log_not_found off; 68 | } 69 | 70 | location = / { 71 | try_files $uri $uri/ /index.html; 72 | } 73 | 74 | location ~ ^/(conf|share)/(.+)$ { 75 | deny all; 76 | } 77 | 78 | location = /RPC2 { 79 | include /etc/nginx/scgi_params; 80 | scgi_pass unix:/run/rtorrent/rtorrent.sock; 81 | } 82 | 83 | location ~ \.php$ { 84 | fastcgi_index index.php; 85 | include /etc/nginx/fastcgi_params; 86 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 87 | fastcgi_pass unix:/run/php/php83-fpm.sock; 88 | } 89 | 90 | location ~* \.(jpg|jpeg|gif|css|png|js|map|woff|woff2|ttf|svg|eot)$ { 91 | expires 30d; 92 | access_log off; 93 | } 94 | 95 | access_log /tmp/nginx-rutorrent-access.log combined; 96 | error_log /tmp/nginx-rutorrent-error.log error; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /rootfs/etc/php83/conf.d/00_opcache.ini: -------------------------------------------------------------------------------- 1 | zend_extension=opcache.so 2 | 3 | opcache.enable=1 4 | opcache.enable_cli=1 5 | opcache.fast_shutdown=1 6 | opcache.memory_consumption=128 7 | opcache.interned_strings_buffer=16 8 | opcache.max_accelerated_files=7963 9 | opcache.revalidate_freq=60 10 | -------------------------------------------------------------------------------- /rootfs/etc/php83/conf.d/apcu.ini: -------------------------------------------------------------------------------- 1 | extension=apcu.so 2 | 3 | apc.enabled=1 4 | apc.shm_size=128M 5 | apc.ttl=7200 6 | -------------------------------------------------------------------------------- /rootfs/etc/php83/conf.d/www.ini: -------------------------------------------------------------------------------- 1 | post_max_size=100M 2 | upload_max_filesize=100M 3 | max_execution_time=10800 4 | max_input_time=3600 5 | expose_php=Off 6 | -------------------------------------------------------------------------------- /rootfs/etc/php83/php-fpm.d/www.conf: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;; 2 | ; FPM Configuration ; 3 | ;;;;;;;;;;;;;;;;;;;;; 4 | 5 | [global] 6 | daemonize = no 7 | error_log = /tmp/php_error.log 8 | 9 | [www] 10 | listen = /run/php/php83-fpm.sock 11 | pm = dynamic 12 | pm.max_children = 15 13 | pm.start_servers = 2 14 | pm.min_spare_servers = 1 15 | pm.max_spare_servers = 6 16 | chdir = / 17 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/.s6-svscan/crash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | echo "crash s6" 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/.s6-svscan/finish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | echo "stop s6" 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/nginx/crash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | exit 1 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/nginx/finish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | exit 0 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/nginx/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | /usr/sbin/nginx 3 | s6-svscanctl -qz /etc/s6.d 4 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/php83/crash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | exit 1 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/php83/finish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | exit 0 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/php83/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | /usr/sbin/php-fpm83 3 | s6-svscanctl -qz /etc/s6.d 4 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/rtorrent/crash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | exit 1 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/rtorrent/finish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | exit 0 3 | -------------------------------------------------------------------------------- /rootfs/etc/s6.d/rtorrent/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | /usr/bin/rtorrent -I 3 | s6-svscanctl -qz /etc/s6.d 4 | -------------------------------------------------------------------------------- /rootfs/filebot/args_amc.txt: -------------------------------------------------------------------------------- 1 | music=y 2 | unsorted=y 3 | ut_kind=multi 4 | excludeList=amc.excludes 5 | musicFormat=/data/media/music/{n}/{fn} 6 | movieFormat=/data/media/movies/{n} ({y}) 7 | animeFormat=/data/media/animes/{n}/{e.pad(3)} - {t} 8 | unsortedFormat=/data/media/unsorted/{file.structurePathTail} 9 | seriesFormat=/data/media/series/{n}/season {s.pad(2)}/{s00e00} - {t} 10 | -------------------------------------------------------------------------------- /rootfs/home/torrent/.rtorrent.rc: -------------------------------------------------------------------------------- 1 | # logs 2 | log.open_file = "rtorrent", "/tmp/rtorrent.log" 3 | log.add_output = "critical", "rtorrent" 4 | log.add_output = "error", "rtorrent" 5 | 6 | # general 7 | system.daemon.set = true 8 | directory.default.set = 9 | session.path.set = /data/.session 10 | protocol.encryption.set = allow_incoming, try_outgoing, enable_retry 11 | 12 | # network 13 | network.scgi.open_local = /run/rtorrent/rtorrent.sock 14 | schedule2 = chmod_scgi_socket,0,0,"execute2=chmod,660,/run/rtorrent/rtorrent.sock" 15 | network.port_range.set = - 16 | network.port_random.set = no 17 | pieces.hash.on_completion.set = no 18 | 19 | trackers.use_udp.set = yes 20 | dht.mode.set = 21 | dht.port.set = 22 | protocol.pex.set = 23 | throttle.min_peers.normal.set = 1 24 | throttle.max_peers.normal.set = 100 25 | throttle.min_peers.seed.set = 1 26 | throttle.max_peers.seed.set = 50 27 | throttle.max_uploads.set = 15 28 | 29 | # divers 30 | encoding.add = utf8 31 | 32 | # scheduling 33 | execute2 = {sh,-c,/usr/bin/php /rutorrent/app/php/initplugins.php torrent &} 34 | schedule2 = watch_directory,1,10,"load.start=/data/.watch/*.torrent" 35 | schedule2 = untied_directory,1,10,"stop_untied=/data/.watch/*.torrent" 36 | schedule2 = espace_disque_insuffisant,15,60,close_low_diskspace=1000M 37 | -------------------------------------------------------------------------------- /rootfs/rutorrent/app/conf/config.php: -------------------------------------------------------------------------------- 1 | false, 13 | 'proto' => 'http', // 'http' or 'https' 14 | 'host' => 'PROXY_HOST_HERE', 15 | 'port' => 3128 16 | ); 17 | 18 | // for xmlrpc actions 19 | $rpcTimeOut = 5; // in seconds 20 | $rpcLogCalls = false; 21 | $rpcLogFaults = true; 22 | 23 | // for php 24 | $phpUseGzip = false; 25 | $phpGzipLevel = 2; 26 | 27 | $schedule_rand = 10; // rand for schedulers start, +0..X seconds 28 | 29 | $do_diagnostic = true; // Diagnose ruTorrent. Recommended to keep enabled, unless otherwise required. 30 | $al_diagnostic = true; // Diagnose auto-loader. Set to "false" to make composer plugins work. 31 | 32 | $log_file = '/tmp/rutorrent-app-errors.log'; // path to log file (comment or leave blank to disable logging) 33 | 34 | $saveUploadedTorrents = true; // Save uploaded torrents to profile/torrents directory or not 35 | $overwriteUploadedTorrents = false; // Overwrite existing uploaded torrents in profile/torrents directory or make unique name 36 | 37 | $topDirectory = '/data/downloads/'; // Upper available directory. Absolute path with trail slash. 38 | $forbidUserSettings = false; 39 | 40 | $scgi_port = 0; 41 | $scgi_host = 'unix:///run/rtorrent/rtorrent.sock'; 42 | 43 | // For web->rtorrent link through unix domain socket 44 | // (scgi_local in rtorrent conf file), change variables 45 | // above to something like this: 46 | // 47 | // $scgi_port = 0; 48 | // $scgi_host = "unix:///tmp/rpc.socket"; 49 | 50 | $XMLRPCMountPoint = "/RPC2"; // DO NOT DELETE THIS LINE!!! DO NOT COMMENT THIS LINE!!! 51 | 52 | $throttleMaxSpeed = 327625*1024; // DO NOT EDIT THIS LINE!!! DO NOT COMMENT THIS LINE!!! 53 | // Can't be greater then 327625*1024 due to limitation in libtorrent ResourceManager::set_max_upload_unchoked function. 54 | 55 | $pathToExternals = array( 56 | "php" => '/usr/bin/php83', // Something like /usr/bin/php. If empty, will be found in PATH. 57 | "curl" => '/usr/local/bin/curl', // Something like /usr/bin/curl. If empty, will be found in PATH. 58 | "gzip" => '/usr/bin/gzip', // Something like /usr/bin/gzip. If empty, will be found in PATH. 59 | "id" => '/usr/bin/id', // Something like /usr/bin/id. If empty, will be found in PATH. 60 | "stat" => '/usr/bin/stat', // Something like /usr/bin/stat. If empty, will be found in PATH. 61 | "pgrep" => '/usr/bin/pgrep', 62 | ); 63 | 64 | $localHostedMode = true; // Set to true if rTorrent is hosted on the SAME machine as ruTorrent 65 | 66 | $localhosts = array( // list of local interfaces 67 | "127.0.0.1", 68 | "localhost", 69 | ); 70 | 71 | $profilePath = '../../share'; // Path to user profiles 72 | $profileMask = 0777; // Mask for files and directory creation in user profiles. 73 | // Both Webserver and rtorrent users must have read-write access to it. 74 | // For example, if Webserver and rtorrent users are in the same group then the value may be 0770. 75 | 76 | $tempDirectory = null; // Temp directory. Absolute path with trail slash. If null, then autodetect will be used. 77 | 78 | $canUseXSendFile = false; // If true then use X-Sendfile feature if it exist 79 | 80 | $locale = "UTF8"; 81 | 82 | $enableCSRFCheck = false; // If true then Origin and Referer will be checked 83 | $enabledOrigins = array(); // List of enabled domains for CSRF check (only hostnames, without protocols, port etc.). 84 | // If empty, then will retrieve domain from HTTP_HOST / HTTP_X_FORWARDED_HOST 85 | -------------------------------------------------------------------------------- /rootfs/rutorrent/app/php/share/torrents/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mondediefr/docker-rutorrent/6eef98195eda143fcd9b01080fb53d1c3551c2ae/rootfs/rutorrent/app/php/share/torrents/.gitkeep -------------------------------------------------------------------------------- /rootfs/rutorrent/app/plugins/create/conf.php: -------------------------------------------------------------------------------- 1 | > "${file}" 11 | chown "${UID}:${GID}" "${file}" 12 | chmod 640 "${file}" 13 | echo "The password was generated for the http user: ${username}" 14 | else 15 | sed -e "s|^${username}:.*|${username}:${passwd}|g" -i "${file}" 16 | chown "${UID}:${GID}" "${file}" 17 | chmod 640 "${file}" 18 | echo "The password has been updated for the http user: ${username}" 19 | fi 20 | fi 21 | -------------------------------------------------------------------------------- /rootfs/usr/local/bin/postdl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | TORRENT_PATH="${1}" 4 | TORRENT_NAME="${2}" 5 | 6 | /filebot/filebot.sh \ 7 | --lang "${FILEBOT_LANG}" \ 8 | -script fn:amc \ 9 | --output "/data/media" \ 10 | --action "${FILEBOT_RENAME_METHOD}" \ 11 | --conflict "${FILEBOT_CONFLICT}" \ 12 | -non-strict \ 13 | --log-file /tmp/filebot-amc.log \ 14 | --def @/filebot/args_amc.txt \ 15 | --def ut_dir="${TORRENT_PATH}" \ 16 | --def ut_title="${TORRENT_NAME}" 2>> /tmp/filebot-error.log 17 | -------------------------------------------------------------------------------- /rootfs/usr/local/bin/postrm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | sleep 10 # wait 10 sec (file removing) 4 | find /data/media -xtype l -delete >> /tmp/filebot-cleaner.log 2>&1 5 | find /data/media -type d -empty -delete >> /tmp/filebot-cleaner.log 2>&1 6 | -------------------------------------------------------------------------------- /rootfs/usr/local/bin/startup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | CSI="\033[" 4 | CEND="${CSI}0m" 5 | CRED="${CSI}1;31m" 6 | CGREEN="${CSI}1;32m" 7 | CYELLOW="${CSI}1;33m" 8 | CBLUE="${CSI}1;34m" 9 | 10 | f_log() { 11 | LOG_TYPE="${1}" 12 | LOG_MESSAGE="${2}" 13 | 14 | case "${LOG_TYPE}" in 15 | "INF") 16 | echo -en "${CBLUE}[$(date +%Y/%m/%d-%H:%M:%S)] ${LOG_MESSAGE}${CEND}" 17 | ;; 18 | "SUC") 19 | echo -e "${CGREEN}${LOG_MESSAGE}${CEND}" 20 | ;; 21 | "WRN") 22 | echo -e "${CYELLOW}[$(date +%Y/%m/%d-%H:%M:%S)] ${LOG_MESSAGE}${CEND}" 23 | ;; 24 | "ERR") 25 | echo -e "${CRED}[$(date +%Y/%m/%d-%H:%M:%S)] ${LOG_MESSAGE}${CEND}" 26 | ;; 27 | esac 28 | } 29 | 30 | f_log INF "Create torrent user... " 31 | 32 | if [ -z "$(grep :${GID}: /etc/group)" ]; then 33 | addgroup -g "${GID}" torrent 34 | fi 35 | 36 | if [ -z "$(grep :${UID}: /etc/passwd)" ]; then 37 | group="$(grep :${GID}: /etc/group | cut -f 1 -d :)" 38 | adduser -h /home/torrent -s /bin/sh -G "${group}" -D -u "${UID}" torrent 39 | f_log SUC "done" # success of Create torrent user 40 | elif [ -e /config/rtorrent/.rtorrent.rc ]; then 41 | f_log SUC "done" # success of Create torrent user 42 | else 43 | echo "" 44 | f_log ERR "Unable to create torrent user, you cannot use UID ${UID}" 45 | exit 1 46 | fi 47 | 48 | f_log INF "Create volume folders... " 49 | mkdir -p /data/.watch /data/.session "${DOWNLOAD_DIRECTORY}" 50 | mkdir -p /config/rtorrent /config/rutorrent /config/custom_themes /config/custom_plugins 51 | f_log SUC "done" # success of Create volume folders 52 | 53 | f_log INF "Generate configuration... " 54 | 55 | # Externalize rutorrent configuration 56 | if [ -d /config/rutorrent/conf ]; then 57 | rm -rf /rutorrent/app/conf 58 | ln -s /config/rutorrent/conf /rutorrent/app/conf 59 | else 60 | mv /rutorrent/app/conf /config/rutorrent 61 | ln -s /config/rutorrent/conf /rutorrent/app/conf 62 | fi 63 | 64 | # Externalize rutorrent share 65 | if [ -d /config/rutorrent/share ]; then 66 | rm -rf /rutorrent/app/share 67 | ln -s /config/rutorrent/share /rutorrent/app/share 68 | else 69 | mv /rutorrent/app/share /config/rutorrent 70 | ln -s /config/rutorrent/share /rutorrent/app/share 71 | fi 72 | 73 | # Add custom plugins 74 | [ "$(ls /config/custom_plugins)" ] && for plugin in $(ls /config/custom_plugins); do 75 | if [ ! -d "/rutorrent/app/plugins/${plugin}" ]; then 76 | ln -s "/config/custom_plugins/${plugin}" "/rutorrent/app/plugins/${plugin}" 77 | fi 78 | done 79 | 80 | # Add custom themes 81 | [ "$(ls /config/custom_themes)" ] && for theme in $(ls /config/custom_themes); do 82 | if [ ! -d "/rutorrent/app/plugins/theme/themes/${theme}" ]; then 83 | ln -s "/config/custom_themes/${theme}" "/rutorrent/app/plugins/theme/themes/${theme}" 84 | fi 85 | done 86 | 87 | sed -e "s||${DOWNLOAD_DIRECTORY}|g" -e "s||${MODE_DHT}|g" -e "s||${PORT_DHT}|g" -e "s||${PEER_EXCHANGE}|g" -e "s||${PORT_RTORRENT}|g" -i /home/torrent/.rtorrent.rc 88 | 89 | # Externalize rtorrent configuration 90 | if [ -e /config/rtorrent/.rtorrent.rc ]; then 91 | ln -sf /config/rtorrent/.rtorrent.rc /home/torrent/.rtorrent.rc 92 | else 93 | mv /home/torrent/.rtorrent.rc /config/rtorrent/.rtorrent.rc 94 | ln -s /config/rtorrent/.rtorrent.rc /home/torrent/.rtorrent.rc 95 | fi 96 | 97 | f_log SUC "done" # success of Generate configuration 98 | 99 | f_log INF "HTTP authentication configuration... " 100 | 101 | # Add http authentication 102 | if [ "${HTTP_AUTH}" = true ]; then 103 | mkdir -p /config/nginx/passwd 104 | sed -e "s||auth_basic \"rutorrent\";\n auth_basic_user_file \"/config/nginx/passwd/rutorrent_passwd\";|g" -i /etc/nginx/nginx.conf 105 | else 106 | sed "//d" -i /etc/nginx/nginx.conf 107 | fi 108 | 109 | f_log SUC "done" # success of HTTP authentication configuration 110 | 111 | # Filebot configuration 112 | if [ -e /filebot/filebot.sh ]; then 113 | f_log INF "Configuration of filebot... " 114 | mkdir -p /data/media /config/filebot 115 | 116 | # Externalize filebot data folder 117 | if [ -d /config/filebot/data ]; then 118 | rm -rf /filebot/data 119 | ln -s /config/filebot/data /filebot/data 120 | else 121 | mkdir -p /config/filebot/data 122 | rm -rf /filebot/data 123 | ln -s /config/filebot/data /filebot/data 124 | fi 125 | 126 | # Add license file 127 | if [ ! -e "${FILEBOT_LICENSE}" ]; then 128 | f_log ERR "License filebot file does not exist" 129 | exit 1 130 | elif [ ! -e /filebot/data/.license ]; then 131 | /filebot/filebot.sh --license "${FILEBOT_LICENSE}" 132 | fi 133 | 134 | # Externalize args_amc.txt file 135 | if [ -e /config/filebot/args_amc.txt ]; then 136 | ln -sf /config/filebot/args_amc.txt /filebot/args_amc.txt 137 | else 138 | mv /filebot/args_amc.txt /config/filebot/args_amc.txt 139 | ln -s /config/filebot/args_amc.txt /filebot/args_amc.txt 140 | fi 141 | 142 | # Custom postdl script 143 | if [ -e /config/filebot/postdl ]; then 144 | ln -sf /config/filebot/postdl /usr/local/bin/postdl 145 | fi 146 | 147 | if [ -z "$(grep ^method.set_key.*event.download.finished,filebot /home/torrent/.rtorrent.rc)" ]; then 148 | echo 'method.set_key = event.download.finished,filebot,"execute2=/usr/local/bin/postdl,$d.base_path=,$d.name="' >> /home/torrent/.rtorrent.rc 149 | fi 150 | 151 | if [ -z "$(grep ^method.set_key.*event.download.erased,filebot_cleaner /home/torrent/.rtorrent.rc)" ]; then 152 | echo 'method.set_key = event.download.erased,filebot_cleaner,"execute2=/usr/local/bin/postrm"' >> /home/torrent/.rtorrent.rc 153 | fi 154 | 155 | find /filebot ! -user "${UID}" -exec chown -h "${UID}:${GID}" {} \; 156 | chmod +x /usr/local/bin/postdl /usr/local/bin/postrm 157 | f_log SUC "done" # success of Configuration of filebot 158 | fi 159 | 160 | f_log INF "Update old configurations... " 161 | /usr/local/bin/update-config 162 | f_log SUC "done" # success of Update old configurations 163 | 164 | f_log INF "Apply system permissions... " 165 | 166 | for folder in /config /rutorrent /rutorrent/app/php/share/torrents /home/torrent /var/lib/nginx /var/log /etc/nginx /etc/php83 /tmp /etc/s6.d /run; do 167 | find "${folder}" ! -user "${UID}" -exec chown -h "${UID}:${GID}" {} \; 168 | done 169 | 170 | find /etc/s6.d -type f -exec chmod +x {} \; 171 | f_log SUC "done" # success of Apply system permissions 172 | 173 | # set perm 174 | chown "${UID}:${GID}" /data/.watch /data/.session "${DOWNLOAD_DIRECTORY}" 175 | 176 | if [ "${CHECK_PERM_DATA}" = true ]; then 177 | f_log INF "Apply data permissions... " 178 | find /data ! -user "${UID}" -exec chown -h "${UID}:${GID}" {} \; 179 | f_log SUC "done" # success of Apply data permissions 180 | fi 181 | 182 | rm -f /data/.session/rtorrent.lock 183 | 184 | exec su-exec "${UID}":"${GID}" "$@" 185 | -------------------------------------------------------------------------------- /rootfs/usr/local/bin/update-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # replace d.directory by d.base_path 4 | sed -e "s|/usr/local/bin/postdl,\$d\.directory|/usr/local/bin/postdl,\$d\.base_path|g" -i /config/rtorrent/.rtorrent.rc 5 | 6 | # replace /RPC by /RPC2 7 | sed -e "s|'\/RPC'|'\/RPC2'|g" -i /config/rutorrent/conf/config.php 8 | 9 | # update to php83 10 | sed -e "s|'\/usr\/bin\/php82'|'\/usr\/bin\/php83'|g" -i /config/rutorrent/conf/config.php 11 | 12 | # replace new location of curl 13 | sed -i -e "s/\/usr\/bin\/curl/\/usr\/local\/bin\/curl/g" /config/rutorrent/conf/config.php 14 | 15 | # replace download directory 16 | sed -i "s|^\(\s*\$topDirectory\s*=\s*\)\S*|\\1'${DOWNLOAD_DIRECTORY}';|" /config/rutorrent/conf/config.php --------------------------------------------------------------------------------