├── .gitattributes ├── .github └── workflows │ ├── better-cloudflare-ip.yml │ ├── chinesesubfinder.yml │ ├── csf-cross-builder.yml │ ├── ddns.yml │ ├── iperf3.yml │ ├── iyuuautoreseed.yml │ ├── iyuuplus.yml │ ├── jellyfin.yml │ ├── libtorrent-rasterbar-buildx.yml │ ├── libtorrent-rasterbar-mirror.yml │ ├── loop.yml │ ├── ncmdump.yml │ ├── nginxwebui.yml │ ├── nodejs.yml │ ├── pve-kernel.yml │ ├── python.yml │ ├── qbittorrent-buildx.yml │ ├── qbittorrent-buildx2.yml │ ├── qbittorrent-edge.yml │ ├── qbittorrent-iyuu.yml │ ├── qbittorrent-mirror.yml │ ├── subfinder.yml │ └── tieba-cloud-sign.yml ├── .gitignore ├── better-cloudflare-ip ├── .dockerignore ├── Dockerfile ├── buildx.sh └── readme.md ├── chinesesubfinder ├── .dockerignore ├── .gitignore ├── Dockerfile ├── buildx.sh ├── entrypoint.sh ├── init.sh └── readme.md ├── csf-cross-builder ├── Dockerfile └── readme.md ├── ddns ├── .dockerignore ├── Dockerfile ├── buildx.sh └── readme.md ├── iperf3 ├── .dockerignore ├── Dockerfile ├── buildx.sh └── readme.md ├── iyuuautoreseed ├── .dockerignore ├── Dockerfile ├── entrypoint.sh └── readme.md ├── iyuuplus ├── .dockerignore ├── Dockerfile ├── buildx.sh ├── entrypoint.sh └── readme.md ├── libtorrent-rasterbar ├── .dockerignore ├── .gitignore ├── Dockerfile ├── buildx-build.sh ├── buildx.sh ├── readme.md └── version.sh ├── license ├── loop ├── Dockerfile ├── bin │ ├── aarch64-unknown-linux-musl │ │ └── loop │ ├── armv7-unknown-linux-musleabihf │ │ └── loop │ └── x86_64-unknown-linux-musl │ │ └── loop └── readme.md ├── ncmdump ├── .dockerignore ├── Dockerfile └── readme.md ├── nginxwebui ├── .dockerignore ├── .gitignore ├── Dockerfile ├── buildx.sh ├── entrypoint.sh ├── readme.md └── settings.xml ├── nodejs ├── .dockerignore ├── Dockerfile ├── buildx.sh ├── readme.md └── s6-overlay │ └── etc │ └── services.d │ ├── crond │ └── run │ └── refresh-cron │ ├── refresh-cron │ └── run ├── opbuilder ├── Dockerfile ├── README.md ├── compose.yml └── entrypoint.sh ├── pagermaid └── Dockerfile ├── python ├── .dockerignore ├── Dockerfile ├── buildx.sh ├── readme.md └── s6-overlay │ └── etc │ └── services.d │ ├── crond │ └── run │ └── refresh-cron │ ├── refresh-cron │ └── run ├── qbittorrent ├── .dockerignore ├── .gitignore ├── Dockerfile ├── Dockerfile.4.3.9 ├── Dockerfile.edge ├── diy │ ├── diy.sh │ └── readme.md ├── pictures │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.png │ └── notify.png ├── readme.md ├── root │ ├── etc │ │ └── entrypoint.d │ │ │ ├── 10-add-pkg.sh │ │ │ ├── 20-mkdir.sh │ │ │ ├── 30-config.sh │ │ │ ├── 40-fix-user.sh │ │ │ └── 50-crontab.sh │ └── usr │ │ └── local │ │ └── bin │ │ ├── alter-limits │ │ ├── auto-cat │ │ ├── change-tracker │ │ ├── del-unseed-dir │ │ ├── detect-ip │ │ ├── dl-finish │ │ ├── entrypoint.sh │ │ ├── gen-dup │ │ ├── gen-qb-passwd │ │ ├── health-check │ │ ├── iyuu-help │ │ ├── nice-size │ │ ├── nice-time │ │ ├── notify │ │ ├── remove-tracker │ │ ├── report-seed-files │ │ ├── report-unseed-files │ │ ├── share │ │ └── tracker-error └── root2 │ └── etc │ └── entrypoint.d │ ├── 60-crontab2.sh │ └── 70-iyuu.sh ├── subfinder ├── .dockerignore ├── Dockerfile ├── buildx.sh ├── entrypoint.sh └── readme.md ├── team ├── Dockerfile ├── docker-compose.yml └── docker-entrypoint.sh └── tieba-cloud-sign ├── .dockerignore ├── Dockerfile ├── buildx.sh ├── readme.md └── s6-overlay └── etc ├── cont-init.d ├── 10-fix-owner ├── 20-fix-config └── 30-set-crontab └── services.d ├── caddy └── run ├── crond └── run └── php-fpm └── run /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | loop binary 3 | *.png binary 4 | -------------------------------------------------------------------------------- /.github/workflows/better-cloudflare-ip.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:better-cloudflare-ip 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:better-cloudflare-ip 9 | env: 10 | IMAGE_NAME: better-cloudflare-ip 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Set Up QEMU 18 | uses: docker/setup-qemu-action@v2 19 | 20 | - 21 | name: Set Up Buildx 22 | uses: docker/setup-buildx-action@v2 23 | 24 | - 25 | name: Login DockerHub 26 | uses: docker/login-action@v2 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - 32 | name: Set Up Cache 33 | uses: actions/cache@v2 34 | id: buildx-cache 35 | with: 36 | path: /tmp/.buildx-cache 37 | key: ${{ runner.os }}-buildx 38 | 39 | - 40 | name: Buildx 41 | uses: docker/build-push-action@v3 42 | with: 43 | context: ${{ env.IMAGE_NAME }} 44 | file: ${{ env.IMAGE_NAME }}/Dockerfile 45 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 46 | push: true 47 | tags: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 48 | 49 | - 50 | name: Update DockerHub Description 51 | uses: christian-korneck/update-container-description-action@v1 52 | env: 53 | DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} 54 | DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} 55 | with: 56 | destination_container_repo: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 57 | provider: dockerhub 58 | readme_file: ./${{ env.IMAGE_NAME }}/readme.md 59 | -------------------------------------------------------------------------------- /.github/workflows/chinesesubfinder.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:chinesesubfinder 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:chinesesubfinder 9 | env: 10 | IMAGE_NAME: chinesesubfinder 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Prepare 18 | id: prepare 19 | run: | 20 | version=$(curl -s https://api.github.com/repos/allanpk716/ChineseSubFinder/tags | jq -r '.[].name' | grep -Evi 'Beta|Docker' | head -1 | sed 's|v||') 21 | echo ::set-output name=version::${version} 22 | 23 | - 24 | name: Set Up QEMU 25 | uses: docker/setup-qemu-action@v2 26 | 27 | - 28 | name: Set Up Buildx 29 | uses: docker/setup-buildx-action@v2 30 | 31 | - 32 | name: Login DockerHub 33 | uses: docker/login-action@v2 34 | with: 35 | username: ${{ secrets.DOCKER_USERNAME }} 36 | password: ${{ secrets.DOCKER_PASSWORD }} 37 | 38 | - 39 | name: Set Up Cache 40 | uses: actions/cache@v2 41 | id: buildx-cache 42 | with: 43 | path: /tmp/.buildx-cache 44 | key: ${{ runner.os }}-buildx 45 | 46 | - 47 | name: Go Build 48 | working-directory: ${{ env.IMAGE_NAME }} 49 | run: | 50 | docker run --rm -e VERSION=${{ steps.prepare.outputs.version }} -v $(pwd)/go:/root/go -v $(pwd)/init.sh:/init.sh --entrypoint "/init.sh" nevinee/csf-cross-builder 51 | 52 | - 53 | name: Docker Buildx 54 | uses: docker/build-push-action@v3 55 | with: 56 | context: ${{ env.IMAGE_NAME }} 57 | file: ${{ env.IMAGE_NAME }}/Dockerfile 58 | platforms: | 59 | linux/386 60 | linux/amd64 61 | linux/arm64 62 | linux/arm/v7 63 | push: true 64 | build-args: | 65 | VERSION=${{ steps.prepare.outputs.version }} 66 | tags: | 67 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 68 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 69 | -------------------------------------------------------------------------------- /.github/workflows/csf-cross-builder.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:csf-cross-builder 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | name: 构建镜像:csf-cross-builder 10 | env: 11 | IMAGE_NAME: csf-cross-builder 12 | steps: 13 | - 14 | name: Checkout 15 | uses: actions/checkout@master 16 | 17 | - 18 | name: Login DockerHub 19 | uses: docker/login-action@v2 20 | with: 21 | username: ${{ secrets.DOCKER_USERNAME }} 22 | password: ${{ secrets.DOCKER_PASSWORD }} 23 | 24 | - 25 | name: Build 26 | uses: docker/build-push-action@v3 27 | with: 28 | context: ${{ env.IMAGE_NAME }} 29 | file: ${{ env.IMAGE_NAME }}/Dockerfile 30 | push: true 31 | tags: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 32 | -------------------------------------------------------------------------------- /.github/workflows/ddns.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:ddns 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:ddns 9 | env: 10 | IMAGE_NAME: ddns 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Prepare 18 | id: prepare 19 | run: | 20 | version=$(curl -s https://api.github.com/repos/NewFuture/DDNS/releases/latest | jq -r .tag_name | sed "s/v//") 21 | echo ::set-output name=version::${version} 22 | 23 | - 24 | name: Set Up QEMU 25 | uses: docker/setup-qemu-action@v2 26 | 27 | - 28 | name: Set Up Buildx 29 | uses: docker/setup-buildx-action@v2 30 | 31 | - 32 | name: Login DockerHub 33 | uses: docker/login-action@v2 34 | with: 35 | username: ${{ secrets.DOCKER_USERNAME }} 36 | password: ${{ secrets.DOCKER_PASSWORD }} 37 | 38 | - 39 | name: Set Up Cache 40 | uses: actions/cache@v2 41 | id: buildx-cache 42 | with: 43 | path: /tmp/.buildx-cache 44 | key: ${{ runner.os }}-buildx 45 | 46 | - 47 | name: Buildx 48 | uses: docker/build-push-action@v3 49 | with: 50 | context: ${{ env.IMAGE_NAME }} 51 | file: ${{ env.IMAGE_NAME }}/Dockerfile 52 | platforms: linux/amd64,linux/arm64,linux/arm/v7 53 | push: true 54 | tags: | 55 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 56 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 57 | -------------------------------------------------------------------------------- /.github/workflows/iperf3.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:iperf3 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:iperf3 9 | env: 10 | IMAGE_NAME: iperf3 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Prepare 18 | id: prepare 19 | run: | 20 | version=$(curl -s https://api.github.com/repos/esnet/iperf/tags | jq -r .[].name | grep -m1 -P "^[\d\.]+$") 21 | echo ::set-output name=version::${version} 22 | 23 | - 24 | name: Set Up QEMU 25 | uses: docker/setup-qemu-action@v2 26 | 27 | - 28 | name: Set Up Buildx 29 | uses: docker/setup-buildx-action@v2 30 | 31 | - 32 | name: Login DockerHub 33 | uses: docker/login-action@v2 34 | with: 35 | username: ${{ secrets.DOCKER_USERNAME }} 36 | password: ${{ secrets.DOCKER_PASSWORD }} 37 | 38 | - 39 | name: Set Up Cache 40 | uses: actions/cache@v2 41 | id: buildx-cache 42 | with: 43 | path: /tmp/.buildx-cache 44 | key: ${{ runner.os }}-buildx 45 | 46 | - 47 | name: Buildx 48 | uses: docker/build-push-action@v3 49 | with: 50 | context: ${{ env.IMAGE_NAME }} 51 | file: ${{ env.IMAGE_NAME }}/Dockerfile 52 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 53 | push: true 54 | build-args: | 55 | ALPINE_VERSION=latest 56 | VERSION=${{ steps.prepare.outputs.version }} 57 | tags: | 58 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 59 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 60 | 61 | - 62 | name: Update DockerHub Description 63 | uses: christian-korneck/update-container-description-action@v1 64 | env: 65 | DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} 66 | DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} 67 | with: 68 | destination_container_repo: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 69 | provider: dockerhub 70 | readme_file: ./${{ env.IMAGE_NAME }}/readme.md 71 | -------------------------------------------------------------------------------- /.github/workflows/iyuuautoreseed.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:iyuuautoreseed 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:iyuuautoreseed 9 | env: 10 | IMAGE_NAME: iyuuautoreseed 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Set Up QEMU 18 | uses: docker/setup-qemu-action@v2 19 | 20 | - 21 | name: Set Up Buildx 22 | uses: docker/setup-buildx-action@v2 23 | 24 | - 25 | name: Login DockerHub 26 | uses: docker/login-action@v2 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - 32 | name: Set Up Cache 33 | uses: actions/cache@v2 34 | id: buildx-cache 35 | with: 36 | path: /tmp/.buildx-cache 37 | key: ${{ runner.os }}-buildx 38 | 39 | - 40 | name: Buildx 41 | uses: docker/build-push-action@v3 42 | with: 43 | context: ${{ env.IMAGE_NAME }} 44 | file: ${{ env.IMAGE_NAME }}/Dockerfile 45 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/s390x 46 | push: true 47 | tags: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 48 | - 49 | name: Update DockerHub Description 50 | uses: peter-evans/dockerhub-description@v2 51 | with: 52 | username: ${{ secrets.DOCKER_USERNAME }} 53 | password: ${{ secrets.DOCKER_PASSWORD }} 54 | repository: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 55 | readme-filepath: ./${{ env.IMAGE_NAME }}/readme.md -------------------------------------------------------------------------------- /.github/workflows/iyuuplus.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:iyuuplus 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:iyuuplus 9 | env: 10 | IMAGE_NAME: iyuuplus 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Prepare 18 | id: prepare 19 | run: | 20 | version=$(curl -s https://raw.githubusercontent.com/ledccn/IYUUPlus/master/app/functions.php | grep -P "return \'(\d+\.?){3,4}\'" | head -1 | perl -pe "s|[\D\.]+((\d+\.?){3,4}).*|\1|") 21 | echo ::set-output name=version::${version} 22 | 23 | - 24 | name: Set Up QEMU 25 | uses: docker/setup-qemu-action@v2 26 | 27 | - 28 | name: Set Up Buildx 29 | uses: docker/setup-buildx-action@v2 30 | 31 | - 32 | name: Login DockerHub 33 | uses: docker/login-action@v2 34 | with: 35 | username: ${{ secrets.DOCKER_USERNAME }} 36 | password: ${{ secrets.DOCKER_PASSWORD }} 37 | 38 | - 39 | name: Set Up Cache 40 | uses: actions/cache@v2 41 | id: buildx-cache 42 | with: 43 | path: /tmp/.buildx-cache 44 | key: ${{ runner.os }}-buildx 45 | 46 | - 47 | name: Buildx 48 | uses: docker/build-push-action@v3 49 | with: 50 | context: ${{ env.IMAGE_NAME }} 51 | file: ${{ env.IMAGE_NAME }}/Dockerfile 52 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 53 | push: true 54 | tags: | 55 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 56 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 57 | 58 | - 59 | name: Update DockerHub Description 60 | uses: christian-korneck/update-container-description-action@v1 61 | env: 62 | DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} 63 | DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} 64 | with: 65 | destination_container_repo: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 66 | provider: dockerhub 67 | readme_file: ./${{ env.IMAGE_NAME }}/readme.md 68 | -------------------------------------------------------------------------------- /.github/workflows/jellyfin.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:jellyfin 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | ubuntu_version: 6 | description: '要基于ubuntu的什么版本构建docker,默认是jammy' 7 | required: false 8 | default: 'jammy' 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: 构建镜像:jellyfin 14 | env: 15 | IMAGE_NAME: jellyfin 16 | steps: 17 | - 18 | name: Checkout 19 | uses: actions/checkout@master 20 | 21 | - 22 | name: Prepare 23 | id: prepare 24 | run: | 25 | version=$(curl -s https://api.github.com/repos/jellyfin/jellyfin/releases/latest | jq -r .tag_name | sed "s/v//") 26 | echo ::set-output name=version::${version} 27 | 28 | - 29 | name: Login DockerHub 30 | uses: docker/login-action@v2 31 | with: 32 | username: ${{ secrets.DOCKER_USERNAME }} 33 | password: ${{ secrets.DOCKER_PASSWORD }} 34 | 35 | - 36 | name: Build 37 | uses: docker/build-push-action@v3 38 | with: 39 | context: ${{ env.IMAGE_NAME }} 40 | file: ${{ env.IMAGE_NAME }}/Dockerfile 41 | platforms: linux/amd64 42 | push: true 43 | build-args: | 44 | CODENAME=${{ github.event.inputs.ubuntu_version }} 45 | tags: | 46 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 47 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 48 | 49 | - 50 | name: Update DockerHub Description 51 | uses: christian-korneck/update-container-description-action@v1 52 | env: 53 | DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} 54 | DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} 55 | with: 56 | destination_container_repo: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 57 | provider: dockerhub 58 | readme_file: ./${{ env.IMAGE_NAME }}/readme.md 59 | -------------------------------------------------------------------------------- /.github/workflows/libtorrent-rasterbar-buildx.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:libtorrent-rasterbar 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: '要构建的版本,可以为v1/v2版,如不输入则默认去检测最新的正式版' 8 | required: false 9 | default: '' 10 | repository_dispatch: 11 | types: libtorrent-rasterbar 12 | 13 | env: 14 | ## 镜像名,也是git仓库中的文件夹名 15 | IMAGE_NAME: libtorrent-rasterbar 16 | ## Dockerfile文件名称,在这里修改 17 | DOCKERFILE_NAME: Dockerfile.GithubAction 18 | 19 | jobs: 20 | base: 21 | runs-on: ubuntu-latest 22 | name: 基本信息 23 | outputs: 24 | full_version: ${{ steps.base.outputs.full_version }} 25 | multitags: ${{ steps.base.outputs.multitags }} 26 | matrix: ${{ steps.base.outputs.matrix }} 27 | build_args: ${{ steps.base.outputs.build_args }} 28 | steps: 29 | - 30 | name: Set Matrix And Base Infomation 31 | id: base 32 | run: | 33 | FULL_VERSION=${{ github.event.inputs.version }} 34 | 35 | ######################### ↓特殊部分↓ ######################### 36 | if [[ -z ${FULL_VERSION} ]]; then 37 | FULL_VERSION=$(curl -s https://api.github.com/repos/arvidn/libtorrent/tags | jq -r .[]."name" | grep -m1 -E "v([0-9]{1,2}\.?){3,4}$" | sed "s/v//") 38 | fi 39 | MAJOR_VERSION=$(echo ${FULL_VERSION} | perl -pe "s|^(\d+)\..+|\1|") 40 | MULTITAGS="${FULL_VERSION} ${MAJOR_VERSION}" 41 | ######################### ↑特殊部分↑ ######################### 42 | 43 | ## 要构建哪些平台的镜像,在这里修改 44 | MATRIX='{"architecture":["linux/386", "linux/amd64", "linux/arm64", "linux/arm/v7", "linux/arm/v6", "linux/ppc64le", "linux/s390x"]}' 45 | 46 | echo ::set-output name=full_version::${FULL_VERSION} 47 | echo ::set-output name=multitags::${MULTITAGS} 48 | echo ::set-output name=matrix::${MATRIX} 49 | 50 | ######################### ↓特殊部分↓ ######################### 51 | echo ::set-output name=build_args_LIBTORRENT_VERSION::LIBTORRENT_VERSION=${FULL_VERSION} 52 | ######################### ↑特殊部分↑ ######################### 53 | 54 | build: 55 | needs: base 56 | runs-on: ubuntu-latest 57 | name: 并行构建 58 | timeout-minutes: 150 59 | strategy: 60 | matrix: ${{ fromJSON(needs.base.outputs.matrix) }} 61 | steps: 62 | - 63 | name: Checkout 64 | uses: actions/checkout@master 65 | 66 | - 67 | name: Prepare 68 | id: prep 69 | run: | 70 | DOCKERHUB_REPOSITORY="${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME}" 71 | FULL_VERSION="${{ needs.base.outputs.full_version }}" 72 | ARCH="${{ matrix.architecture }}" 73 | TAGS="${DOCKERHUB_REPOSITORY}:${FULL_VERSION}-$(echo ${ARCH} | perl -pe '{s|linux/||g; s|/|-|g}')" 74 | JNPROC=$(nproc) 75 | 76 | echo ::set-output name=tags::${TAGS} 77 | echo ::set-output name=build_args_JNPROC::JNPROC=${JNPROC} 78 | 79 | - 80 | name: Set Up QEMU 81 | uses: docker/setup-qemu-action@v2 82 | 83 | - 84 | name: Set Up Buildx 85 | uses: docker/setup-buildx-action@v2 86 | 87 | - 88 | name: Login DockerHub 89 | uses: docker/login-action@v2 90 | with: 91 | username: ${{ secrets.DOCKER_USERNAME }} 92 | password: ${{ secrets.DOCKER_PASSWORD }} 93 | 94 | - 95 | name: Set Up Cache 96 | uses: actions/cache@v2 97 | id: buildx-cache 98 | with: 99 | path: /tmp/.buildx-cache 100 | key: ${{ runner.os }}-buildx 101 | 102 | - 103 | name: Buildx 104 | uses: docker/build-push-action@v3 105 | with: 106 | context: ${{ env.IMAGE_NAME }} 107 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME }} 108 | platforms: ${{ matrix.architecture }} 109 | push: true 110 | build-args: | 111 | ${{ needs.base.outputs.build_args_LIBTORRENT_VERSION }} 112 | ${{ steps.prep.outputs.build_args_JNPROC }} 113 | tags: ${{ steps.prep.outputs.tags }} 114 | 115 | maintain: 116 | needs: [base, build] 117 | runs-on: ubuntu-latest 118 | name: 信息维护 119 | steps: 120 | - 121 | name: Checkout 122 | uses: actions/checkout@master 123 | 124 | - 125 | name: Login DockerHub 126 | uses: docker/login-action@v2 127 | with: 128 | username: ${{ secrets.DOCKER_USERNAME }} 129 | password: ${{ secrets.DOCKER_PASSWORD }} 130 | 131 | - 132 | name: Create And Push Manifest 133 | env: 134 | DOCKER_CLI_EXPERIMENTAL: enabled 135 | run: | 136 | DOCKERHUB_REPOSITORY="${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME}" 137 | FULL_VERSION="${{ needs.base.outputs.full_version }}" 138 | MATRIX='${{ needs.base.outputs.matrix }}' 139 | ALL_ARCH=( $(echo ${MATRIX} | jq -r .architecture[] | perl -pe '{s|linux/||g; s|/|-|g}') ) 140 | MULTITAGS="${{ needs.base.outputs.multitags }}" 141 | 142 | echo ALL_ARCH[@]=${ALL_ARCH[@]} 143 | 144 | IMAGES=() 145 | for arch in ${ALL_ARCH[@]}; do 146 | IMAGES+=( "${DOCKERHUB_REPOSITORY}:${FULL_VERSION}-${arch}" ) 147 | done 148 | 149 | echo IMAGES[@]=${IMAGES[@]} 150 | 151 | for tag in ${MULTITAGS}; do 152 | docker manifest create "${DOCKERHUB_REPOSITORY}:${tag}" "${IMAGES[@]}" 153 | done 154 | 155 | echo MULTITAGS=${MULTITAGS} 156 | 157 | for tag in ${MULTITAGS}; do 158 | docker manifest push --purge "${DOCKERHUB_REPOSITORY}:${tag}" 159 | done 160 | 161 | deltag: 162 | needs: [base, maintain] 163 | runs-on: ubuntu-latest 164 | name: 删除标签 165 | steps: 166 | - 167 | ## 参考https://github.com/xaynetwork/xaynet/blob/master/.github/workflows/dockerhub-cleanup.yml 168 | name: Setup Hub-tool 169 | env: 170 | DHUSER: ${{ secrets.DOCKER_USERNAME }} 171 | DHTOKEN: ${{ secrets.DOCKER_PASSWORD }} 172 | DEBIAN_FRONTEND: noninteractive 173 | run: | 174 | echo "Install hub-tool ..." 175 | ver_hub_tool=$(curl -s https://api.github.com/repos/docker/hub-tool/releases/latest | jq -r .name) 176 | wget -q https://github.com/docker/hub-tool/releases/download/${ver_hub_tool}/hub-tool-linux-amd64.tar.gz -O /tmp/hub-tool-linux-amd64.tar.gz 177 | tar xzvf /tmp/hub-tool-linux-amd64.tar.gz --strip-components 1 -C /tmp hub-tool/hub-tool 178 | sudo chmod +x /tmp/hub-tool 179 | mkdir -pv -m 700 ~/.docker 180 | chmod -v 600 ~/.docker/config.json 181 | echo -ne "ewogICJ1c2VybmFtZSI6ICJESFVTRVIiLAogICJwYXNzd29yZCI6ICJESFRPS0VOIgp9Cg==" | base64 -d > /tmp/auth.json 182 | echo -ne "ewogICJhdXRocyI6IHsKICAgICJodWItdG9vbCI6IHsKICAgICAgImF1dGgiOiAiREhVU0VSVE9LRU4iCiAgICB9LAogICAgImh1Yi10b29sLXJlZnJlc2gtdG9rZW4iOiB7CiAgICAgICJhdXRoIjogIkRIVVNFUiIKICAgIH0sCiAgICAiaHViLXRvb2wtdG9rZW4iOiB7CiAgICAgICJhdXRoIjogIkRIVVNFUiIsCiAgICAgICJpZGVudGl0eXRva2VuIjogIkpXVFRPS0VOIgogICAgfQogIH0KfQoK" | base64 -d > ~/.docker/config.json 183 | RUSERTOKEN=$(echo -ne "${DHUSER}:${DHTOKEN}" | base64 -w0) 184 | RUSER=$(echo -ne "${DHUSER}:" | base64 -w0) 185 | RTOKEN=$(echo -ne "${DHTOKEN}" | base64 -w0) 186 | sed -i -e "s,DHUSERTOKEN,${RUSERTOKEN},g" -e "s,DHUSER,${RUSER},g" -e "s,DHTOKEN,${RTOKEN},g" /tmp/auth.json ~/.docker/config.json 187 | JWT=$(curl -s -XPOST "https://hub.docker.com/v2/users/login" -H "Content-Type:application/json" -d "@/tmp/auth.json" | jq -r .token) 188 | sed -i -e "s,JWTTOKEN,${JWT},g" ~/.docker/config.json 189 | 190 | - 191 | name: Delete Unwanted Tags 192 | run: | 193 | DOCKERHUB_REPOSITORY="${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME}" 194 | FULL_VERSION="${{ needs.base.outputs.full_version }}" 195 | MATRIX='${{ needs.base.outputs.matrix }}' 196 | ALL_ARCH=( $(echo ${MATRIX} | jq -r .architecture[] | perl -pe '{s|linux/||g; s|/|-|g}') ) 197 | TAGS=( $(/tmp/hub-tool tag ls --format json ${DOCKERHUB_REPOSITORY} | jq -r .[].Name) ) 198 | 199 | for tag in ${TAGS[@]}; do 200 | for arch in ${ALL_ARCH[@]}; do 201 | if [[ ${tag} == ${DOCKERHUB_REPOSITORY}:${FULL_VERSION}-${arch} ]]; then 202 | /tmp/hub-tool tag rm --verbose -f $tag 203 | fi 204 | done 205 | done 206 | 207 | - 208 | name: Logout Docker Hub-tool 209 | if: always() 210 | run: | 211 | rm -rf /tmp/auth.json ~/.docker/config.json 212 | /tmp/hub-tool logout 213 | -------------------------------------------------------------------------------- /.github/workflows/libtorrent-rasterbar-mirror.yml: -------------------------------------------------------------------------------- 1 | name: 同步仓库:libtorrent 2 | 3 | on: 4 | workflow_dispatch: 5 | repository_dispatch: 6 | types: [mirror, libtorrent-rasterbar, libtorrent-rasterbar-1.x, libtorrent-rasterbar-2.x] 7 | 8 | concurrency: 9 | group: git-mirror 10 | 11 | jobs: 12 | git-mirror: 13 | runs-on: ubuntu-latest 14 | name: 同步仓库:libtorrent 15 | steps: 16 | - uses: wearerequired/git-mirror-action@v1 17 | env: 18 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }} 19 | with: 20 | source-repo: "https://github.com/arvidn/libtorrent.git" 21 | destination-repo: "git@gitee.com:evine/libtorrent.git" -------------------------------------------------------------------------------- /.github/workflows/loop.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:loop 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:loop 9 | env: 10 | IMAGE_NAME: loop 11 | DOCKER_CLI_EXPERIMENTAL: enabled 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v2 15 | 16 | - name: Login to DockerHub 17 | uses: docker/login-action@v2 18 | with: 19 | username: ${{ secrets.DOCKER_USERNAME }} 20 | password: ${{ secrets.DOCKER_PASSWORD }} 21 | 22 | - name: Setup Docker Buildx 23 | uses: docker/setup-buildx-action@v2 24 | 25 | - name: Buildx cache 26 | uses: actions/cache@v2 27 | id: buildx-cache 28 | with: 29 | path: /tmp/.buildx-cache 30 | key: ${{ runner.os }}-buildx 31 | 32 | - name: Build 33 | run: | 34 | cd ${IMAGE_NAME} 35 | DOCKERHUB_REPOSITORY=${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME} 36 | declare -a IMAGES 37 | 38 | echo "Build amd64" 39 | docker buildx build \ 40 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 41 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 42 | --output "type=image,push=true" \ 43 | --platform linux/amd64 \ 44 | --build-arg "TARGET=x86_64-unknown-linux-musl" \ 45 | --tag "${DOCKERHUB_REPOSITORY}:latest-amd64" \ 46 | -f Dockerfile \ 47 | . 48 | IMAGES+=( "${DOCKERHUB_REPOSITORY}:latest-amd64" ) 49 | 50 | echo "Build arm-v7" 51 | docker buildx build \ 52 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 53 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 54 | --output "type=image,push=true" \ 55 | --platform linux/arm/v7 \ 56 | --build-arg "TARGET=armv7-unknown-linux-musleabihf" \ 57 | --tag "${DOCKERHUB_REPOSITORY}:latest-arm-v7" \ 58 | -f Dockerfile \ 59 | . 60 | IMAGES+=( "${DOCKERHUB_REPOSITORY}:latest-arm-v7" ) 61 | 62 | echo "Build arm64-v8" 63 | docker buildx build \ 64 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 65 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 66 | --output "type=image,push=true" \ 67 | --platform linux/arm64/v8 \ 68 | --build-arg "TARGET=aarch64-unknown-linux-musl" \ 69 | --tag "${DOCKERHUB_REPOSITORY}:latest-arm64-v8" \ 70 | -f Dockerfile \ 71 | . 72 | IMAGES+=( "${DOCKERHUB_REPOSITORY}:latest-arm64-v8" ) 73 | 74 | echo "Create manifest lists" 75 | docker manifest create "${DOCKERHUB_REPOSITORY}:latest" "${IMAGES[@]}" 76 | docker manifest annotate "${DOCKERHUB_REPOSITORY}:latest" "${DOCKERHUB_REPOSITORY}:latest-arm-v7" --variant "v7" 77 | docker manifest annotate "${DOCKERHUB_REPOSITORY}:latest" "${DOCKERHUB_REPOSITORY}:latest-arm64-v8" --variant "v8" 78 | 79 | echo "Push manifest lists & delete local copies" 80 | docker manifest push --purge "${DOCKERHUB_REPOSITORY}:latest" 81 | -------------------------------------------------------------------------------- /.github/workflows/ncmdump.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:ncmdump 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:ncmdump 9 | env: 10 | IMAGE_NAME: ncmdump 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Set Up QEMU 18 | uses: docker/setup-qemu-action@v2 19 | 20 | - 21 | name: Set Up Buildx 22 | uses: docker/setup-buildx-action@v2 23 | 24 | - 25 | name: Login DockerHub 26 | uses: docker/login-action@v2 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - 32 | name: Set Up Cache 33 | uses: actions/cache@v2 34 | id: buildx-cache 35 | with: 36 | path: /tmp/.buildx-cache 37 | key: ${{ runner.os }}-buildx 38 | 39 | - 40 | name: Buildx 41 | uses: docker/build-push-action@v3 42 | with: 43 | context: ${{ env.IMAGE_NAME }} 44 | file: ${{ env.IMAGE_NAME }}/Dockerfile 45 | platforms: | 46 | linux/amd64 47 | linux/arm64 48 | linux/arm/v7 49 | push: true 50 | tags: | 51 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 52 | -------------------------------------------------------------------------------- /.github/workflows/nginxwebui.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:nginxwebui 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:nginxwebui 9 | env: 10 | IMAGE_NAME: nginxwebui 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - name: Build nginxWebUI.jar 17 | id: prepare 18 | run: | 19 | cd ${{ env.IMAGE_NAME }} 20 | git clone --depth 1 https://gitee.com/cym1102/nginxWebUI src 21 | cd src 22 | version=$(cat pom.xml | grep -A1 nginxWebUI | grep version | perl -pe "s|.*((\d+\.?){3,}).*|\1|") 23 | echo ::set-output name=version::${version} 24 | mvn clean package 25 | 26 | - 27 | name: Set Up QEMU 28 | uses: docker/setup-qemu-action@v2 29 | 30 | - 31 | name: Set Up Buildx 32 | uses: docker/setup-buildx-action@v2 33 | 34 | - 35 | name: Login DockerHub 36 | uses: docker/login-action@v2 37 | with: 38 | username: ${{ secrets.DOCKER_USERNAME }} 39 | password: ${{ secrets.DOCKER_PASSWORD }} 40 | 41 | - 42 | name: Set Up Cache 43 | uses: actions/cache@v2 44 | id: buildx-cache 45 | with: 46 | path: /tmp/.buildx-cache 47 | key: ${{ runner.os }}-buildx 48 | 49 | - 50 | name: Buildx 51 | uses: docker/build-push-action@v3 52 | with: 53 | context: ${{ env.IMAGE_NAME }} 54 | file: ${{ env.IMAGE_NAME }}/Dockerfile 55 | platforms: | 56 | linux/386 57 | linux/amd64 58 | linux/arm64 59 | linux/arm/v7 60 | push: true 61 | tags: | 62 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 63 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 64 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:nodejs 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:nodejs 9 | env: 10 | IMAGE_NAME: nodejs 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Set Up QEMU 18 | uses: docker/setup-qemu-action@v2 19 | 20 | - 21 | name: Set Up Buildx 22 | uses: docker/setup-buildx-action@v2 23 | 24 | - 25 | name: Login DockerHub 26 | uses: docker/login-action@v2 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - 32 | name: Set Up Cache 33 | uses: actions/cache@v2 34 | id: buildx-cache 35 | with: 36 | path: /tmp/.buildx-cache 37 | key: ${{ runner.os }}-buildx 38 | 39 | - 40 | name: Buildx 41 | uses: docker/build-push-action@v3 42 | with: 43 | context: ${{ env.IMAGE_NAME }} 44 | file: ${{ env.IMAGE_NAME }}/Dockerfile 45 | platforms: | 46 | linux/amd64 47 | linux/arm64 48 | linux/arm/v7 49 | push: true 50 | tags: | 51 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest -------------------------------------------------------------------------------- /.github/workflows/pve-kernel.yml: -------------------------------------------------------------------------------- 1 | name: 同步仓库:pve-kernel 2 | 3 | on: 4 | workflow_dispatch: 5 | repository_dispatch: 6 | types: [mirror, pve-kernel] 7 | 8 | concurrency: 9 | group: git-mirror 10 | 11 | jobs: 12 | git-mirror: 13 | runs-on: ubuntu-latest 14 | name: 同步仓库:pve-kernel 15 | steps: 16 | - 17 | uses: wearerequired/git-mirror-action@v1 18 | env: 19 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }} 20 | with: 21 | source-repo: "https://github.com/proxmox/pve-kernel.git" 22 | destination-repo: "git@gitee.com:evine/pve-kernel.git" 23 | 24 | - 25 | uses: wearerequired/git-mirror-action@v1 26 | env: 27 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }} 28 | with: 29 | source-repo: "https://github.com/proxmox/mirror_ubuntu-focal-kernel.git" 30 | destination-repo: "git@gitee.com:evine/mirror_ubuntu-focal-kernel.git" 31 | 32 | - 33 | uses: wearerequired/git-mirror-action@v1 34 | env: 35 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }} 36 | with: 37 | source-repo: "git://git.proxmox.com/git/zfsonlinux.git" 38 | destination-repo: "git@gitee.com:evine/zfsonlinux.git" 39 | -------------------------------------------------------------------------------- /.github/workflows/python.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:python 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:python 9 | env: 10 | IMAGE_NAME: python 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Set Up QEMU 18 | uses: docker/setup-qemu-action@v2 19 | 20 | - 21 | name: Set Up Buildx 22 | uses: docker/setup-buildx-action@v2 23 | 24 | - 25 | name: Login DockerHub 26 | uses: docker/login-action@v2 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - 32 | name: Set Up Cache 33 | uses: actions/cache@v2 34 | id: buildx-cache 35 | with: 36 | path: /tmp/.buildx-cache 37 | key: ${{ runner.os }}-buildx 38 | 39 | - 40 | name: Buildx 41 | uses: docker/build-push-action@v3 42 | with: 43 | context: ${{ env.IMAGE_NAME }} 44 | file: ${{ env.IMAGE_NAME }}/Dockerfile 45 | platforms: | 46 | linux/amd64 47 | linux/arm64 48 | linux/arm/v7 49 | push: true 50 | tags: | 51 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 52 | -------------------------------------------------------------------------------- /.github/workflows/qbittorrent-buildx.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:qbittorrent 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: '要构建的版本,可以为beta/rc版,如不输入则默认去检测最新的正式版' 8 | required: false 9 | default: '' 10 | alpine_version: 11 | description: '要使用的alpine基础版本,如不输入则默认使用latest' 12 | required: false 13 | default: '' 14 | repository_dispatch: 15 | types: qbittorrent 16 | 17 | env: 18 | ## 镜像名,也是git仓库中的文件夹名 19 | IMAGE_NAME: qbittorrent 20 | ## Dockerfile文件名称,在这里修改 21 | DOCKERFILE_NAME: Dockerfile 22 | DOCKERFILE_NAME2: Dockerfile.iyuu 23 | 24 | jobs: 25 | base: 26 | runs-on: ubuntu-latest 27 | name: 基本信息 28 | outputs: 29 | full_version: ${{ steps.base.outputs.full_version }} 30 | multitags: ${{ steps.base.outputs.multitags }} 31 | matrix: ${{ steps.base.outputs.matrix }} 32 | build_args: ${{ steps.base.outputs.build_args }} 33 | steps: 34 | - 35 | name: Set Matrix And Base Infomation 36 | id: base 37 | run: | 38 | FULL_VERSION=${{ github.event.inputs.version }} 39 | 40 | ######################### ↓特殊部分↓ ######################### 41 | LATEST_VERSION=$(curl -s https://api.github.com/repos/qbittorrent/qBittorrent/tags | jq -r .[]."name" | grep -m1 -E "release-([0-9]{1,2}\.?){3,4}$" | sed "s/release-//") 42 | if [[ -z ${FULL_VERSION} ]]; then 43 | FULL_VERSION=${LATEST_VERSION} 44 | fi 45 | 46 | if [[ ${FULL_VERSION} == ${LATEST_VERSION} ]]; then 47 | MULTITAGS="${FULL_VERSION} latest" 48 | else 49 | MULTITAGS="${FULL_VERSION} unstable" 50 | fi 51 | 52 | if [[ $(echo ${FULL_VERSION} | awk -F '.' '{print $1}') -eq 4 && $(echo ${FULL_VERSION} | awk -F '.' '{print $2}') -le 3 ]]; then 53 | LIBTORRENT_VERSION=1 54 | else 55 | LIBTORRENT_VERSION=2 56 | fi 57 | ######################### ↑特殊部分↑ ######################### 58 | 59 | ## 要构建哪些平台的镜像,在这里修改 60 | MATRIX='{"architecture":["linux/386", "linux/amd64", "linux/arm64", "linux/arm/v7", "linux/arm/v6", "linux/ppc64le", "linux/s390x"]}' 61 | 62 | echo ::set-output name=full_version::${FULL_VERSION} 63 | echo ::set-output name=multitags::${MULTITAGS} 64 | echo ::set-output name=matrix::${MATRIX} 65 | 66 | ######################### ↓特殊部分↓ ######################### 67 | echo ::set-output name=build_args_QBITTORRENT_VERSION::QBITTORRENT_VERSION=${FULL_VERSION} 68 | echo ::set-output name=build_args_LIBTORRENT_VERSION::LIBTORRENT_VERSION=${LIBTORRENT_VERSION} 69 | ######################### ↑特殊部分↑ ######################### 70 | 71 | build: 72 | needs: base 73 | runs-on: ubuntu-latest 74 | name: 并行构建 75 | timeout-minutes: 150 76 | strategy: 77 | matrix: ${{ fromJSON(needs.base.outputs.matrix) }} 78 | steps: 79 | - 80 | name: Checkout 81 | uses: actions/checkout@master 82 | 83 | - 84 | name: Prepare 85 | id: prep 86 | run: | 87 | DOCKERHUB_REPOSITORY="${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME}" 88 | FULL_VERSION="${{ needs.base.outputs.full_version }}" 89 | ARCH="${{ matrix.architecture }}" 90 | TAGS="${DOCKERHUB_REPOSITORY}:${FULL_VERSION}-$(echo ${ARCH} | perl -pe '{s|linux/||g; s|/|-|g}')" 91 | JNPROC=$(nproc) 92 | 93 | echo ::set-output name=tags::${TAGS} 94 | echo ::set-output name=build_args_JNPROC::JNPROC=${JNPROC} 95 | 96 | - 97 | name: Set Up QEMU 98 | uses: docker/setup-qemu-action@v2 99 | 100 | - 101 | name: Set Up Buildx 102 | uses: docker/setup-buildx-action@v2 103 | 104 | - 105 | name: Login DockerHub 106 | uses: docker/login-action@v2 107 | with: 108 | username: ${{ secrets.DOCKER_USERNAME }} 109 | password: ${{ secrets.DOCKER_PASSWORD }} 110 | 111 | - 112 | name: Set Up Cache 113 | uses: actions/cache@v2 114 | id: buildx-cache 115 | with: 116 | path: /tmp/.buildx-cache 117 | key: ${{ runner.os }}-buildx 118 | 119 | - 120 | name: Buildx 121 | uses: docker/build-push-action@v3 122 | with: 123 | context: ${{ env.IMAGE_NAME }} 124 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME }} 125 | platforms: ${{ matrix.architecture }} 126 | push: true 127 | build-args: | 128 | ${{ needs.base.outputs.build_args_QBITTORRENT_VERSION }} 129 | ${{ needs.base.outputs.build_args_LIBTORRENT_VERSION }} 130 | ${{ steps.prep.outputs.build_args_JNPROC }} 131 | tags: ${{ steps.prep.outputs.tags }} 132 | 133 | maintain: 134 | needs: [base, build] 135 | runs-on: ubuntu-latest 136 | name: 信息维护 137 | steps: 138 | - 139 | name: Checkout 140 | uses: actions/checkout@master 141 | 142 | - 143 | name: Login DockerHub 144 | uses: docker/login-action@v2 145 | with: 146 | username: ${{ secrets.DOCKER_USERNAME }} 147 | password: ${{ secrets.DOCKER_PASSWORD }} 148 | 149 | - 150 | name: Create And Push Manifest 151 | env: 152 | DOCKER_CLI_EXPERIMENTAL: enabled 153 | run: | 154 | DOCKERHUB_REPOSITORY="${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME}" 155 | FULL_VERSION="${{ needs.base.outputs.full_version }}" 156 | MATRIX='${{ needs.base.outputs.matrix }}' 157 | ALL_ARCH=( $(echo ${MATRIX} | jq -r .architecture[] | perl -pe '{s|linux/||g; s|/|-|g}') ) 158 | MULTITAGS="${{ needs.base.outputs.multitags }}" 159 | 160 | echo ALL_ARCH[@]=${ALL_ARCH[@]} 161 | 162 | IMAGES=() 163 | for arch in ${ALL_ARCH[@]}; do 164 | IMAGES+=( "${DOCKERHUB_REPOSITORY}:${FULL_VERSION}-${arch}" ) 165 | done 166 | 167 | echo IMAGES[@]=${IMAGES[@]} 168 | 169 | for tag in ${MULTITAGS}; do 170 | docker manifest create "${DOCKERHUB_REPOSITORY}:${tag}" "${IMAGES[@]}" 171 | done 172 | 173 | echo MULTITAGS=${MULTITAGS} 174 | 175 | for tag in ${MULTITAGS}; do 176 | docker manifest push --purge "${DOCKERHUB_REPOSITORY}:${tag}" 177 | done 178 | 179 | - 180 | name: Update DockerHub Description 181 | if: endsWith(needs.base.outputs.multitags, 'latest') 182 | uses: christian-korneck/update-container-description-action@v1 183 | env: 184 | DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} 185 | DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} 186 | with: 187 | destination_container_repo: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 188 | provider: dockerhub 189 | readme_file: ./${{ env.IMAGE_NAME }}/readme.md 190 | short_description: ${{ env.IMAGE_NAME }} ${{ needs.base.outputs.full_version }}:下载完成通知,自动分类,IYUU辅助,tracker错误标记,批量修改tracker,设备上线自动限速,多时段限速等等 191 | 192 | deltag: 193 | needs: [base, maintain] 194 | runs-on: ubuntu-latest 195 | name: 删除标签 196 | steps: 197 | - 198 | ## 参考https://github.com/xaynetwork/xaynet/blob/master/.github/workflows/dockerhub-cleanup.yml 199 | name: Setup Hub-tool 200 | env: 201 | DHUSER: ${{ secrets.DOCKER_USERNAME }} 202 | DHTOKEN: ${{ secrets.DOCKER_PASSWORD }} 203 | DEBIAN_FRONTEND: noninteractive 204 | run: | 205 | echo "Install hub-tool ..." 206 | ver_hub_tool=$(curl -s https://api.github.com/repos/docker/hub-tool/releases/latest | jq -r .name) 207 | wget -q https://github.com/docker/hub-tool/releases/download/${ver_hub_tool}/hub-tool-linux-amd64.tar.gz -O /tmp/hub-tool-linux-amd64.tar.gz 208 | tar xzvf /tmp/hub-tool-linux-amd64.tar.gz --strip-components 1 -C /tmp hub-tool/hub-tool 209 | sudo chmod +x /tmp/hub-tool 210 | mkdir -pv -m 700 ~/.docker 211 | chmod -v 600 ~/.docker/config.json 212 | echo -ne "ewogICJ1c2VybmFtZSI6ICJESFVTRVIiLAogICJwYXNzd29yZCI6ICJESFRPS0VOIgp9Cg==" | base64 -d > /tmp/auth.json 213 | echo -ne "ewogICJhdXRocyI6IHsKICAgICJodWItdG9vbCI6IHsKICAgICAgImF1dGgiOiAiREhVU0VSVE9LRU4iCiAgICB9LAogICAgImh1Yi10b29sLXJlZnJlc2gtdG9rZW4iOiB7CiAgICAgICJhdXRoIjogIkRIVVNFUiIKICAgIH0sCiAgICAiaHViLXRvb2wtdG9rZW4iOiB7CiAgICAgICJhdXRoIjogIkRIVVNFUiIsCiAgICAgICJpZGVudGl0eXRva2VuIjogIkpXVFRPS0VOIgogICAgfQogIH0KfQoK" | base64 -d > ~/.docker/config.json 214 | RUSERTOKEN=$(echo -ne "${DHUSER}:${DHTOKEN}" | base64 -w0) 215 | RUSER=$(echo -ne "${DHUSER}:" | base64 -w0) 216 | RTOKEN=$(echo -ne "${DHTOKEN}" | base64 -w0) 217 | sed -i -e "s,DHUSERTOKEN,${RUSERTOKEN},g" -e "s,DHUSER,${RUSER},g" -e "s,DHTOKEN,${RTOKEN},g" /tmp/auth.json ~/.docker/config.json 218 | JWT=$(curl -s -XPOST "https://hub.docker.com/v2/users/login" -H "Content-Type:application/json" -d "@/tmp/auth.json" | jq -r .token) 219 | sed -i -e "s,JWTTOKEN,${JWT},g" ~/.docker/config.json 220 | 221 | - 222 | name: Delete Unwanted Tags 223 | run: | 224 | DOCKERHUB_REPOSITORY="${{ secrets.DOCKER_USERNAME }}/${IMAGE_NAME}" 225 | FULL_VERSION="${{ needs.base.outputs.full_version }}" 226 | MATRIX='${{ needs.base.outputs.matrix }}' 227 | ALL_ARCH=( $(echo ${MATRIX} | jq -r .architecture[] | perl -pe '{s|linux/||g; s|/|-|g}') ) 228 | TAGS=( $(/tmp/hub-tool tag ls --format json ${DOCKERHUB_REPOSITORY} | jq -r .[].Name) ) 229 | 230 | for tag in ${TAGS[@]}; do 231 | for arch in ${ALL_ARCH[@]}; do 232 | if [[ ${tag} == ${DOCKERHUB_REPOSITORY}:${FULL_VERSION}-${arch} ]]; then 233 | /tmp/hub-tool tag rm --verbose -f $tag 234 | fi 235 | done 236 | done 237 | 238 | - 239 | name: Logout Docker Hub-tool 240 | if: always() 241 | run: | 242 | rm -rf /tmp/auth.json ~/.docker/config.json 243 | /tmp/hub-tool logout 244 | 245 | build2: 246 | needs: [base, build, maintain] 247 | if: endsWith(needs.base.outputs.multitags, 'latest') 248 | runs-on: ubuntu-latest 249 | name: 并行构建IYUU 250 | timeout-minutes: 10 251 | steps: 252 | - 253 | name: Checkout 254 | uses: actions/checkout@master 255 | 256 | - 257 | name: Prepare 258 | id: prep 259 | run: | 260 | MATRIX='${{ needs.base.outputs.matrix }}' 261 | PLATFORMS="$(echo ${MATRIX} | jq -r .architecture[])" 262 | PLATFORMS=$(echo ${PLATFORMS} | perl -pe "s| |,|g") 263 | echo "::set-output name=platforms::${PLATFORMS}" 264 | 265 | - 266 | name: Set Up QEMU 267 | uses: docker/setup-qemu-action@v2 268 | 269 | - 270 | name: Set Up Buildx 271 | uses: docker/setup-buildx-action@v2 272 | 273 | - 274 | name: Login DockerHub 275 | uses: docker/login-action@v2 276 | with: 277 | username: ${{ secrets.DOCKER_USERNAME }} 278 | password: ${{ secrets.DOCKER_PASSWORD }} 279 | 280 | - 281 | name: Set Up Cache 282 | uses: actions/cache@v2 283 | id: buildx-cache 284 | with: 285 | path: /tmp/.buildx-cache 286 | key: ${{ runner.os }}-buildx 287 | 288 | - 289 | name: Buildx 290 | uses: docker/build-push-action@v3 291 | with: 292 | context: ${{ env.IMAGE_NAME }} 293 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME2 }} 294 | platforms: ${{ steps.prep.outputs.platforms }} 295 | push: true 296 | tags: | 297 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ needs.base.outputs.full_version }}-iyuu 298 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:iyuu 299 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest-iyuu -------------------------------------------------------------------------------- /.github/workflows/qbittorrent-buildx2.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:qbittorrent2 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | qbittorrent_version: 7 | description: '要构建的qBittorrent版本,只能为正式版,如不输入则默认去检测最新的正式版' 8 | required: false 9 | default: '' 10 | alpine_version: 11 | description: '要使用的alpine基础版本,如不输入则默认使用latest' 12 | required: false 13 | default: '' 14 | repository_dispatch: 15 | types: qbittorrent 16 | 17 | env: 18 | ## 镜像名,也是git仓库中的文件夹名 19 | IMAGE_NAME: qbittorrent 20 | 21 | ## Dockerfile文件名称,在这里修改 22 | DOCKERFILE_NAME: Dockerfile 23 | DOCKERFILE_NAME2: Dockerfile.iyuu 24 | 25 | jobs: 26 | build: 27 | runs-on: ubuntu-latest 28 | name: 构建镜像:qbittorrent2 29 | timeout-minutes: 300 30 | steps: 31 | - 32 | name: Checkout 33 | uses: actions/checkout@master 34 | 35 | - 36 | name: Prepare 37 | id: prepare 38 | run: | 39 | QBITTORRENT_VERSION=${{ github.event.inputs.qbittorrent_version }} 40 | LATEST_VERSION=$(curl -s https://api.github.com/repos/qbittorrent/qBittorrent/tags | jq -r .[]."name" | grep -m1 -E "release-([0-9]{1,2}\.?){3,4}$" | sed "s/release-//") 41 | if [[ -z ${QBITTORRENT_VERSION} ]]; then 42 | QBITTORRENT_VERSION=${LATEST_VERSION} 43 | fi 44 | 45 | if [[ $(echo ${FULL_VERSION} | awk -F '.' '{print $1}') -eq 4 && $(echo ${FULL_VERSION} | awk -F '.' '{print $2}') -le 3 ]]; then 46 | LIBTORRENT_VERSION=1 47 | else 48 | LIBTORRENT_VERSION=2 49 | fi 50 | 51 | ALPINE_VERSION=${{ github.event.inputs.alpine_version }} 52 | if [[ -z ${ALPINE_VERSION} ]]; then 53 | ALPINE_VERSION=latest 54 | fi 55 | 56 | JNPROC=$(nproc) 57 | 58 | echo ::set-output name=qbittorrent_version::${QBITTORRENT_VERSION} 59 | echo ::set-output name=libtorrent_version::${LIBTORRENT_VERSION} 60 | echo ::set-output name=alpine_version::${ALPINE_VERSION} 61 | echo ::set-output name=jnproc::${JNPROC} 62 | 63 | - 64 | name: Set Up QEMU 65 | uses: docker/setup-qemu-action@v2 66 | 67 | - 68 | name: Set Up Buildx 69 | uses: docker/setup-buildx-action@v2 70 | 71 | - 72 | name: Login DockerHub 73 | uses: docker/login-action@v2 74 | with: 75 | username: ${{ secrets.DOCKER_USERNAME }} 76 | password: ${{ secrets.DOCKER_PASSWORD }} 77 | 78 | - 79 | name: Set Up Cache 80 | uses: actions/cache@v2 81 | id: buildx-cache 82 | with: 83 | path: /tmp/.buildx-cache 84 | key: ${{ runner.os }}-buildx 85 | 86 | - 87 | name: Buildx qBittorrent 88 | uses: docker/build-push-action@v3 89 | with: 90 | context: ${{ env.IMAGE_NAME }} 91 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME }} 92 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 93 | push: true 94 | build-args: | 95 | QBITTORRENT_VERSION=${{ steps.prepare.outputs.qbittorrent_version }} 96 | LIBTORRENT_VERSION=${{ steps.prepare.outputs.libtorrent_version }} 97 | ALPINE_VERSION=${{ steps.prepare.outputs.alpine_version }} 98 | JNPROC=${{ steps.prepare.outputs.jnproc }} 99 | tags: | 100 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.QBITTORRENT_VERSION }} 101 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 102 | 103 | - 104 | name: Buildx qBittorrent With IYUUPlus 105 | uses: docker/build-push-action@v3 106 | with: 107 | context: ${{ env.IMAGE_NAME }} 108 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME2 }} 109 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 110 | push: true 111 | tags: | 112 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.QBITTORRENT_VERSION }}-iyuu 113 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:iyuu 114 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest-iyuu 115 | 116 | - 117 | name: Update DockerHub Description 118 | uses: christian-korneck/update-container-description-action@v1 119 | env: 120 | DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} 121 | DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} 122 | with: 123 | destination_container_repo: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }} 124 | provider: dockerhub 125 | readme_file: ./${{ env.IMAGE_NAME }}/readme.md 126 | short_description: ${{ env.IMAGE_NAME }} ${{ steps.prepare.outputs.QBITTORRENT_VERSION }}:下载完成通知,自动分类,IYUU辅助,tracker错误标记,批量修改tracker,设备上线自动限速,多时段限速等等 127 | -------------------------------------------------------------------------------- /.github/workflows/qbittorrent-edge.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:qbittorrent-edge 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | env: 7 | IMAGE_NAME: qbittorrent 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | name: 构建镜像:qbittorrent-edge 13 | steps: 14 | - 15 | name: Checkout 16 | uses: actions/checkout@master 17 | 18 | - 19 | name: Set Up QEMU 20 | uses: docker/setup-qemu-action@v2 21 | 22 | - 23 | name: Set Up Buildx 24 | uses: docker/setup-buildx-action@v2 25 | 26 | - 27 | name: Login DockerHub 28 | uses: docker/login-action@v2 29 | with: 30 | username: ${{ secrets.DOCKER_USERNAME }} 31 | password: ${{ secrets.DOCKER_PASSWORD }} 32 | 33 | - 34 | name: Buildx qBittorrent Edge 35 | uses: docker/build-push-action@v3 36 | with: 37 | context: ${{ env.IMAGE_NAME }} 38 | file: ${{ env.IMAGE_NAME }}/Dockerfile.edge 39 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x,linux/riscv64 40 | push: true 41 | tags: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:edge 42 | -------------------------------------------------------------------------------- /.github/workflows/qbittorrent-iyuu.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:qbittorrent(iyuu) 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: '要构建的版本,仅支持正式版' 8 | required: true 9 | default: '' 10 | 11 | env: 12 | ## 镜像名,也是git仓库中的文件夹名 13 | IMAGE_NAME: qbittorrent 14 | ## Dockerfile文件名称,在这里修改 15 | DOCKERFILE_NAME2: Dockerfile.iyuu 16 | 17 | jobs: 18 | build2: 19 | runs-on: ubuntu-latest 20 | name: 构建镜像:qbittorrent(iyuu) 21 | timeout-minutes: 10 22 | steps: 23 | - 24 | name: Checkout 25 | uses: actions/checkout@master 26 | 27 | - 28 | name: Set Up QEMU 29 | uses: docker/setup-qemu-action@v2 30 | 31 | - 32 | name: Set Up Buildx 33 | uses: docker/setup-buildx-action@v2 34 | 35 | - 36 | name: Login DockerHub 37 | uses: docker/login-action@v2 38 | with: 39 | username: ${{ secrets.DOCKER_USERNAME }} 40 | password: ${{ secrets.DOCKER_PASSWORD }} 41 | 42 | - 43 | name: Set Up Cache 44 | uses: actions/cache@v2 45 | id: buildx-cache 46 | with: 47 | path: /tmp/.buildx-cache 48 | key: ${{ runner.os }}-buildx 49 | 50 | - 51 | name: Buildx 52 | uses: docker/build-push-action@v3 53 | with: 54 | context: ${{ env.IMAGE_NAME }} 55 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME2 }} 56 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 57 | push: true 58 | tags: | 59 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.version }}-iyuu 60 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:iyuu 61 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest-iyuu -------------------------------------------------------------------------------- /.github/workflows/qbittorrent-mirror.yml: -------------------------------------------------------------------------------- 1 | name: 同步仓库:qbittorrent 2 | 3 | on: 4 | workflow_dispatch: 5 | repository_dispatch: 6 | types: [mirror, qbittorrent, qbittorrent-beta] 7 | 8 | concurrency: 9 | group: git-mirror 10 | 11 | jobs: 12 | git-mirror: 13 | runs-on: ubuntu-latest 14 | name: 同步仓库:qbittorrent 15 | steps: 16 | - uses: wearerequired/git-mirror-action@v1 17 | env: 18 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }} 19 | with: 20 | source-repo: "https://github.com/qbittorrent/qBittorrent.git" 21 | destination-repo: "git@gitee.com:evine/qBittorrent.git" -------------------------------------------------------------------------------- /.github/workflows/subfinder.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:subfinder 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | name: 构建镜像:subfinder 9 | env: 10 | IMAGE_NAME: subfinder 11 | steps: 12 | - 13 | name: Checkout 14 | uses: actions/checkout@master 15 | 16 | - 17 | name: Prepare 18 | id: prepare 19 | run: | 20 | version=$(curl -s https://api.github.com/repos/ausaki/subfinder/releases/latest | jq -r .tag_name | sed "s/v//") 21 | echo ::set-output name=version::${version} 22 | 23 | - 24 | name: Set Up QEMU 25 | uses: docker/setup-qemu-action@v2 26 | 27 | - 28 | name: Set Up Buildx 29 | uses: docker/setup-buildx-action@v2 30 | 31 | - 32 | name: Login DockerHub 33 | uses: docker/login-action@v2 34 | with: 35 | username: ${{ secrets.DOCKER_USERNAME }} 36 | password: ${{ secrets.DOCKER_PASSWORD }} 37 | 38 | - 39 | name: Set Up Cache 40 | uses: actions/cache@v2 41 | id: buildx-cache 42 | with: 43 | path: /tmp/.buildx-cache 44 | key: ${{ runner.os }}-buildx 45 | 46 | - 47 | name: Buildx 48 | uses: docker/build-push-action@v3 49 | with: 50 | context: ${{ env.IMAGE_NAME }} 51 | file: ${{ env.IMAGE_NAME }}/Dockerfile 52 | platforms: | 53 | linux/amd64 54 | linux/arm64 55 | linux/arm/v7 56 | push: true 57 | tags: | 58 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 59 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 60 | -------------------------------------------------------------------------------- /.github/workflows/tieba-cloud-sign.yml: -------------------------------------------------------------------------------- 1 | name: 构建镜像:tieba-cloud-sign 2 | 3 | on: 4 | workflow_dispatch: 5 | repository_dispatch: 6 | types: tieba-cloud-sign 7 | 8 | env: 9 | ## 镜像名,也是git仓库中的文件夹名 10 | IMAGE_NAME: tieba-cloud-sign 11 | ## Dockerfile文件名称,在这里修改 12 | DOCKERFILE_NAME: Dockerfile 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | name: 构建镜像:tieba-cloud-sign 18 | timeout-minutes: 30 19 | steps: 20 | - 21 | name: Checkout 22 | uses: actions/checkout@master 23 | 24 | - 25 | name: Prepare 26 | id: prepare 27 | run: | 28 | version=$(curl -s https://raw.githubusercontent.com/MoeNetwork/Tieba-Cloud-Sign/master/init.php | grep "'SYSTEM_VER'" | awk -F "'" '{print $4}') 29 | echo ::set-output name=version::${version} 30 | 31 | - 32 | name: Set Up QEMU 33 | uses: docker/setup-qemu-action@v2 34 | 35 | - 36 | name: Set Up Buildx 37 | uses: docker/setup-buildx-action@v2 38 | 39 | - 40 | name: Login DockerHub 41 | uses: docker/login-action@v2 42 | with: 43 | username: ${{ secrets.DOCKER_USERNAME }} 44 | password: ${{ secrets.DOCKER_PASSWORD }} 45 | 46 | - 47 | name: Set Up Cache 48 | uses: actions/cache@v2 49 | id: buildx-cache 50 | with: 51 | path: /tmp/.buildx-cache 52 | key: ${{ runner.os }}-buildx 53 | 54 | - 55 | name: Buildx 56 | uses: docker/build-push-action@v3 57 | with: 58 | context: ${{ env.IMAGE_NAME }} 59 | file: ${{ env.IMAGE_NAME }}/${{ env.DOCKERFILE_NAME }} 60 | platforms: linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x 61 | push: true 62 | tags: | 63 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.prepare.outputs.version }} 64 | ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */logs 2 | -------------------------------------------------------------------------------- /better-cloudflare-ip/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Dockerfile 3 | -------------------------------------------------------------------------------- /better-cloudflare-ip/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:${ALPINE_VERSION} 3 | ENV LANG=zh_CN.UTF-8 PS1="\u@\h:\w \$ " 4 | WORKDIR /cf 5 | RUN apk add --update --no-cache \ 6 | curl \ 7 | bash \ 8 | && apk add --no-cache --virtual .build \ 9 | musl-dev \ 10 | make \ 11 | gcc \ 12 | tar \ 13 | gzip \ 14 | && mkdir build \ 15 | && cd build \ 16 | && curl -sSL https://github.com/badafans/better-cloudflare-ip/releases/latest/download/linux.tar.gz | tar xz --strip-components 1 \ 17 | && sed -i "s|^int random_data_flag;|extern int random_data_flag;|" src/fping.h \ 18 | && ./configure --prefix=/usr \ 19 | && make \ 20 | && make install \ 21 | && strip $(type fping | awk '{print $3}') \ 22 | && cd .. \ 23 | && sed "s|./fping|fping|" build/src/cf.sh > cf.sh \ 24 | && chmod +x cf.sh \ 25 | && apk del --purge .build \ 26 | && rm -rf build /tmp/* /var/cache/apk/* 27 | CMD ["/cf/cf.sh"] 28 | 29 | -------------------------------------------------------------------------------- /better-cloudflare-ip/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/better-cloudflare-ip" 4 | arch="linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x" 5 | alpine_ver=${1:-latest} 6 | 7 | docker pull tonistiigi/binfmt 8 | docker run --privileged --rm tonistiigi/binfmt --install all 9 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 10 | docker buildx inspect --bootstrap 11 | docker buildx build \ 12 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 13 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 14 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 15 | --platform "$arch" \ 16 | --tag ${repo}:latest \ 17 | --push \ 18 | . 19 | docker pushrm -s "寻找CloudFlare最优IP" $repo # https://github.com/christian-korneck/docker-pushrm 20 | -------------------------------------------------------------------------------- /better-cloudflare-ip/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | 这个项目的Docker实现:https://github.com/badafans/better-cloudflare-ip 4 | 5 | ## 运行 6 | 7 | ``` 8 | docker run -it --rm nevinee/better-cloudflare-ip 9 | ``` 10 | 11 | 如需要经常使用,可修改`~/.bashrc`或`~/.zshrc`,在最后添加一行`alias dcf="docker run -it --rm nevinee/better-cloudflare-ip"`,执行`source ~/.你的rc`后可输入`dcf`命令。 12 | 13 | *注:网络经常发生变化,如再遇无法连接的情况,可再次运行查找最优IP。* 14 | 15 | 根据输出的ip修改hosts: 16 | 17 | - Windows: C:\Windows\System32\Drivers\etc\hosts 18 | 19 | - Linux: /etc/hosts 20 | 21 | - Docker: 三种方法 22 | 23 | 1. 如果命令行创建容器,添加`--add-host :`; 24 | 25 | 2. 如果是compose创建,添加`extra_hosts`; 26 | 27 | 3. 也可以直接容器内修改`/etc/hosts`文件,但重启或重建将失效。 28 | 29 | ## 关于armv7设备的补充说明 30 | 31 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 32 | 33 | 解决办法如下: 34 | 35 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 36 | 37 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 38 | 39 | ``` 40 | security_opt: 41 | - seccomp=unconfined 42 | ``` 43 | -------------------------------------------------------------------------------- /chinesesubfinder/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !entrypoint.sh 3 | !Dockerfile* 4 | !go 5 | -------------------------------------------------------------------------------- /chinesesubfinder/.gitignore: -------------------------------------------------------------------------------- 1 | go 2 | -------------------------------------------------------------------------------- /chinesesubfinder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV TZ=Asia/Shanghai \ 3 | PUID=1000 \ 4 | PGID=100 \ 5 | UMASK=022 \ 6 | PS1="\u@\h:\w \$ " 7 | ARG TARGETARCH 8 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/g' /etc/apk/repositories \ 9 | && apk add --no-cache \ 10 | ffmpeg \ 11 | ca-certificates \ 12 | tini \ 13 | su-exec \ 14 | tzdata \ 15 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 16 | && echo "${TZ}" > /etc/timezone \ 17 | && rm -rf /tmp/* /var/cache/apk/* 18 | COPY go/out/${TARGETARCH}/chinesesubfinder /usr/bin/chinesesubfinder 19 | COPY entrypoint.sh /usr/bin/entrypoint.sh 20 | VOLUME ["/config"] 21 | WORKDIR /config 22 | ENTRYPOINT ["tini", "entrypoint.sh"] 23 | -------------------------------------------------------------------------------- /chinesesubfinder/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/chinesesubfinder" 4 | arch="linux/386,linux/amd64,linux/arm64,linux/arm/v7" 5 | ver=$(curl -s https://api.github.com/repos/allanpk716/ChineseSubFinder/tags | jq -r '.[].name' | grep -Evi 'Beta|Docker' | head -1 | sed 's|v||') 6 | alpine_ver=${1:-latest} 7 | 8 | buildx() { 9 | docker pull tonistiigi/binfmt 10 | docker run --privileged --rm tonistiigi/binfmt --install all 11 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 12 | docker buildx inspect --bootstrap 13 | docker buildx build \ 14 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 15 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 16 | --platform "$arch" \ 17 | --build-arg "VERSION=${ver}" \ 18 | --tag ${repo}:${ver} \ 19 | --tag ${repo}:latest \ 20 | --push \ 21 | . 22 | docker pushrm -s "自动下载中文字幕,支持平台:386/amd64/arm64/armv7" $repo # https://github.com/christian-korneck/docker-pushrm 23 | } 24 | 25 | if [[ $ver ]]; then 26 | [[ ! -d logs ]] && mkdir logs 27 | [[ -d go/src ]] && rm -rf go/src 28 | echo "alpine_ver=${1:-latest}" 29 | docker run --rm \ 30 | --env VERSION=${ver} \ 31 | --volume $(pwd)/go:/root/go \ 32 | --volume $(pwd)/init.sh:/init.sh \ 33 | --entrypoint "/init.sh" \ 34 | nevinee/csf-cross-builder 35 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 36 | else 37 | echo "未获取到最新版本号" 38 | fi 39 | -------------------------------------------------------------------------------- /chinesesubfinder/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | chown -R "${PUID}:${PGID}" /config 4 | echo "请自行在宿主上检查你设置的 'PUID=${PUID} PGID=${PGID}' 这个用户有你所设置媒体目录的读取和写入权限..." 5 | echo "开始启动ChineseSubFinder,生成的日志、缓存、配置文件都保存在config目录下..." 6 | umask ${UMASK:-022} 7 | cd /config 8 | exec su-exec "${PUID}:${PGID}" chinesesubfinder 9 | -------------------------------------------------------------------------------- /chinesesubfinder/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export CGO_ENABLED=1 6 | export GO111MODULE=on 7 | export GOOS=linux 8 | export MUSL=/musl 9 | 10 | ## 准备必要的环境 11 | [[ ! -d ~/go/src ]] && mkdir -p ~/go/src 12 | [[ ! -d ~/go/bin ]] && mkdir -p ~/go/bin 13 | 14 | ## 下载源码并下载go mod 15 | cd ~/go/src 16 | curl -sSL https://github.com/allanpk716/ChineseSubFinder/archive/refs/tags/v${VERSION}.tar.gz | tar xvz --strip-components 1 17 | npm --prefix frontend ci 18 | npm --prefix frontend run build 19 | go mod tidy 20 | 21 | ## 编译共用函数 22 | cross_make() { 23 | export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 24 | if [[ -n ${CROSS_NAME} ]]; then 25 | export CPLUS_VERSION=$(${MUSL}/${CROSS_NAME}-cross/bin/${CROSS_NAME}-g++ --version | grep -oE '\d+\.\d+\.\d+' | head -1) 26 | export PATH=${MUSL}/${CROSS_NAME}-cross/bin:${MUSL}/${CROSS_NAME}-cross/${CROSS_NAME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 27 | export C_INCLUDE_PATH=${MUSL}/${CROSS_NAME}-cross/${CROSS_NAME}/include 28 | export CPLUS_INCLUDE_PATH=${MUSL}/${CROSS_NAME}-cross/${CROSS_NAME}/include/c++/${CPLUS_VERSION} 29 | export LIBRARY_PATH=${MUSL}/${CROSS_NAME}-cross/${CROSS_NAME}/lib 30 | export CC=${CROSS_NAME}-gcc 31 | export CXX=${CROSS_NAME}-g++ 32 | export AR=${CROSS_NAME}-ar 33 | fi 34 | echo "[$(date +'%H:%M:%S')] 开始编译 ${GOARCH} 平台..." 35 | go build -ldflags="-s -w --extldflags '-static -fpic' -X main.AppVersion=v${VERSION} -X main.LiteMode=true" -o ~/go/out/${GOARCH}/chinesesubfinder ./cmd/chinesesubfinder 36 | if [[ -n ${CROSS_NAME} ]]; then 37 | unset -v CPLUS_VERSION PATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH LIBRARY_PATH CC CXX AR 38 | fi 39 | export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 40 | } 41 | 42 | ## 开始交叉编译 43 | arches=( amd64 386 arm64 arm ) 44 | crosses=( "" i686-linux-musl aarch64-linux-musl armv7l-linux-musleabihf ) 45 | for ((i=0; i<${#arches[@]}; i++)); do 46 | export GOARCH=${arches[i]} 47 | export CROSS_NAME=${crosses[i]} 48 | [[ ${GOARCH} == amd64 ]] && export GOAMD64=v1 49 | [[ ${GOARCH} == arm ]] && export GOARM=7 50 | cross_make 51 | unset -v GOARCH CROSS_NAME GOAMD64 GOARM 52 | done 53 | 54 | ## 列出文件 55 | ls -lR ~/go/out 56 | exit 0 57 | -------------------------------------------------------------------------------- /chinesesubfinder/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | 中文字幕自动下载,是这个项目的Docker实现:https://github.com/allanpk716/ChineseSubFinder 4 | 5 | 基于alpine实现,比官方镜像体积小、层数少,日志和设置文件全部和配置文件保存在一起,支持 386/amd64/arm64/armv7。 6 | 7 | **注意:本镜像未安装chromium及其运行依赖,无法从subhd下载字幕,如有此需要,请使用官方原版镜像allanpk716/chinesesubfinder。** 8 | 9 | ## 创建 10 | 11 | **注:从0.20.0起,需要从webui来设置参数,因此需要额外映射端口出来。并且从该版本起,可以设置多个媒体目录。** 12 | 13 | **注:从0.33.0起,本镜像调整为lite模式。** 14 | 15 | **docker cli** 16 | 17 | ``` 18 | docker run -d \ 19 | -v $(pwd)/config:/config `# 冒号左边请修改为你想在主机上保存配置、日志等文件的路径` \ 20 | -v $(pwd)/media:/media `# 请修改为需要下载字幕的媒体目录,冒号右边可以改成你方便记忆的目录,多个媒体目录需要添加多个-v映射` \ 21 | -e PUID=1000 \ 22 | -e PGID=100 \ 23 | -e UMASK=022 \ 24 | -e TZ=Asia/Shanghai \ 25 | -p 19035:19035 `# 从0.20.0版本开始,通过webui来设置` \ 26 | --name chinesesubfinder \ 27 | --hostname chinesesubfinder \ 28 | --log-driver "json-file" \ 29 | --log-opt "max-size=100m" `# 限制日志大小,可自行调整` \ 30 | nevinee/chinesesubfinder 31 | ``` 32 | 33 | 创建好后访问`http://:19035`来进行下一步设置。 34 | 35 | **docker-compose** 36 | 37 | 新建`docker-compose.yml`文件如下,并以命令`docker-compose up -d`启动。 38 | 39 | ``` 40 | version: "3" 41 | services: 42 | chinesesubfinder: 43 | image: nevinee/chinesesubfinder:latest 44 | volumes: 45 | - ./config:/config # 冒号左边请修改为你想在主机上保存配置、日志等文件的路径 46 | - ./media:/media # 请修改为你的媒体目录,冒号右边可以改成你方便记忆的目录,多个媒体目录需要分别映射进来 47 | environment: 48 | - PUID=1000 49 | - PGID=100 50 | - UMASK=022 51 | - TZ=Asia/Shanghai 52 | restart: always 53 | network_mode: bridge 54 | hostname: chinesesubfinder 55 | container_name: chinesesubfinder 56 | ports: 57 | - 19035:19035 # 从0.20.0版本开始,通过webui来设置 58 | logging: 59 | driver: "json-file" 60 | options: 61 | max-size: "100m" # 限制日志大小,可自行调整 62 | ``` 63 | 64 | 创建好后访问`http://:19035`来进行下一步设置。 65 | 66 | ## 关于PUID/PGID的说明 67 | 68 | 如在使用诸如emby、jellyfin、plex、qbittorrent、transmission、deluge、jackett、sonarr、radarr等等的docker镜像,请在创建本容器时的设置和它们的PUID/PGID和它们一样,如若真的不想设置为一样,至少要保证本容器PUID/PGID所定义的用户拥有你设置的媒体目录(示例中是`/media`)的读取和写入权限。 69 | 70 | ## 关于armv7设备的补充说明 71 | 72 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 73 | 74 | 解决办法如下: 75 | 76 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 77 | 78 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 79 | 80 | ``` 81 | security_opt: 82 | - seccomp=unconfined 83 | ``` 84 | 85 | ## 源码 86 | 87 | https://gitee.com/evine/dockerfiles/tree/master/chinesesubfinder 88 | 89 | https://github.com/devome/dockerfiles/tree/master/chinesesubfinder 90 | -------------------------------------------------------------------------------- /csf-cross-builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | WORKDIR /musl 3 | ARG ARCH="aarch64-linux-musl armv7l-linux-musleabihf i686-linux-musl" 4 | RUN baseurl=https://more.musl.cc/x86_64-linux-musl && \ 5 | apk add --no-cache bash musl-dev gcc g++ go npm tar curl gzip && \ 6 | for target in ${ARCH}; do \ 7 | curl -fsSL ${baseurl}/${target}-cross.tgz -o ${target}-cross.tgz && \ 8 | tar zxf ${target}-cross.tgz; \ 9 | done && \ 10 | rm -rf */usr $(find . -name "ld-musl-*.so.1") *.tgz && \ 11 | chown -R root:root . && \ 12 | ls -l 13 | -------------------------------------------------------------------------------- /csf-cross-builder/readme.md: -------------------------------------------------------------------------------- 1 | 本镜像用于使用musl-libc交叉编译docker镜像[allanpk716/chinesesubfinder:latest-lite](https://github.com/allanpk716/ChineseSubFinder) -------------------------------------------------------------------------------- /ddns/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Dockerfile* -------------------------------------------------------------------------------- /ddns/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:${ALPINE_VERSION} 3 | ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ 4 | LANG=zh_CN.UTF-8 \ 5 | SHELL=/bin/bash \ 6 | PS1="\u@\h:\w \$ " \ 7 | CRON="3-53/5 * * * *" 8 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ 9 | && apk update -f \ 10 | && apk --no-cache add -f \ 11 | bash \ 12 | curl \ 13 | openssl \ 14 | tzdata \ 15 | tini \ 16 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 17 | && echo "Asia/Shanghai" > /etc/timezone \ 18 | && rm -rf /var/cache/apk/* \ 19 | && echo -e '#!/usr/bin/env bash\necho "$CRON ddns -c /config/config.json" | crontab -\nexec -- "$@"' > /usr/local/bin/entrypoint.sh \ 20 | && chmod +x /usr/local/bin/entrypoint.sh 21 | COPY --from=newfuture/ddns:latest /ddns /usr/local/bin/ddns 22 | VOLUME ["/config"] 23 | ENTRYPOINT ["tini", "entrypoint.sh"] 24 | CMD ["crond", "-f"] 25 | WORKDIR /config -------------------------------------------------------------------------------- /ddns/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/ddns" 4 | arch="linux/amd64,linux/arm64,linux/arm/v7" 5 | ver=$(curl -s https://api.github.com/repos/NewFuture/DDNS/releases/latest | jq -r .tag_name | sed "s/v//") 6 | alpine_ver=${1:-latest} 7 | 8 | buildx() { 9 | docker pull tonistiigi/binfmt 10 | docker run --privileged --rm tonistiigi/binfmt --install all 11 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 12 | docker buildx inspect --bootstrap 13 | docker buildx build \ 14 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 15 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 16 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 17 | --platform "$arch" \ 18 | --tag ${repo}:${ver} \ 19 | --tag ${repo}:latest \ 20 | --push \ 21 | . 22 | docker pushrm $repo # https://github.com/christian-korneck/docker-pushrm 23 | } 24 | 25 | if [[ $ver ]]; then 26 | [[ ! -d logs ]] && mkdir logs 27 | echo "alpine_ver=${1:-latest}" 28 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 29 | else 30 | echo "未获取到最新版本号" 31 | fi 32 | -------------------------------------------------------------------------------- /ddns/readme.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 基于 https://hub.docker.com/r/newfuture/ddns 调整了一点点自己想用的内容而已,也可以使用官方原版。 4 | 5 | 本镜像和原版的一点点区别: 6 | - 原版直接映射一个config.json文件,本镜像映射一个文件夹config,这个文件夹下除了要放config.json,还可以放一些其他的辅助脚本; 7 | - 原版的cron无法自定义,本镜像可以; 8 | - 把时区调整为北京时间; 9 | - 增加了bash, curl包,方便自己写获取ip的shell脚本。 10 | 11 | ## 创建 12 | 13 | ### 1.持续运行,并定时自动检查更新IP 14 | 15 | **命令行** 16 | 17 | ``` 18 | docker run -d \ 19 | --name ddns \ 20 | --resart always \ 21 | -v $(pwd)/ddns:/config `# 冒号左边请设置为你保存的按官方配置教程配置好的config.json所在文件夹的路径` \ 22 | -e CRON="3-53/5 * * * *" `# 可以自定义cron` \ 23 | nevinee/ddns 24 | ``` 25 | 26 | **docker-compose** 27 | 28 | 创建`docker-compose.yml`如下,并以`docker-compose up -d`启动。 29 | ``` 30 | version: "2.0" 31 | services: 32 | ddns: 33 | image: nevinee/ddns 34 | container_name: ddns 35 | restart: always 36 | network_mode: host 37 | hostname: ddns 38 | volumes: 39 | - ./:/config #文件夹下必须存在按官方教程配置好的config.json 40 | environment: 41 | - CRON=3-53/5 * * * * # 可以自定义 42 | ``` 43 | 44 | ### 2.只运行一次 45 | 46 | ``` 47 | docker run --rm -v $(pwd)/config.json:/config.json nevinee/ddns ddns -c /config.json 48 | ``` 49 | 50 | 注:请将命令中的`$(pwd)/config.json`修改为你保存config.json的路径。 51 | 52 | ## 关于armv7设备的补充说明 53 | 54 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 55 | 56 | 解决办法如下: 57 | 58 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 59 | 60 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 61 | 62 | ``` 63 | security_opt: 64 | - seccomp=unconfined 65 | ``` 66 | 67 | ## Dockerfile 68 | 69 | https://gitee.com/evine/dockerfiles/tree/master/ddns 70 | 71 | https://github.com/devome/dockerfiles/tree/master/ddns 72 | -------------------------------------------------------------------------------- /iperf3/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Dockerfile 3 | -------------------------------------------------------------------------------- /iperf3/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:${ALPINE_VERSION} 3 | ARG VERSION 4 | RUN apk add --no-cache --virtual .build \ 5 | curl \ 6 | musl-dev \ 7 | make \ 8 | gcc \ 9 | tar \ 10 | gzip \ 11 | && mkdir -p /tmp/build \ 12 | && cd /tmp/build \ 13 | && curl -sSL https://github.com/esnet/iperf/archive/refs/tags/${VERSION}.tar.gz | tar xz --strip-components 1 \ 14 | && ./configure --prefix=/usr --disable-static \ 15 | && make install-strip \ 16 | && apk del --purge .build \ 17 | && apk add libcrypto1.1 \ 18 | && rm -rf /tmp/* /var/cache/apk/* 19 | ENTRYPOINT ["iperf3"] 20 | CMD ["-s"] 21 | -------------------------------------------------------------------------------- /iperf3/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/iperf3" 4 | arch="linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x" 5 | ver=$(curl -s https://api.github.com/repos/esnet/iperf/tags | jq -r .[].name | grep -m1 -P "^[\d\.]+$") 6 | alpine_ver=${1:-latest} 7 | 8 | buildx() { 9 | docker pull tonistiigi/binfmt 10 | docker run --privileged --rm tonistiigi/binfmt --install all 11 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 12 | docker buildx inspect --bootstrap 13 | docker buildx build \ 14 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 15 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 16 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 17 | --build-arg "VERSION=$ver" \ 18 | --platform "$arch" \ 19 | --tag ${repo}:${ver} \ 20 | --tag ${repo}:latest \ 21 | --push \ 22 | . 23 | docker pushrm -s "局域网测速工具iperf3" $repo # https://github.com/christian-korneck/docker-pushrm 24 | } 25 | 26 | if [[ $ver ]]; then 27 | [[ ! -d logs ]] && mkdir logs 28 | echo "alpine_ver=${1:-latest}" 29 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 30 | else 31 | echo "未获取到最新版本号" 32 | fi 33 | -------------------------------------------------------------------------------- /iperf3/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | 这个项目的Docker实现:https://github.com/esnet/iperf ,这是著名的局域网测速工具。 4 | 5 | Docker的网络结构会对速度有影响,因此非必要情况下,不建议使用Docker版。 6 | 7 | ## 运行 8 | 9 | ``` 10 | ## 以服务器形式运行,接收其他客户端开展测速 11 | docker run -it --rm -p 5201:5201 nevinee/iperf3 -s # 前台 12 | docker run -itd -p 5201:5201 nevinee/iperf3 -s # 后台 13 | 14 | ## 以客户端形式运行,去连接服务器开展测速,运行完即自动删除容器 15 | docker run --rm -it nevinee/iperf3 -c <服务器ip> 16 | 17 | ## 查看帮助 18 | docker run --rm nevinee/iperf3 -h 19 | ``` 20 | 21 | ## 关于armv7设备的补充说明 22 | 23 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 24 | 25 | 解决办法如下: 26 | 27 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 28 | 29 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 30 | 31 | ``` 32 | security_opt: 33 | - seccomp=unconfined 34 | ``` -------------------------------------------------------------------------------- /iyuuautoreseed/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !entrypoint.sh 3 | !Dockerfile* -------------------------------------------------------------------------------- /iyuuautoreseed/Dockerfile: -------------------------------------------------------------------------------- 1 | ## 修改自:https://github.com/ledccn/IYUUAutoReseed 2 | 3 | ARG ALPINE_VERSION=latest 4 | FROM alpine:${ALPINE_VERSION} 5 | ENV APP_ENV=prod \ 6 | LANG=zh_CN.UTF-8 \ 7 | TZ=Asia/Shanghai \ 8 | PS1="\u@\h:\w \$ " 9 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories \ 10 | && apk add --no-cache --update \ 11 | bash \ 12 | git \ 13 | tzdata \ 14 | php7 \ 15 | php7-curl \ 16 | php7-dom \ 17 | php7-json \ 18 | php7-mbstring \ 19 | php7-simplexml \ 20 | php7-zip \ 21 | php7-xml \ 22 | && echo -e "upload_max_filesize=100M\npost_max_size=108M\nmemory_limit=1024M\ndate.timezone=${TZ}" > /etc/php7/conf.d/99-overrides.ini \ 23 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 24 | && echo "${TZ}" > /etc/timezone \ 25 | && rm -rf \ 26 | /var/cache/apk/* \ 27 | /tmp/* \ 28 | /usr/share/man \ 29 | /usr/share/php7 30 | COPY entrypoint.sh /usr/local/bin/entrypoint.sh 31 | WORKDIR /iyuu 32 | VOLUME ["/iyuu"] 33 | ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -------------------------------------------------------------------------------- /iyuuautoreseed/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ ! -d /iyuu/.git ]]; then 4 | git clone https://gitee.com/ledc/IYUUAutoReseed.git /iyuu 5 | else 6 | git -C /iyuu pull 7 | fi 8 | 9 | if [[ ! -s /iyuu/config/config.php ]]; then 10 | cp /iyuu/config/config.sample.php /iyuu/config/config.php 11 | fi 12 | 13 | if [[ -z ${CRON_GIT_PULL} ]]; then 14 | CRON_GIT_PULL="23 7,19 * * *" 15 | fi 16 | 17 | if [[ -z ${CRON_IYUU} ]]; then 18 | CRON_IYUU="51 7,19 * * *" 19 | fi 20 | 21 | echo "设置cron..." 22 | echo -e "${CRON_GIT_PULL} git -C /iyuu pull\n${CRON_IYUU} php /iyuu/iyuu.php" | crontab - 23 | 24 | echo "当前crontab如下:" 25 | crontab -l 26 | 27 | exec crond -f 28 | -------------------------------------------------------------------------------- /iyuuautoreseed/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | https://github.com/ledccn/IYUUAutoReseed ,官方提供了Docker镜像的,建议选择官方的镜像。本镜像主要是为了本人使用方便。 4 | 5 | ## 本镜像创建 6 | 7 | ``` 8 | version: "2.0" 9 | services: 10 | iyuuautoreseed: 11 | image: nevinee/iyuuautoreseed 12 | container_name: iyuuautoreseed 13 | restart: always 14 | network_mode: bridge 15 | hostname: iyuuautoreseed 16 | volumes: 17 | - ./iyuu:/iyuu # 首次启动前映射的iyuu文件夹必须是空的 18 | environment: 19 | - CRON_GIT_PULL=23 7,19 * * * # 更新脚本的cron 20 | - CRON_IYUU=51 7,19 * * * # 辅种程序的cron 21 | ``` 22 | 23 | 创建好后编辑`./iyuu/config/config.php`即可,不负责解释一切疑问。 24 | 25 | ## 关于armv7设备的补充说明 26 | 27 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 28 | 29 | 解决办法如下: 30 | 31 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 32 | 33 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 34 | 35 | ``` 36 | security_opt: 37 | - seccomp=unconfined 38 | ``` 39 | -------------------------------------------------------------------------------- /iyuuplus/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !entrypoint.sh 3 | !Dockerfile* -------------------------------------------------------------------------------- /iyuuplus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV APP_ENV=prod \ 3 | LANG=zh_CN.UTF-8 \ 4 | TZ=Asia/Shanghai \ 5 | PUID=1000 \ 6 | PGID=1000\ 7 | PS1="\u@\h:\w \$ " 8 | WORKDIR /IYUU 9 | RUN apk add --no-cache \ 10 | su-exec \ 11 | busybox-suid \ 12 | shadow \ 13 | ca-certificates \ 14 | curl \ 15 | tar \ 16 | libressl \ 17 | openssl \ 18 | wget \ 19 | zip \ 20 | unzip \ 21 | git \ 22 | tzdata \ 23 | pcre \ 24 | tini \ 25 | composer \ 26 | php81 \ 27 | php81-curl \ 28 | php81-dom \ 29 | php81-json \ 30 | php81-mbstring \ 31 | php81-openssl \ 32 | php81-opcache \ 33 | php81-pdo \ 34 | php81-pdo_sqlite \ 35 | php81-phar \ 36 | php81-pcntl \ 37 | php81-posix \ 38 | php81-simplexml \ 39 | php81-sockets \ 40 | php81-session \ 41 | php81-zip \ 42 | php81-zlib \ 43 | php81-xml \ 44 | && git config --global pull.ff only \ 45 | && git config --global --add safe.directory /IYUU \ 46 | && echo -e "upload_max_filesize=100M\npost_max_size=108M\nmemory_limit=1024M\ndate.timezone=${TZ}" > /etc/php81/conf.d/99-overrides.ini \ 47 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 48 | && echo "${TZ}" > /etc/timezone \ 49 | && useradd iyuu -u ${PUID} -U -M -d /IYUU -s /sbin/nologin \ 50 | && git clone --depth=1 https://github.com/ledccn/IYUUPlus.git . \ 51 | && rm -rf /var/cache/apk/* /tmp/* /usr/share/man /usr/share/php81 \ 52 | && sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/' /etc/apk/repositories 53 | COPY entrypoint.sh /usr/local/bin/entrypoint.sh 54 | EXPOSE 8787 55 | VOLUME ["/IYUU"] 56 | ENTRYPOINT ["tini", "entrypoint.sh"] 57 | -------------------------------------------------------------------------------- /iyuuplus/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/iyuuplus" 4 | arch="linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x" 5 | ver=$(curl -s https://gitee.com/ledc/iyuuplus/raw/master/app/functions.php | grep -P "return \'(\d+\.?){3,4}\'" | head -1 | perl -pe "s|[\D\.]+((\d+\.?){3,4}).*|\1|") 6 | alpine_ver=${1:-latest} 7 | 8 | buildx() { 9 | docker pull tonistiigi/binfmt 10 | docker run --privileged --rm tonistiigi/binfmt --install all 11 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 12 | docker buildx inspect --bootstrap 13 | docker buildx build \ 14 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 15 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 16 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 17 | --platform "$arch" \ 18 | --tag ${repo}:${ver} \ 19 | --tag ${repo}:latest \ 20 | --push \ 21 | . 22 | docker pushrm $repo # https://github.com/christian-korneck/docker-pushrm 23 | } 24 | 25 | if [[ $ver ]]; then 26 | [[ ! -d logs ]] && mkdir logs 27 | echo "alpine_ver=${1:-latest}" 28 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 29 | else 30 | echo "未获取到最新版本号" 31 | fi 32 | -------------------------------------------------------------------------------- /iyuuplus/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd /IYUU 4 | 5 | ## 更新 6 | if [[ ! -d .git ]]; then 7 | git clone https://github.com/ledccn/IYUUPlus.git /tmp/IYUU 8 | #git clone https://gitee.com/ledc/iyuuplus.git /tmp/IYUU 9 | find /tmp/IYUU -mindepth 1 -maxdepth 1 | xargs -I {} cp -r {} /IYUU 10 | rm -rf /tmp/IYUU 11 | else 12 | git fetch --all 13 | git reset --hard origin/master 14 | git pull 15 | fi 16 | 17 | if [[ ! -s .env ]]; then 18 | cp -f .env.example .env 19 | fi 20 | 21 | if [ ! -d db ]; then 22 | mkdir db 23 | fi 24 | 25 | ## 生成crontab 26 | if [[ -z "${CRON_UPDATE}" ]]; then 27 | minute=$(($RANDOM % 60)) 28 | hour_start=$(($RANDOM % 6)) 29 | hour_interval=$(($RANDOM % 4 + 6)) 30 | CRON_UPDATE="${minute} ${hour_start}-23/${hour_interval} * * *" 31 | fi 32 | crontmp=$(mktemp) 33 | echo "${CRON_UPDATE} cd /IYUU && git fetch --all && git reset --hard origin/master && git pull && php start.php restart -d" > $crontmp 34 | echo "设置crontab如下:" 35 | cat $crontmp 36 | 37 | ## 重置权限 38 | groupmod -o -g "${PGID}" iyuu 39 | usermod -o -u "${PUID}" iyuu 40 | chown -R ${PUID}:${PGID} $crontmp /IYUU 41 | su-exec ${PUID}:${PGID} crontab $crontmp 42 | rm $crontmp 43 | 44 | ## 启动 45 | su-exec ${PUID}:${PGID} php start.php start -d 46 | exec crond -f 47 | -------------------------------------------------------------------------------- /iyuuplus/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | 本镜像测试通过以后就把代码PR到了官方仓库中:https://github.com/ledccn/IYUUPlus 4 | 5 | **2022年1月18日,本镜像增加了一项功能:允许用户以非root用户权限运行iyuuplus,修改PUID,PGID两个环境变量即可。未推送到官方。** 6 | 7 | **2022年6月29日,先合并官方未合并的[#57](https://github.com/ledccn/IYUUPlus/pull/57),本镜像已经可以用于qBittorrent 4.4.x版本转移种子了。** 8 | 9 | ## 说明 10 | 11 | 因为从php7升级到了php8,如果要使用旧的配置文件,需要作些修改工作,请从下列方式中**选择其一进行**: 12 | 13 | - 修改配置文件夹db下的`crontab.php`和`crontab.json`,将其中的`php7`改为`php`; 14 | 15 | - 删除配置文件夹db下的`crontab.php`和`crontab.json`,然后重新设置定时任务; 16 | 17 | - 删除原有所有配置文件,全新创建容器。 18 | 19 | ## 创建 20 | 21 | ### docker compose 22 | ``` 23 | version: "3.8" 24 | services: 25 | iyuuplus: 26 | image: nevinee/iyuuplus 27 | container_name: iyuuplus 28 | restart: always 29 | network_mode: bridge 30 | hostname: iyuuplus 31 | volumes: 32 | - ./db:/IYUU/db 33 | - /qb种子路径/:/BT_backup 34 | - /tr种子路径/:/torrent 35 | environment: 36 | - PUID=1000 # 以什么用记运行iyuuplus,该用户的uid 37 | - PGID=100 # 以什么用记运行iyuuplus,该用户的gid 38 | ports: 39 | - 8787:8787 40 | ``` 41 | 42 | ### docker cli 43 | ``` 44 | docker run -d \ 45 | --name iyuuplus \ 46 | --hostname iyuuplus \ 47 | --restart always \ 48 | --network bridge \ 49 | --volume $(pwd)/db:/IYUU/db \ 50 | --volume /qb种子路径/:/BT_backup \ 51 | --volume /tr种子路径/:/torrent \ 52 | --env PUID=1000 `# 以什么用记运行iyuuplus,该用户的uid` \ 53 | --env PGID=100 `# 以什么用记运行iyuuplus,该用户的gid` \ 54 | --publish 8787:8787 \ 55 | nevinee/iyuuplus 56 | ``` 57 | 58 | ## 源代码、问题反馈、意见建议 59 | 60 | 全套代码见 [Github](https://github.com/devome/dockerfiles/tree/master/iyuuplus) 或 [Gitee](https://gitee.com/evine/dockerfiles/tree/master/iyuuplus)。 61 | 62 | 如有使用上的问题,或者有其他好的功能建议,请在 [Github这里](https://github.com/devome/dockerfiles/issues) 或 [Gitee这里](https://gitee.com/evine/dockerfiles/issues) 提交。 63 | -------------------------------------------------------------------------------- /libtorrent-rasterbar/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Dockerfile -------------------------------------------------------------------------------- /libtorrent-rasterbar/.gitignore: -------------------------------------------------------------------------------- 1 | *.version 2 | -------------------------------------------------------------------------------- /libtorrent-rasterbar/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | ARG LIBTORRENT_VERSION 3 | ARG JNPROC=1 4 | RUN apk add --no-cache --virtual .build \ 5 | boost-dev \ 6 | openssl-dev \ 7 | cmake \ 8 | g++ \ 9 | samurai \ 10 | curl \ 11 | tar \ 12 | && mkdir -p /tmp/libtorrent-rasterbar \ 13 | && cd /tmp/libtorrent-rasterbar \ 14 | && curl -sSL https://github.com/arvidn/libtorrent/releases/download/v${LIBTORRENT_VERSION}/libtorrent-rasterbar-${LIBTORRENT_VERSION}.tar.gz | tar xz --strip-components 1 \ 15 | && cmake \ 16 | -DCMAKE_BUILD_TYPE=Release \ 17 | -DCMAKE_CXX_STANDARD=17 \ 18 | -DBUILD_SHARED_LIBS=ON \ 19 | -Brelease \ 20 | -GNinja \ 21 | && cd release \ 22 | && ninja -j${JNPROC} \ 23 | && ninja install \ 24 | && ls -al /usr/local/lib \ 25 | && run_deps="$(scanelf -nB /usr/local/lib/libtorrent-rasterbar* | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' | xargs -r apk info -e | sort -u)" \ 26 | && apk del --purge .build \ 27 | && apk add --no-cache $run_deps \ 28 | && rm -rf /tmp/* /var/cache/apk/* -------------------------------------------------------------------------------- /libtorrent-rasterbar/buildx-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 请不要直接运行本脚本,请通过运行 buildx.sh 脚本来调用本脚本。 4 | 5 | set -e 6 | 7 | for arch in ${BUILDX_ARCH}; do 8 | echo "------------------------- 构建目标平台:linux/${arch} -------------------------" 9 | docker buildx build \ 10 | --tag ${DOCKERHUB_REPOSITORY}:${LIBTORRENT_VERSION}-${arch//\//-} \ 11 | --output "type=${OUTPUT}" \ 12 | --platform linux/${arch} \ 13 | --build-arg "LIBTORRENT_VERSION=${LIBTORRENT_VERSION}" \ 14 | --build-arg "JNPROC=${JNPROC}" \ 15 | --file ${DOCKERFILE_NAME} \ 16 | . 17 | done 18 | -------------------------------------------------------------------------------- /libtorrent-rasterbar/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 1. 运行脚本的前提:已经安装docker、docker-pushrm、hub-tool,已经登陆docker和hub-tool; 4 | ## 2. 本地编译仍然会花费好几个小时; 5 | ## 3. 在Dockerfile同目录下运行; 6 | ## 4. 请使用root用户运行; 7 | ## 5. 宿主机安装好 moreutils 这个包; 8 | ## 6. 运行build.sh -h查看帮助 9 | 10 | set -o pipefail 11 | 12 | ## 跨平台构建相关 13 | prepare_buildx() { 14 | docker pull tonistiigi/binfmt 15 | docker run --privileged --rm tonistiigi/binfmt --install all 16 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 17 | docker buildx inspect --bootstrap 18 | } 19 | 20 | ## 构建 21 | docker_build() { 22 | for ((c=1; c<=${BUILD_COUNT}; c++)); do 23 | echo "============================= 第 $c 次构建尝试 =============================" 24 | ./buildx-build.sh && break 25 | done 26 | } 27 | 28 | ## 推送 29 | docker_push() { 30 | if [[ ${OUTPUT} == docker ]]; then 31 | for arch in ${BUILDX_ARCH}; do 32 | docker push ${DOCKERHUB_REPOSITORY}:${QBITTORRENT_VERSION}-${arch//\//-} 33 | done 34 | fi 35 | } 36 | 37 | ## 维护标签 38 | docker_manifest() { 39 | for ((n=1; n<=${MANIFEST_COUNT}; n++)); do 40 | echo "============================= 第 $n 次信息维护 =============================" 41 | for tag in ${MULTITAGS}; do 42 | docker manifest create --insecure "${DOCKERHUB_REPOSITORY}:${tag}" "${IMAGES[@]}" 43 | docker manifest push --insecure --purge "${DOCKERHUB_REPOSITORY}:${tag}" 44 | done 45 | done 46 | } 47 | 48 | ## 删除单平台标签,需要先安装好hub-tool:https://github.com/docker/hub-tool 49 | del_tag() { 50 | for image in ${IMAGES[@]}; do 51 | hub-tool tag rm --verbose -f $image 52 | done 53 | } 54 | 55 | ## 基础函数 56 | base_func() { 57 | cd $(dirname $0) 58 | [[ ! -d logs ]] && mkdir logs 59 | 60 | ## 版本、仓库名、网址等 61 | export DOCKER_CLI_EXPERIMENTAL=enabled 62 | export LATEST_VERSION=$(curl -s https://api.github.com/repos/arvidn/libtorrent/tags | jq -r .[]."name" | grep -m1 -E "v([0-9]{1,2}\.?){3,4}$" | sed "s/v//") 63 | 64 | [[ $ver ]] && export LIBTORRENT_VERSION=$ver || export LIBTORRENT_VERSION=${LATEST_VERSION} 65 | [[ $repo ]] && export DOCKERHUB_REPOSITORY=$repo || export DOCKERHUB_REPOSITORY=nevinee/libtorrent-rasterbar 66 | [[ $filename ]] && export DOCKERFILE_NAME=${filename} || export DOCKERFILE_NAME=Dockerfile 67 | [[ $bcount ]] && export BUILD_COUNT=$bcount || export BUILD_COUNT=20 68 | [[ $mcount ]] && export MANIFEST_COUNT=$mcount || export MANIFEST_COUNT=1 69 | [[ $jnproc ]] && export JNPROC=$jnproc || export JNPROC=1 70 | [[ $output ]] && export OUTPUT=$ourput || export OUTPUT=registry 71 | [[ $archtech ]] && export BUILDX_ARCH="$archtech" || export BUILDX_ARCH="386 amd64 arm64 arm/v6 arm/v7 ppc64le s390x" 72 | 73 | ## 标签 74 | MAJOR_VERSION=$(echo ${LIBTORRENT_VERSION} | perl -pe "s|^(\d+)\..+|\1|") 75 | MULTITAGS="${LIBTORRENT_VERSION} ${MAJOR_VERSION}" 76 | 77 | ## 单平台标签数组 78 | IMAGES=() 79 | for arch in ${BUILDX_ARCH}; do 80 | IMAGES+=( "${DOCKERHUB_REPOSITORY}:${LIBTORRENT_VERSION}-${arch//\//-}" ) 81 | done 82 | } 83 | 84 | ## 输出 85 | echo_console() { 86 | echo "控制变量如下:" 87 | echo "LIBTORRENT_VERSION=${LIBTORRENT_VERSION}" 88 | echo "DOCKERHUB_REPOSITORY=${DOCKERHUB_REPOSITORY}" 89 | echo "DOCKERFILE_NAME=${DOCKERFILE_NAME}" 90 | echo "BUILDX_ARCH='${BUILDX_ARCH}'" 91 | echo "MULTITAGS='${MULTITAGS}'" 92 | echo "JNPROC=${JNPROC}" 93 | echo "OUTPUT=${OUTPUT}" 94 | echo "IMAGES[@]='${IMAGES[@]}'" 95 | } 96 | 97 | ## 用法 98 | usage() { 99 | echo "可接受选项:" 100 | echo "-a # 可用动作见下,默认all" 101 | echo "-b # 针对unstable版本,仅推送'unstable'标签,不推送版本标签" 102 | echo "-c # 构建镜像尝试次数上限,默认20" 103 | echo "-d # Dockerfile文件路径,默认Dockerfile" 104 | echo "-j # 用来编译的核心数,默认1" 105 | echo "-l # 是否记录日志[YES|Yes|yes|y / NO|No|no|n],默认yes" 106 | echo "-n # 信息维护次数,默认1" 107 | echo "-o # 输出到镜像(docker)还是直接推送到hub(registry),默认registry" 108 | echo "-r # 构建镜像名(不含标签),默认nevinee/libtorrent-rasterbar" 109 | echo "-t # 构建架构,默认全构架" 110 | echo "-v # 构建版本,默认最新稳定版" 111 | echo 112 | echo "其中'-a'选项可接受的动作:" 113 | echo "A|all # 构建镜像、推送镜像、维护信息、删除标签(默认值)" 114 | echo "a|all_except_deltag # 构建镜像、推送镜像、维护信息" 115 | echo "b|build # 构建镜像" 116 | echo "p|push # 推送镜像" 117 | echo "P|push_manifest # 推送镜像、维护信息" 118 | echo "Q|push_manifest_deltag # 推送镜像、维护信息、删除标签" 119 | echo "m|manifest # 维护信息" 120 | echo "M|manifest_deltag # 维护信息、删除标签" 121 | echo "d|deltag # 删除标签" 122 | } 123 | 124 | ## 运行 125 | run() { 126 | case $1 in 127 | a | all_except_deltag) # 构建镜像、推送镜像、更新教程、维护信息 128 | echo_console 129 | echo "BUILD_COUNT=${BUILD_COUNT}" 130 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 131 | prepare_buildx 132 | docker_build && { 133 | docker_push 134 | docker_manifest 135 | docker_pushrm 136 | } || { 137 | echo "构建失败,不推送镜像,不维护信息,退出!" 138 | exit 4 139 | } 140 | ;; 141 | A | all) # 构建镜像、推送镜像、维护信息、更新教程、删除标签 142 | echo_console 143 | echo "BUILD_COUNT=${BUILD_COUNT}" 144 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 145 | prepare_buildx 146 | docker_build && { 147 | docker_push 148 | docker_manifest 149 | docker_pushrm 150 | del_tag 151 | } || { 152 | echo "构建失败,不推送镜像,不维护信息,退出!" 153 | exit 4 154 | } 155 | ;; 156 | b | build) # 构建镜像 157 | echo_console 158 | echo "BUILD_COUNT=${BUILD_COUNT}" 159 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 160 | prepare_buildx 161 | docker_build 162 | ;; 163 | d | deltag) # 删除标签 164 | echo_console 165 | del_tag 166 | ;; 167 | m | manifest) # 维护信息 168 | echo_console 169 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 170 | docker_manifest 171 | ;; 172 | M | manifest_deltag) # 维护信息、删除标签 173 | echo_console 174 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 175 | docker_manifest 176 | del_tag 177 | ;; 178 | p | push) # 推送镜像 179 | echo_console 180 | docker_push 181 | ;; 182 | P | push_manifest) # 推送镜像、维护信息 183 | echo_console 184 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 185 | docker_push 186 | docker_manifest 187 | ;; 188 | Q | push_manifest_deltag) # 推送镜像、维护信息、删除标签 189 | echo_console 190 | echo "MANIFEST_COUNT=${MANIFEST_COUNT}" 191 | docker_push 192 | docker_manifest 193 | del_tag 194 | ;; 195 | esac 196 | } 197 | 198 | ## 主函数 199 | main() { 200 | while getopts :a:bc:f:j:l:n:r:t:v: opt; do 201 | case $opt in 202 | # 传入参数 203 | a) action=$OPTARG;; 204 | b) onlyunstable=yes;; 205 | c) bcount=$OPTARG;; 206 | f) filename=$OPTARG;; 207 | j) jnproc=$OPTARG;; 208 | l) log=$OPTARG;; 209 | n) mcount=$OPTARG;; 210 | o) output=$OPTARG;; 211 | r) repo=$OPTARG;; 212 | t) archtech=$OPTARG;; 213 | v) ver=$OPTARG;; 214 | 215 | # 帮助 216 | ?) usage; exit 1;; 217 | esac 218 | done 219 | shift $((OPTIND - 1)) 220 | [[ $1 ]] && usage && exit 2 221 | [[ -z $action ]] && action=all 222 | [[ -z $log ]] && log=yes 223 | case $action in 224 | A|all|a|all_except_deltag|b|build|p|push|P|push_manifest|Q|push_manifest_deltag|m|manifest|M|manifest_deltag|d|deltag) 225 | base_func 226 | case $log in 227 | YES|Yes|yes|y) run $action 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${LIBTORRENT_VERSION}.log;; 228 | NO|No|no|n) run $action 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]";; 229 | esac 230 | ;; 231 | *) 232 | usage 233 | exit 3 234 | ;; 235 | esac 236 | } 237 | 238 | main "$@" 239 | -------------------------------------------------------------------------------- /libtorrent-rasterbar/readme.md: -------------------------------------------------------------------------------- 1 | 本镜像已将这个项目 https://github.com/arvidn/libtorrent 编译为库文件,用来后续进一步编译qbittorrent用的。 2 | 3 | Dockerfile 4 | 5 | https://gitee.com/evine/dockerfiles/tree/master/libtorrent-rasterbar 6 | 7 | https://github.com/devome/dockerfiles/tree/master/libtorrent-rasterbar -------------------------------------------------------------------------------- /libtorrent-rasterbar/version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o pipefail 4 | 5 | dir_shell=$(cd $(dirname $0); pwd) 6 | dir_myscripts=$(cd $(dirname $0); cd ../../myscripts; pwd) 7 | 8 | cd $dir_shell 9 | 10 | ## 官方版本 11 | lib_tag=$(curl -s --retry 5 --retry-delay 8 https://api.github.com/repos/arvidn/libtorrent/tags) 12 | ver_lib1_official=$(echo $lib_tag | jq -r .[].name | grep -m1 -E "v1(\.[0-9]+){2,3}$" | sed "s/v//") 13 | ver_lib2_official=$(echo $lib_tag | jq -r .[].name | grep -m1 -E "v2(\.[0-9]+){2,3}$" | sed "s/v//") 14 | 15 | ## 本地版本 16 | ver_lib1_local=$(cat 1.x.version) 17 | ver_lib2_local=$(cat 2.x.version) 18 | 19 | ## 导入通知程序及配置 20 | . $dir_myscripts/notify.sh 21 | . $dir_myscripts/my_config.sh 22 | 23 | ## 检测官方版本与本地版本是否一致,如不一致则发出通知 24 | build_mark_1=0 25 | if [[ $ver_lib1_official ]]; then 26 | if [[ $ver_lib1_official != $ver_lib1_local ]]; then 27 | echo "官方已升级libtorrent-1.x版本至:$ver_lib1_official" 28 | notify "libtorrent-1.x已经升级" "当前官方版本: ${ver_lib1_official}\n当前本地版本: ${ver_lib1_local}" 29 | echo "$ver_lib1_official" > 1.x.version 30 | build_mark_1=1 31 | else 32 | echo -e "libtorrent-1.x版本无变化,均为${ver_lib1_official}" 33 | fi 34 | fi 35 | 36 | build_mark_2=0 37 | if [[ $ver_lib2_official ]]; then 38 | if [[ $ver_lib2_official != $ver_lib2_local ]]; then 39 | echo "官方已升级libtorrent-2.x版本至:$ver_lib2_official" 40 | notify "libtorrent-2.x已经升级" "当前官方版本: ${ver_lib2_official}\n当前本地版本: ${ver_lib2_local}" 41 | echo "$ver_lib2_official" > 2.x.version 42 | build_mark_2=1 43 | else 44 | echo -e "libtorrent-2.x版本无变化,均为${ver_lib2_official}" 45 | fi 46 | fi 47 | 48 | ## 需要更新时则重新构建 49 | # if [[ $build_mark_1 -eq 1 ]]; then 50 | # ./buildx.sh -v$ver_lib1_official 51 | # fi 52 | 53 | # if [[ $build_mark_2 -eq 1 ]]; then 54 | # ./buildx.sh -v$ver_lib2_official 55 | # fi 56 | -------------------------------------------------------------------------------- /loop/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ARG TARGET 3 | COPY bin/$TARGET/loop /usr/local/bin/loop -------------------------------------------------------------------------------- /loop/bin/aarch64-unknown-linux-musl/loop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/loop/bin/aarch64-unknown-linux-musl/loop -------------------------------------------------------------------------------- /loop/bin/armv7-unknown-linux-musleabihf/loop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/loop/bin/armv7-unknown-linux-musleabihf/loop -------------------------------------------------------------------------------- /loop/bin/x86_64-unknown-linux-musl/loop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/loop/bin/x86_64-unknown-linux-musl/loop -------------------------------------------------------------------------------- /loop/readme.md: -------------------------------------------------------------------------------- 1 | 这个项目 https://github.com/Miserlou/Loop 的Docker实现,支持 amd64/arm64/armv7 三大主流平台,镜像中仅有 `/usr/local/bin/loop` 这一个文件,如需使用,需要在Dokerfile中编写如下语句: 2 | 3 | ``` 4 | COPY --from=nevinee/loop / / 5 | ``` 6 | 7 | loop的详细用法见:https://github.com/Miserlou/Loop 8 | 9 | 一些使用案例: 10 | 11 | 1. https://gitee.com/evine/dockerfiles/blob/master/subfinder/entrypoint.sh#L16 12 | 13 | 2. https://gitee.com/evine/dockerfiles/blob/master/nodejs/s6-overlay/etc/services.d/refresh-cron/run 14 | 15 | Dockerfile见: 16 | 17 | https://gitee.com/evine/dockerfiles/tree/master/loop -------------------------------------------------------------------------------- /ncmdump/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Dockerfile* -------------------------------------------------------------------------------- /ncmdump/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV LANG=zh_CN.UTF-8 \ 3 | PS1="\u@\h:\w \$ " 4 | RUN apk add --update --no-cache \ 5 | python3 \ 6 | py3-pip \ 7 | && apk add --no-cache --virtual .build \ 8 | git \ 9 | gcc \ 10 | musl-dev \ 11 | && ln /usr/bin/python3 /usr/bin/python \ 12 | && pip install pycryptodome mutagen \ 13 | && pip install git+https://github.com/nondanee/ncmdump.git \ 14 | && apk del .build \ 15 | && rm -rf /tmp/* /root/.cache 16 | ENTRYPOINT ["/usr/bin/ncmdump"] 17 | -------------------------------------------------------------------------------- /ncmdump/readme.md: -------------------------------------------------------------------------------- 1 | 转换网易云的ncm格式为mp3/flac等其他格式。这个项目( https://github.com/nondanee/ncmdump ,已被屏蔽)的Docker实现,支持 amd64/arm64/armv7 三大主流平台。 2 | 3 | 查看具体用法 4 | 5 | ``` 6 | docker run --rm nevinee/ncmdump -h 7 | ``` 8 | 9 | 如 10 | 11 | ``` 12 | docker run --rm -v $(pwd):/music nevinee/ncmdump /music 13 | docker run --rm -v $(pwd):/music nevinee/ncmdump /music/xxx.ncm 14 | docker run --rm -v $(pwd):/music nevinee/ncmdump -r /music/xxx.ncm 15 | ``` 16 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 17 | 18 | 解决办法如下: 19 | 20 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 21 | 22 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 23 | 24 | ``` 25 | security_opt: 26 | - seccomp=unconfined 27 | ``` 28 | 29 | 30 | 源码: 31 | 32 | https://gitee.com/evine/dockerfiles/blob/master/ncmdump/Dockerfile 33 | 34 | https://github.com/devome/dockerfiles/blob/master/ncmdump/Dockerfile -------------------------------------------------------------------------------- /nginxwebui/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !src/target/nginxWebUI-*.jar 3 | !Dockerfile* 4 | !entrypoint.sh 5 | -------------------------------------------------------------------------------- /nginxwebui/.gitignore: -------------------------------------------------------------------------------- 1 | src 2 | version -------------------------------------------------------------------------------- /nginxwebui/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV LANG=zh_CN.UTF-8 \ 3 | TZ=Asia/Shanghai \ 4 | PUID=1000 \ 5 | PGID=1000 \ 6 | PS1="\u@\h:\w \$ " 7 | RUN apk upgrade \ 8 | && apk add --no-cache \ 9 | acme.sh \ 10 | curl \ 11 | fontconfig \ 12 | net-tools \ 13 | nginx \ 14 | nginx-mod-stream \ 15 | nginx-mod-http-headers-more \ 16 | nginx-mod-http-lua \ 17 | openjdk8-jre \ 18 | shadow \ 19 | su-exec \ 20 | tini \ 21 | ttf-dejavu \ 22 | tzdata \ 23 | wget \ 24 | && fc-cache -f -v \ 25 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 26 | && echo "${TZ}" > /etc/timezone \ 27 | && rm -rf /var/cache/apk/* /tmp/* \ 28 | && sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/g' /etc/apk/repositories 29 | COPY src/target/nginxWebUI-*.jar /home/nginxWebUI.jar 30 | COPY --chmod=755 entrypoint.sh /usr/local/bin/entrypoint.sh 31 | VOLUME ["/home/nginxWebUI"] 32 | ENTRYPOINT ["tini", "entrypoint.sh"] 33 | -------------------------------------------------------------------------------- /nginxwebui/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o pipefail 4 | 5 | repo="nevinee/nginxwebui" 6 | arch="linux/386,linux/amd64,linux/arm64,linux/arm/v7" 7 | 8 | buildx() { 9 | cd src 10 | mvn clean package 11 | cd .. 12 | docker pull tonistiigi/binfmt 13 | docker run --privileged --rm tonistiigi/binfmt --install all 14 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 15 | docker buildx inspect --bootstrap 16 | docker buildx build \ 17 | --platform "$arch" \ 18 | --tag ${repo}:${ver} \ 19 | --tag ${repo}:latest \ 20 | --push \ 21 | . 22 | } 23 | 24 | git -C src pull 25 | ver=$(cat src/pom.xml | grep -A1 nginxWebUI | grep version | perl -pe "s|.*((\d+\.?){3,}).*|\1|") 26 | if [[ $ver != $(cat version 2>/dev/null) ]]; then 27 | echo "构建镜像:$repo" 28 | echo "构建平台:$arch" 29 | echo "构建版本:$ver" 30 | echo "3秒后开始编译jar并构建镜像..." 31 | sleep 3 32 | [[ ! -d logs ]] && mkdir logs 33 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 34 | [[ $? -eq 0 ]] && { 35 | echo $ver > version 36 | docker pushrm -s "可视化配置nginx,支持386/amd64/arm64/armv7" $repo # https://github.com/christian-korneck/docker-pushrm 37 | } 38 | else 39 | echo "当前已经是最新版本:$ver" 40 | fi 41 | -------------------------------------------------------------------------------- /nginxwebui/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | groupmod -o -g "${PGID}" nginx 4 | usermod -o -u "${PUID}" nginx 5 | chown -R ${PUID}:${PGID} /home/nginxWebUI.jar /home/nginxWebUI /var/lib/nginx /var/log/nginx /run/nginx 6 | 7 | cd /home 8 | exec su-exec ${PUID}:${PGID} java -jar -Dfile.encoding=UTF-8 -Xmx64m nginxWebUI.jar ${BOOT_OPTIONS} >/dev/null 9 | -------------------------------------------------------------------------------- /nginxwebui/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | 这个项目的docker实现:https://gitee.com/cym1102/nginxWebUI 4 | 5 | ## 标签 6 | 7 | ### 3.0.0版本及以上 8 | 9 | `x.x.x` , `latest` 10 | 11 | 基于alpine制作的镜像,相比于v2版本,v3版本因作者大佬更换了依赖,可以基于alpine来制作镜像了,大大减小了镜像体积(大约减少一半),也大大减少了内存占用(也大约减少一半),支持平台:`linux/386` , `linux/amd64` , `linux/arm64` , `linux/arm/v7`。 12 | 13 | ### 2.9.4版本及以下 14 | 15 | 1. `x.x.x` , `latest` 16 | 17 | 基于ubuntu制作的镜像,体积较小,支持平台:`linux/amd64` , `linux/arm64` , `linux/arm/v7` 18 | 19 | 2. `x.x.x-debian` , `latest-debian` 20 | 21 | 基于debian制作的镜像,体积较大,支持平台:`linux/386` , `linux/amd64` , `linux/arm64` , `linux/arm/v7` , `linux/mips64le` 22 | 23 | ## 创建 24 | 25 | **除了镜像名称不一样,其实创建命令和官方是一样的,参见:https://gitee.com/cym1102/nginxWebUI** 26 | 27 | ## 源码 28 | 29 | https://gitee.com/evine/dockerfiles/tree/master/nginxwebui 30 | 31 | https://github.com/devome/dockerfiles/blob/master/nginxwebui 32 | -------------------------------------------------------------------------------- /nginxwebui/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | /usr/share/maven/ref/repository 3 | 4 | 5 | aliyun 6 | central 7 | aliyun maven 8 | https://maven.aliyun.com/repository/public 9 | 10 | 11 | huaweicloud 12 | central 13 | huaweicloud maven 14 | https://mirrors.huaweicloud.com/repository/maven/ 15 | 16 | 17 | tencentcloud 18 | central 19 | tencentloud maven 20 | http://mirrors.cloud.tencent.com/nexus/repository/maven-public/ 21 | 22 | 23 | -------------------------------------------------------------------------------- /nodejs/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !s6-overlay* 3 | !Dockerfile* -------------------------------------------------------------------------------- /nodejs/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:${ALPINE_VERSION} 3 | LABEL maintainer="Evine Deng " 4 | ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ 5 | HOME=/root \ 6 | LANG=zh_CN.UTF-8 \ 7 | SHELL=/bin/bash \ 8 | PS1="\u@\h:\w \$ " 9 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ 10 | && apk update -f \ 11 | && apk --no-cache add -f \ 12 | bash \ 13 | s6-overlay \ 14 | nodejs \ 15 | npm \ 16 | yarn \ 17 | openssl \ 18 | coreutils \ 19 | moreutils \ 20 | git \ 21 | wget \ 22 | curl \ 23 | nano \ 24 | tzdata \ 25 | && rm -rf /var/cache/apk/* \ 26 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 27 | && echo "Asia/Shanghai" > /etc/timezone 28 | COPY --from=nevinee/loop:latest / / 29 | COPY s6-overlay / 30 | WORKDIR /root 31 | ENTRYPOINT ["/init"] 32 | -------------------------------------------------------------------------------- /nodejs/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/nodejs" 4 | arch="linux/amd64,linux/arm64,linux/arm/v7" 5 | alpine_ver=${1:-latest} 6 | 7 | buildx() { 8 | docker pull tonistiigi/binfmt 9 | docker run --privileged --rm tonistiigi/binfmt --install all 10 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 11 | docker buildx inspect --bootstrap 12 | docker buildx build \ 13 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 14 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 15 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 16 | --platform "$arch" \ 17 | --tag ${repo}:latest \ 18 | --push \ 19 | . 20 | docker pushrm $repo # https://github.com/christian-korneck/docker-pushrm 21 | } 22 | 23 | [[ ! -d logs ]] && mkdir logs 24 | echo "alpine_ver=${1:-latest}" 25 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 26 | -------------------------------------------------------------------------------- /nodejs/readme.md: -------------------------------------------------------------------------------- 1 | 基于alpine集成了`nodejs yarn npm bash openssl coreutils moreutils git wget curl nano tzdata perl`,默认时区`Asia/Shanghai`。 2 | 3 | 创建: 4 | 5 | ```shell 6 | docker run -dit \ 7 | -v /宿主机上的目录/:/root \ 8 | --name nodejs \ 9 | --hostname nodejs \ 10 | nevinee/nodejs 11 | ``` 12 | 13 | 然后进入容器,你想干啥就干啥: 14 | 15 | ```shell 16 | docker exec -it nodejs bash 17 | ``` 18 | 19 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 20 | 21 | 解决办法如下: 22 | 23 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 24 | 25 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 26 | 27 | ``` 28 | security_opt: 29 | - seccomp=unconfined 30 | ``` 31 | 32 | 如果映射目录下存在`crontab.list`,将在创建后以它作为容器的定时任务。修改`crontab.list`两秒后会自动更新容器的cron。 33 | 34 | [![dockeri.co](http://dockeri.co/image/nevinee/nodejs)](https://hub.docker.com/r/nevinee/nodejs/) -------------------------------------------------------------------------------- /nodejs/s6-overlay/etc/services.d/crond/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | exec s6-setuidgid root crond -f &>/dev/null 4 | -------------------------------------------------------------------------------- /nodejs/s6-overlay/etc/services.d/refresh-cron/refresh-cron: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -s /root/crontab.list ] && [[ $(cat /root/crontab.list) != $(crontab -l) ]]; then 4 | echo "[services.d] 检测到/root/crontab.list有变化,立即刷新定时任务..." 5 | crontab /root/crontab.list 6 | fi -------------------------------------------------------------------------------- /nodejs/s6-overlay/etc/services.d/refresh-cron/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | echo -e "\n[services.d] ======================== 启动定时任务自动刷新程序 ========================\n" 4 | echo -e "[services.d] 每2秒检测一次$JD_DIR/config/crontab.list是否发生变化,如发生变化则立即刷新定时任务。\n" 5 | 6 | exec s6-setuidgid root loop -e 2s -- ./refresh-cron 7 | -------------------------------------------------------------------------------- /opbuilder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ 4 | SHELL=/bin/bash \ 5 | LANG=C.UTF-8 \ 6 | PS1="\u@\h:\w \$ " \ 7 | TZ=Asia/Shanghai \ 8 | PUID=1000 \ 9 | PGID=1000 \ 10 | ENABLE_CHOWN=false \ 11 | USERNAME=evine 12 | RUN echo "change repo..." \ 13 | && sed -i 's/archive.ubuntu.com/mirrors.bfsu.edu.cn/g' /etc/apt/sources.list \ 14 | && sed -i 's/security.ubuntu.com/mirrors.bfsu.edu.cn/g' /etc/apt/sources.list \ 15 | && sed -i 's/ports.ubuntu.com/mirrors.bfsu.edu.cn/g' /etc/apt/sources.list \ 16 | && apt-get update \ 17 | && apt-get upgrade -y \ 18 | && apt-get install --no-install-recommends -y \ 19 | # 额外装的包 20 | autojump \ 21 | bsdmainutils \ 22 | ca-certificates \ 23 | coreutils \ 24 | fzf \ 25 | htop \ 26 | jq \ 27 | moreutils \ 28 | openssh-client \ 29 | openssl \ 30 | perl \ 31 | sudo \ 32 | tzdata \ 33 | zsh \ 34 | # 编译需要的包 35 | ack \ 36 | antlr3 \ 37 | aria2 \ 38 | asciidoc \ 39 | autoconf \ 40 | automake \ 41 | autopoint \ 42 | binutils \ 43 | bison \ 44 | build-essential \ 45 | bzip2 \ 46 | ccache \ 47 | cmake \ 48 | cpio \ 49 | curl \ 50 | device-tree-compiler \ 51 | fastjar \ 52 | flex \ 53 | gawk \ 54 | gettext \ 55 | gcc-multilib \ 56 | g++-multilib \ 57 | git \ 58 | gperf \ 59 | haveged \ 60 | help2man \ 61 | intltool \ 62 | libc6-dev-i386 \ 63 | libelf-dev \ 64 | libglib2.0-dev \ 65 | libgmp3-dev \ 66 | libltdl-dev \ 67 | libmpc-dev \ 68 | libmpfr-dev \ 69 | libncurses5-dev \ 70 | libncursesw5-dev \ 71 | libpython3-dev \ 72 | libreadline-dev \ 73 | libssl-dev \ 74 | libtool \ 75 | lrzsz \ 76 | mkisofs \ 77 | msmtp \ 78 | nano \ 79 | ninja-build \ 80 | p7zip \ 81 | p7zip-full \ 82 | patch \ 83 | pkgconf \ 84 | python2.7 \ 85 | python3 \ 86 | python3-pyelftools \ 87 | python3-setuptools \ 88 | qemu-utils \ 89 | rsync \ 90 | scons \ 91 | squashfs-tools \ 92 | subversion \ 93 | swig \ 94 | texinfo \ 95 | uglifyjs \ 96 | upx-ucl \ 97 | unzip \ 98 | vim \ 99 | wget \ 100 | xmlto \ 101 | xxd \ 102 | zlib1g-dev \ 103 | && if [ ! -f /usr/bin/python ]; then cd /usr/bin; ln -s python3 python; fi \ 104 | && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \ 105 | && echo "$TZ" > /etc/timezone \ 106 | && echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USERNAME \ 107 | && update-ca-certificates \ 108 | && useradd $USERNAME -u $PUID -U -m -d /home/$USERNAME -s /usr/bin/zsh \ 109 | && apt-get clean -y \ 110 | && rm -rf \ 111 | /tmp/* \ 112 | /var/lib/apt/lists/* \ 113 | /var/tmp/* 114 | COPY entrypoint.sh /usr/bin/entrypoint.sh 115 | USER $USERNAME 116 | WORKDIR /home/$USERNAME 117 | ENTRYPOINT ["/usr/bin/entrypoint.sh"] 118 | -------------------------------------------------------------------------------- /opbuilder/README.md: -------------------------------------------------------------------------------- 1 | 用来编译 openwrt / lede 的容器,容器中已含有全部编译的依赖项,创建的配置如下: 2 | 3 | ```yaml 4 | version: "3.8" 5 | services: 6 | opbuilder: 7 | image: nevinee/opbuilder 8 | container_name: opbuilder 9 | restart: unless-stopped 10 | network_mode: host 11 | hostname: opbuilder 12 | volumes: 13 | - .:/home/evine 14 | init: true 15 | environment: 16 | PUID: 1000 # 默认1000,如果需要使用其他uid的用户来编译,请修改为对应用户的uid 17 | PGID: 1000 # 默认1000,如果需要使用其他gid的用户来编译,请修改为对应用户的gid 18 | ENABLE_CHOWN: true # 默认false,不重新设置文件所有者,如遇文件权限问题,请设置为true,将在创建后重新设置映射文件夹的权限 19 | ``` 20 | 21 | 也可以按需修改下列命令中`$(pwd)` `PUID` `PGID` `ENABLE_CHOWN`来创建: 22 | 23 | ```shell 24 | docker run -d \ 25 | --volume $(pwd):/home/evine \ 26 | --env PUID=1000 `# 默认1000,如果需要使用其他uid的用户来编译,请修改为对应用户的uid` \ 27 | --env PGID=1000 `# 默认1000,如果需要使用其他gid的用户来编译,请修改为对应用户的gid` \ 28 | --env ENABLE_CHOWN=true `# 默认false,不重新设置文件所有者,如遇文件权限问题,请设置为true,将在创建后重新设置映射文件夹的权限` \ 29 | --restart unless-stopped \ 30 | --hostname opbuilder \ 31 | --name opbuilder \ 32 | --init \ 33 | nevinee/opbuilder 34 | ``` 35 | 36 | 已安装zsh,以`docker exec -it opbuilder zsh`进入容器后即可编译openwrt。**注:在容器内可以免密执行sudo命令。** 37 | 38 | 如果不想输入上面这么长的命令,可以在宿主机上这样操作(如果使用的是zsh可以把`.bashrc`换成`.zshrc`),然后你就可以直接输入`dto`就进入容器了: 39 | 40 | ```shell 41 | echo "alias dto='docker exec -it opbuilder zsh'" >> ~/.bashrc 42 | source ~/.bashrc 43 | ``` 44 | 45 | 建议首次创建时,进入容器后运行一次以下命令以安装`oh-my-zsh`: 46 | 47 | ```shell 48 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 49 | cd ~/.oh-my-zsh/custom/plugins 50 | git clone --depth 1 https://github.com/zsh-users/zsh-autosuggestions.git 51 | git clone --depth 1 https://github.com/zsh-users/zsh-syntax-highlighting.git 52 | ``` 53 | 54 | 提供一个容器内的`/home/evine/.zshrc`文件作参考: 55 | 56 | ```shell 57 | export ZSH="$HOME/.oh-my-zsh" 58 | ZSH_THEME="agnoster" 59 | plugins=(git extract sudo z zsh-autosuggestions zsh-syntax-highlighting zsh-interactive-cd) # z也可以用autojump代替 60 | source $ZSH/oh-my-zsh.sh 61 | ``` 62 | 63 | `.zshrc`中和plugin如何使用请见:https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins 64 | 65 | 本容器亦支持运行一次编译脚本后直接删除容器,创建时只要增加command即可: 66 | 67 | ```shell 68 | docker run -d \ 69 | --rm \ 70 | --volume $(pwd):/home/evine \ 71 | --env PUID=1000 `# 默认1000,如果保持默认可以不要本行` \ 72 | --env PGID=1000 `# 默认1000,如果保持默认可以不要本行` \ 73 | --env ENABLE_CHOWN=true `# 默认false,不重新设置文件所有者,如果保持默认可以不要本行` \ 74 | nevinee/opbuilder \ 75 | bash /home/evine/your_script.sh #只要带上command即可,运行完你的脚本后会直接删除容器 76 | ``` 77 | 78 | Dockerfile见:https://github.com/devome/dockerfiles/tree/master/opbuilder 79 | -------------------------------------------------------------------------------- /opbuilder/compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | services: 3 | opbuilder: 4 | image: nevinee/opbuilder 5 | container_name: opbuilder 6 | restart: unless-stopped 7 | network_mode: host 8 | hostname: opbuilder 9 | volumes: 10 | - .:/home/evine 11 | init: true 12 | environment: 13 | PUID: 1000 # 默认1000,如果需要使用其他uid的用户来编译,请修改为对应用户的uid 14 | PGID: 1000 # 默认1000,如果需要使用其他gid的用户来编译,请修改为对应用户的gid 15 | ENABLE_CHOWN: false # 默认false,不重新设置文件所有者,如遇文件权限问题,请设置为true,将在创建后重新设置映射文件夹的权限 -------------------------------------------------------------------------------- /opbuilder/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | cmd="$@" 4 | 5 | sudo update-ca-certificates 6 | 7 | sudo groupmod -o -g "${PGID}" $USERNAME 8 | sudo usermod -o -u "${PUID}" $USERNAME 9 | 10 | if [[ $ENABLE_CHOWN == true ]]; then 11 | sudo chown -R "${PGID}:${PUID}" /home/$USERNAME 12 | fi 13 | 14 | if [[ -z $cmd ]]; then 15 | exec tail -f /dev/null 16 | else 17 | eval "$cmd" 18 | exit 0 19 | fi 20 | -------------------------------------------------------------------------------- /pagermaid/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | ARG S6_VERSION=v2.2.0.3 3 | ARG S6_ARCH=amd64 4 | ARG DEBIAN_FRONTEND=noninteractive 5 | ARG USER_NAME=pagermaid 6 | ARG WORK_DIR=/pagermaid/workdir 7 | ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ 8 | SHELL=/bin/bash \ 9 | LANG=zh_CN.UTF-8 \ 10 | PS1="\u@\h:\w \$ " \ 11 | RUN_AS_ROOT=true 12 | SHELL ["/bin/bash", "-c"] 13 | WORKDIR $WORK_DIR 14 | RUN source ~/.bashrc \ 15 | ## 安装运行环境依赖,自编译建议修改为国内镜像源 16 | && sed -i 's/archive.ubuntu.com/mirrors.bfsu.edu.cn/g' /etc/apt/sources.list \ 17 | && sed -i 's/security.ubuntu.com/mirrors.bfsu.edu.cn/g' /etc/apt/sources.list \ 18 | && sed -i 's/ports.ubuntu.com/mirrors.bfsu.edu.cn/g' /etc/apt/sources.list \ 19 | && apt-get update \ 20 | && apt-get upgrade -y \ 21 | && apt-get install --no-install-recommends -y \ 22 | python3 \ 23 | python3-pip \ 24 | tesseract-ocr \ 25 | tesseract-ocr-eng \ 26 | tesseract-ocr-chi-sim \ 27 | language-pack-zh-hans \ 28 | sudo \ 29 | git \ 30 | openssl \ 31 | redis-server \ 32 | curl \ 33 | wget \ 34 | neofetch \ 35 | imagemagick \ 36 | ffmpeg \ 37 | fortune-mod \ 38 | figlet \ 39 | libmagic1 \ 40 | libzbar0 \ 41 | iputils-ping \ 42 | ## 安装s6 43 | && curl -L -o /tmp/s6-overlay-installer https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/s6-overlay-${S6_ARCH}-installer \ 44 | && chmod +x /tmp/s6-overlay-installer \ 45 | && /tmp/s6-overlay-installer / \ 46 | ## 安装编译依赖 47 | && apt-get update \ 48 | && apt-get install --no-install-recommends -y \ 49 | ## 这是跨平台交叉编译要用到的包,如果自行构建,有可能不需要 50 | build-essential \ 51 | apt-utils \ 52 | python3-dev \ 53 | libxslt1-dev \ 54 | libxml2-dev \ 55 | libssl-dev \ 56 | libffi-dev \ 57 | zlib1g-dev \ 58 | tcl8.6-dev \ 59 | tk8.6-dev \ 60 | libimagequant-dev \ 61 | libraqm-dev \ 62 | libjpeg-dev \ 63 | libtiff5-dev \ 64 | libopenjp2-7-dev \ 65 | libfreetype6-dev \ 66 | liblcms2-dev \ 67 | libwebp-dev \ 68 | python3-tk \ 69 | libharfbuzz-dev \ 70 | libfribidi-dev \ 71 | libxcb1-dev \ 72 | pkg-config \ 73 | ## 设置时区 74 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 75 | && echo "Asia/Shanghai" > /etc/timezone \ 76 | ## python软链接 77 | && ln -sf /usr/bin/python3 /usr/bin/python \ 78 | ## 升级pip 79 | && pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \ 80 | && python -m pip install --upgrade pip \ 81 | ## 添加用户 82 | && useradd $USER_NAME -u 917 -U -r -m -d /$USER_NAME -s /bin/bash \ 83 | && usermod -aG sudo,users $USER_NAME \ 84 | && echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/$USER_NAME \ 85 | ## 克隆仓库 86 | && git clone -b master https://github.com/Xtao-Labs/PagerMaid-Modify.git $WORK_DIR \ 87 | && git config --global pull.ff only \ 88 | ## 复制s6启动脚本 89 | && cp -r s6/* / \ 90 | ## pip install 91 | && pip install -r requirements.txt \ 92 | ## 卸载编译依赖 93 | && sudo apt-get purge --auto-remove -y \ 94 | build-essential \ 95 | apt-utils \ 96 | python3-dev \ 97 | libxslt1-dev \ 98 | libxml2-dev \ 99 | libssl-dev \ 100 | libffi-dev \ 101 | zlib1g-dev \ 102 | tcl8.6-dev \ 103 | tk8.6-dev \ 104 | libimagequant-dev \ 105 | libraqm-dev \ 106 | libjpeg-dev \ 107 | libtiff5-dev \ 108 | libopenjp2-7-dev \ 109 | libfreetype6-dev \ 110 | liblcms2-dev \ 111 | libwebp-dev \ 112 | python3-tk \ 113 | libharfbuzz-dev \ 114 | libfribidi-dev \ 115 | libxcb1-dev \ 116 | pkg-config \ 117 | && apt-get clean -y \ 118 | && rm -rf \ 119 | ## 删除apt和pip的安装缓存 120 | /tmp/* \ 121 | /var/lib/apt/lists/* \ 122 | /var/tmp/* \ 123 | ~/.cache 124 | ENTRYPOINT ["/init"] 125 | -------------------------------------------------------------------------------- /python/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !s6-overlay* 3 | !Dockerfile* -------------------------------------------------------------------------------- /python/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nevinee/alpine-s6 2 | LABEL maintainer="Evine Deng " 3 | ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ 4 | HOME=/root \ 5 | LANG=zh_CN.UTF-8 \ 6 | SHELL=/bin/bash \ 7 | PS1="\u@\h:\w \$ " 8 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ 9 | && apk update -f \ 10 | && apk --no-cache add -f \ 11 | python3-dev \ 12 | py3-pip \ 13 | bash \ 14 | openssl \ 15 | coreutils \ 16 | moreutils \ 17 | git \ 18 | wget \ 19 | curl \ 20 | nano \ 21 | tzdata \ 22 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 23 | && echo "Asia/Shanghai" > /etc/timezone \ 24 | && ln -s /usr/bin/python3 /usr/bin/python \ 25 | && python -m pip install --upgrade pip \ 26 | && rm -rf \ 27 | /tmp/* \ 28 | /root/.cache 29 | COPY --from=nevinee/loop:latest / / 30 | COPY s6-overlay / 31 | WORKDIR /root 32 | ENTRYPOINT ["/init"] -------------------------------------------------------------------------------- /python/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/python" 4 | arch="linux/amd64,linux/arm64,linux/arm/v7" 5 | 6 | buildx() { 7 | docker pull tonistiigi/binfmt 8 | docker run --privileged --rm tonistiigi/binfmt --install all 9 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 10 | docker buildx inspect --bootstrap 11 | docker buildx build \ 12 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 13 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 14 | --platform "$arch" \ 15 | --tag ${repo}:latest \ 16 | --push \ 17 | . 18 | docker pushrm $repo # https://github.com/christian-korneck/docker-pushrm 19 | } 20 | 21 | [[ ! -d logs ]] && mkdir logs 22 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 23 | -------------------------------------------------------------------------------- /python/readme.md: -------------------------------------------------------------------------------- 1 | 基于python官方版本docker集成了`bash openssl coreutils moreutils git wget curl nano tzdata perl`,默认时区`Asia/Shanghai`。 2 | 3 | 创建: 4 | 5 | ```shell 6 | docker run -dit \ 7 | -v /宿主机上的目录/:/root \ 8 | --name python \ 9 | --hostname python \ 10 | nevinee/python 11 | ``` 12 | 13 | 然后进入容器,你想干啥就干啥: 14 | 15 | ```shell 16 | docker exec -it python bash 17 | ``` 18 | 19 | 如果映射目录下存在`crontab.list`,将在创建后以它作为容器的定时任务。修改`crontab.list`两秒后会自动更新容器的cron。 20 | 21 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 22 | 23 | 解决办法如下: 24 | 25 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 26 | 27 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 28 | 29 | ``` 30 | security_opt: 31 | - seccomp=unconfined 32 | ``` 33 | 34 | [![dockeri.co](http://dockeri.co/image/nevinee/python)](https://hub.docker.com/r/nevinee/python/) -------------------------------------------------------------------------------- /python/s6-overlay/etc/services.d/crond/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | exec s6-setuidgid root crond -f &>/dev/null 4 | -------------------------------------------------------------------------------- /python/s6-overlay/etc/services.d/refresh-cron/refresh-cron: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -s /root/crontab.list ] && [[ $(cat /root/crontab.list) != $(crontab -l) ]]; then 4 | echo "[services.d] 检测到/root/crontab.list有变化,立即刷新定时任务..." 5 | crontab /root/crontab.list 6 | fi -------------------------------------------------------------------------------- /python/s6-overlay/etc/services.d/refresh-cron/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | echo -e "\n[services.d] ======================== 启动定时任务自动刷新程序 ========================\n" 4 | echo -e "[services.d] 每2秒检测一次$JD_DIR/config/crontab.list是否发生变化,如发生变化则立即刷新定时任务。\n" 5 | 6 | exec s6-setuidgid root loop -e 2s -- ./refresh-cron 7 | -------------------------------------------------------------------------------- /qbittorrent/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !root* 3 | !Dockerfile* -------------------------------------------------------------------------------- /qbittorrent/.gitignore: -------------------------------------------------------------------------------- 1 | *version* -------------------------------------------------------------------------------- /qbittorrent/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG LIBTORRENT_VERSION=2 2 | FROM nevinee/libtorrent-rasterbar:${LIBTORRENT_VERSION} AS builder 3 | RUN apk upgrade \ 4 | && apk add --no-cache \ 5 | boost-dev \ 6 | openssl-dev \ 7 | qt6-qtbase-dev \ 8 | qt6-qttools-dev \ 9 | g++ \ 10 | cmake \ 11 | curl \ 12 | tar \ 13 | samurai \ 14 | && rm -rf /tmp/* /var/cache/apk/* 15 | ARG QBITTORRENT_VERSION 16 | ARG NPROC=1 17 | RUN mkdir -p /tmp/qbittorrent \ 18 | && cd /tmp/qbittorrent \ 19 | && curl -sSL https://github.com/qbittorrent/qBittorrent/archive/refs/tags/release-${QBITTORRENT_VERSION}.tar.gz | tar xz --strip-components 1 \ 20 | && cmake \ 21 | -DCMAKE_BUILD_TYPE=Release \ 22 | -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \ 23 | -DCMAKE_CXX_STANDARD=20 \ 24 | -DWEBUI=ON \ 25 | -DVERBOSE_CONFIGURE=OFF \ 26 | -DSTACKTRACE=OFF \ 27 | -DDBUS=OFF \ 28 | -DGUI=OFF \ 29 | -DQT6=ON \ 30 | -Brelease \ 31 | -GNinja \ 32 | && cmake --build release -j $NPROC \ 33 | && cmake --install release \ 34 | && ls -al /usr/local/bin/ \ 35 | && qbittorrent-nox --help 36 | RUN echo "Copy to /out" \ 37 | && strip /usr/local/lib/libtorrent-rasterbar.so.* \ 38 | && strip /usr/local/bin/qbittorrent-nox \ 39 | && mkdir -p /out/usr/lib /out/usr/bin \ 40 | && cp -d /usr/local/lib/libtorrent-rasterbar.so* /out/usr/lib \ 41 | && cp /usr/local/bin/qbittorrent-nox /out/usr/bin 42 | 43 | FROM alpine:latest AS app 44 | ENV QBT_PROFILE=/home/qbittorrent \ 45 | TZ=Asia/Shanghai \ 46 | PUID=1000 \ 47 | PGID=100 \ 48 | WEBUI_PORT=8080 \ 49 | BT_PORT=34567 \ 50 | QB_USERNAME=admin \ 51 | QB_PASSWORD=adminadmin \ 52 | LANG=zh_CN.UTF-8 \ 53 | SHELL=/bin/bash \ 54 | PS1="\u@\h:\w \$ " 55 | RUN apk upgrade \ 56 | && apk add --no-cache \ 57 | bash \ 58 | busybox-suid \ 59 | curl \ 60 | jq \ 61 | openssl \ 62 | python3 \ 63 | qt6-qtbase \ 64 | qt6-qtbase-sqlite \ 65 | shadow \ 66 | su-exec \ 67 | tini \ 68 | tzdata \ 69 | && rm -rf /tmp/* /var/cache/apk/* \ 70 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 71 | && echo "${TZ}" > /etc/timezone \ 72 | && useradd qbittorrent -u ${PUID} -U -m -d ${QBT_PROFILE} -s /sbin/nologin \ 73 | && sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/g' /etc/apk/repositories 74 | COPY --from=builder /out / 75 | COPY root / 76 | WORKDIR /data 77 | VOLUME ["/data"] 78 | ENTRYPOINT ["tini", "-g", "--", "entrypoint.sh"] 79 | -------------------------------------------------------------------------------- /qbittorrent/Dockerfile.4.3.9: -------------------------------------------------------------------------------- 1 | ARG LIBTORRENT_VERSION=1 2 | FROM nevinee/libtorrent-rasterbar:${LIBTORRENT_VERSION} AS builder 3 | RUN apk upgrade \ 4 | && apk add --no-cache \ 5 | boost-dev \ 6 | openssl-dev \ 7 | qt5-qtbase-dev \ 8 | qt5-qttools-dev \ 9 | g++ \ 10 | cmake \ 11 | curl \ 12 | tar \ 13 | samurai \ 14 | && rm -rf /tmp/* /var/cache/apk/* 15 | ARG QBITTORRENT_VERSION 16 | RUN mkdir -p /tmp/qbittorrent \ 17 | && cd /tmp/qbittorrent \ 18 | && curl -sSL https://github.com/qbittorrent/qBittorrent/archive/refs/tags/release-${QBITTORRENT_VERSION}.tar.gz | tar xz --strip-components 1 \ 19 | && cmake \ 20 | -DCMAKE_BUILD_TYPE=Release \ 21 | -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \ 22 | -DCMAKE_CXX_STANDARD=17 \ 23 | -DWEBUI=ON \ 24 | -DVERBOSE_CONFIGURE=OFF \ 25 | -DSTACKTRACE=OFF \ 26 | -DDBUS=OFF \ 27 | -DGUI=OFF \ 28 | -DQT6=OFF \ 29 | -Brelease \ 30 | -GNinja \ 31 | && cmake --build release -j $(nproc) \ 32 | && cmake --install release \ 33 | && ls -al /usr/local/bin/ \ 34 | && qbittorrent-nox --help 35 | RUN echo "Copy to /out" \ 36 | && strip /usr/local/lib/libtorrent-rasterbar.so.* \ 37 | && strip /usr/local/bin/qbittorrent-nox \ 38 | && mkdir -p /out/usr/lib /out/usr/bin \ 39 | && cp -d /usr/local/lib/libtorrent-rasterbar.so* /out/usr/lib \ 40 | && cp /usr/local/bin/qbittorrent-nox /out/usr/bin 41 | 42 | FROM alpine:latest AS app 43 | ENV QBT_PROFILE=/home/qbittorrent \ 44 | TZ=Asia/Shanghai \ 45 | PUID=1000 \ 46 | PGID=100 \ 47 | WEBUI_PORT=8080 \ 48 | BT_PORT=34567 \ 49 | QB_USERNAME=admin \ 50 | QB_PASSWORD=adminadmin \ 51 | LANG=zh_CN.UTF-8 \ 52 | SHELL=/bin/bash \ 53 | PS1="\u@\h:\w \$ " 54 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/g' /etc/apk/repositories \ 55 | && apk add --no-cache \ 56 | bash \ 57 | busybox-suid \ 58 | curl \ 59 | jq \ 60 | openssl \ 61 | python3 \ 62 | qt5-qtbase \ 63 | shadow \ 64 | su-exec \ 65 | tini \ 66 | tzdata \ 67 | && rm -rf /tmp/* /var/cache/apk/* \ 68 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 69 | && echo "${TZ}" > /etc/timezone \ 70 | && useradd qbittorrent -u ${PUID} -U -m -d ${QBT_PROFILE} -s /sbin/nologin 71 | COPY --from=builder /out / 72 | COPY root / 73 | WORKDIR /data 74 | VOLUME ["/data"] 75 | ENTRYPOINT ["tini", "-g", "--", "entrypoint.sh"] 76 | -------------------------------------------------------------------------------- /qbittorrent/Dockerfile.edge: -------------------------------------------------------------------------------- 1 | FROM alpine:edge 2 | ENV QBT_PROFILE=/var/lib/qbittorrent \ 3 | TZ=Asia/Shanghai \ 4 | PUID=1000 \ 5 | PGID=100 \ 6 | WEBUI_PORT=8080 \ 7 | BT_PORT=34567 \ 8 | QB_USERNAME=admin \ 9 | QB_PASSWORD=adminadmin \ 10 | LANG=zh_CN.UTF-8 \ 11 | SHELL=/bin/bash \ 12 | PS1="\u@\h:\w \$ " 13 | RUN apk add --no-cache \ 14 | bash \ 15 | busybox-suid \ 16 | curl \ 17 | jq \ 18 | openssl \ 19 | python3 \ 20 | qbittorrent-nox \ 21 | qt6-qtbase-sqlite \ 22 | shadow \ 23 | su-exec \ 24 | tini \ 25 | tzdata \ 26 | && rm -rf /tmp/* /var/cache/apk/* \ 27 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 28 | && echo "${TZ}" > /etc/timezone \ 29 | && sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/g' /etc/apk/repositories 30 | COPY root / 31 | WORKDIR /data 32 | VOLUME ["/data"] 33 | ENTRYPOINT ["tini", "-g", "--", "entrypoint.sh"] 34 | -------------------------------------------------------------------------------- /qbittorrent/diy/diy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## 使用本脚本有两种方式: 4 | 5 | ## 方式一:先向jellyfin/emby触发刮削操作,并在资源同目录下写入nfo(jellyfin/emby必须在刮削之前将媒体库设置中“媒体资料储存方式”勾选“nfo”),然后再向chinesesubfinder触发字幕下载。 6 | ## 如果种子中本来存在同名nfo,直接采用方式一会被破坏导致无法做种,如不想被覆盖,可在在运行下面的内容之前,先用其他命令行工具自动建立硬连接到其他文件夹,让jellyfin/emby、chinesesubfinder都只处理硬连接后的文件夹,或者直接采用方式二。 7 | ## 注意:如果硬连接了,硬连接后的视频文件名和它所在的文件夹名,须和原始文件名/文件夹名结构保持一致,如果不一致,无法使用本脚本。 8 | ## 注意:所有变量必须都赋值。 9 | 10 | ## 方式二:直接向chinesesubfinder触发字幕下载,但在同目录下缺少影视信息nfo的前提下,可能下载的字幕会不准确。 11 | ## chinesesubfinder不太建议采用这种方式,详见:https://github.com/allanpk716/ChineseSubFinder/blob/docs/DesignFile/ApiKey%E8%AE%BE%E8%AE%A1/ApiKey%E8%AE%BE%E8%AE%A1.md#%E6%96%B0%E5%A2%9E%E4%B8%80%E4%B8%AA%E4%BB%BB%E5%8A%A1 12 | ## 如采用方式二,这三个变量请不要赋值:media_server_url、media_server_token、delay。 13 | 14 | ## jellyfin/emby的访问地址,如果是在同一个容器网络,可以是172.x.x.x或主机名,主机名需要自行在创建容器时设置 15 | ## 示例1(HTTP+IP):media_server_url="http://10.0.0.18:8096" 16 | ## 示例2(HTTPS+IP):media_server_url="https://10.0.0.18:8920" 17 | ## 示例3(HTTP+域名):media_server_url="http://nas.example.com:8096" 18 | ## 示例4(HTTPS+域名):media_server_url="https://nas.example.com:8920" 19 | ## 示例5(HTTP+主机名):media_server_url="http://jellyfin:8096" 20 | ## 示例6(HTTPS+主机名):media_server_url="https://jellyfin:8920" 21 | ## 采用方式二时不要赋值 22 | media_server_url="" 23 | 24 | ## 从jellyfin/emby控制台处获取的api密钥; 25 | ## 采用方式二时不要赋值。 26 | media_server_token="" 27 | 28 | ## 向jellyfin/emby触发刮削操作和向chinesesubfinder触发字幕下载之间的间隔,采用方式一时有效; 29 | ## 由于每个人的资源库大小不一,从向jellyfin/emby触发刮削操作到jellyfin/emby完成刮削时间不一样,因此建议用户自行观察一下,触发刮削后媒体库需要花多少时间刮削完,其确保已经写入nfo; 30 | ## 采用方式二时不要赋值; 31 | ## 单位:秒。 32 | delay="30" 33 | 34 | ## chinesesubfinder的访问地址,形式同上面的media_server_url 35 | csf_url="" 36 | 37 | ## 从chinesesubfinder webui中获取的apikey,从v0.26.0起才有,老版本没有 38 | csf_token="" 39 | 40 | ## 需要排除的关键字,不区分大小写,如果视频文件名中含有所设置的关键字,则该文件不会向chinesesubfidner提交字幕下载,多个关键字之间使用"|"分隔 41 | ignore_keyword="sample|bonus|trailer" 42 | 43 | ## chinesesubfinder中设置的允许下载字幕的视频后缀,默认是mp4 mkv rmvb iso,如有修改,请同步调整下面的数组。 44 | video_exts=( mp4 mkv rmvb iso ) 45 | 46 | ## qbittorrent的下载目录和chinesesubfidner媒体目录的对应关系数组; 47 | ## 资源保存目录不在这个对应关系清单中的,就不会触发chinesesubfinder; 48 | ## 一行一个对应关系,用半角冒号(:)分隔,每一个对应关系使用双引号引起来,目录允许含有空格(但不建议); 49 | ## 第一个冒号前是该目录的类型,0代表电影,1代表电视剧,详见:https://github.com/allanpk716/ChineseSubFinder/blob/docs/DesignFile/ApiKey%E8%AE%BE%E8%AE%A1/ApiKey%E8%AE%BE%E8%AE%A1.md 50 | ## 第二个冒号前的是qbittorrent的目录,第二个冒号后的是chinesesubfinder的目录,一一对应; 51 | ## 如果有硬连接,第二个冒号前应该是硬连接前qbittorrent下载保存的路径,第二个冒号后应该是硬连接后chinesesubfinder可识别的路径; 52 | ## 如 qb2csf_dir_match=( 53 | ## "0:/movies1:/media/movies" 54 | ## "0:/movies2:/media/movies" 55 | ## "1:/tv:/media/tv" 56 | ## ) 57 | qb2csf_dir_match=( 58 | "" 59 | ) 60 | 61 | ## 如果刚刚下载的视频中存在中文字幕,是否将chinesusubfinder中对应的任务设置为忽略,即取消字幕下载,如需要取消,请设置为true。 62 | ## 需要qbittorrent的所处的环境中含有mediainfo,如使用 nevinee/qbittorrent 镜像只需要将环境变量 EXTRA_PACKAGES 中增加一个 mediainfo 即可,其他环境请自行处理。 63 | cancel_has_subtitle=false 64 | 65 | 66 | ########################## 以上为配置部分,以下为运行部分 ########################## 67 | 68 | 69 | ## 如果资源保存目录不在qb2csf_dir_match填写的目录对应关系清单中的,直接退出 70 | hash="$1" 71 | [[ -z $api_url_base ]] && api_url_base="${qb_url}/api/v2" 72 | content_path=$(curl -sSk "${api_url_base}/torrents/info?hashes=${hash}" | jq -r .[0].content_path) 73 | is_match=no 74 | for ((j=0; j<${#qb2csf_dir_match[*]}; j++)); do 75 | match_before=$(echo ${qb2csf_dir_match[j]} | awk -F ':' '{print $2}') 76 | if [[ "$content_path" == "$match_before/"* ]]; then 77 | is_match=yes 78 | break 79 | fi 80 | done 81 | if [[ $is_match == no ]]; then 82 | exit 0 83 | fi 84 | 85 | ## 触发jellyfin/emby扫描资源库,输出的 http code 含义分别见: 86 | ## emby: http://swagger.emby.media/?staticview=true#/LibraryService/postLibraryRefresh 87 | ## jellyfin: https://api.jellyfin.org/#operation/RefreshLibrary 88 | ## 比如 emby 是 200 代表成功,而 jellyfin 则是 204 代表成功,如果输出 401 则是你给的 token 不对。 89 | ## 似乎/Library/Media/Updated这个api没法达到指定视频文件路径更新的效果,所以用的全量扫描Library/Refresh这个api。 90 | ## 有变化的文件不多的情况下,/Library/Refresh也能快速的扫描完成,扫描文件其实很快的,但在刮削时受制于和tmdb-api的连接性,可能会较慢,在向chinesesubfinder发起请求前,需要等待刮削完成。 91 | echo "向 media server 触发媒体库扫描指令..." 92 | if [[ -n $media_server_url && -n $media_server_token ]]; then 93 | curl -ik \ 94 | -H "Content-Type: application/json" \ 95 | -H "X-Emby-Token: ${media_server_token}" \ 96 | -X POST \ 97 | "${media_server_url}/Library/Refresh" 98 | echo "等待 $delay 秒后再向 ChineseSubFinder 发起字幕下载请求..." 99 | sleep $delay 100 | fi 101 | 102 | ## chinesesubfinder中设置的视频后缀,默认是 mp4 mkv rmvb iso 103 | if [[ ${#video_exts[*]} -eq 0 ]]; then 104 | video_exts=( mp4 mkv rmvb iso ) 105 | fi 106 | 107 | ## 寻找刚刚下载完成的资源中,所有设置的视频后缀video_exts的文件路径,转换为chinesesubfinder可识别的路径,并提交字幕下载 108 | fdtmp="-iname *.${video_exts[0]}" 109 | for ((i=1; i<${#video_exts[*]}; i++)); do fdtmp="$fdtmp -o -iname *.${video_exts[i]}"; done 110 | tmplist=$(mktemp) 111 | find "$content_path" \( $fdtmp \) > $tmplist 112 | cat $tmplist | grep -Evi "$ignore_keyword" | while read file; do 113 | for ((j=0; j<${#qb2csf_dir_match[*]}; j++)); do 114 | match_before=$(echo ${qb2csf_dir_match[j]} | awk -F ':' '{print $2}') 115 | if [[ "$file" == "$match_before/"* ]]; then 116 | video_type=$(echo ${qb2csf_dir_match[j]} | awk -F ':' '{print $1}') 117 | match_after=$(echo ${qb2csf_dir_match[j]} | awk -F ':' '{print $3}') 118 | csf_file=$(echo "$file" | sed "s|$match_before|$match_after|") 119 | csf_result=$(curl -sSk \ 120 | -H "Content-Type: application/json" \ 121 | -H "Authorization: Bearer $csf_token" \ 122 | -X POST \ 123 | -d "{\"video_type\":$video_type,\"physical_video_file_full_path\":\"$csf_file\",\"task_priority_level\":3}" \ 124 | "${csf_url}/api/v1/add-job" 125 | ) 126 | csf_job_id=$(echo $csf_result | jq -r .job_id) 127 | csf_message=$(echo $csf_result | jq -r .message) 128 | echo "视频类型:${video_type},qB的文件:${file},对应CSF的文件:${csf_file},CSF任务ID:${csf_job_id},CSF任务消息:${csf_message}" 129 | 130 | ## 检测是否有中文字幕,如果有中文字幕,向csf设置ignore 131 | if [[ $cancel_has_subtitle == true ]]; then 132 | if ! type mediainfo &>/dev/null; then 133 | echo "未安装mediainfo,无法检测字幕,退出..." 134 | exit 1 135 | fi 136 | 137 | if [[ -n $(mediainfo --Output=JSON "$file" | jq '.media.track[] | select(."@type" == "Text")' | jq 'select(.Language == "zh")') ]]; then 138 | csf_result2=$(curl -sSk \ 139 | -H "Content-Type: application/json" \ 140 | -H "Authorization: Bearer $csf_token" \ 141 | -X POST \ 142 | -d "{\"id\":\"$csf_job_id\",\"job_status\":5}" \ 143 | "${csf_url}/api/v1/change-job-status" 144 | ) 145 | echo "检测到本视频含有中文字幕,取消字幕下载任务,取消结果:$(echo $csf_result2 | jq -r .message)" 146 | fi 147 | fi 148 | break 149 | fi 150 | done 151 | sleep 0.3 152 | done 153 | rm $tmplist 154 | -------------------------------------------------------------------------------- /qbittorrent/diy/readme.md: -------------------------------------------------------------------------------- 1 | ## 脚本作用 2 | 3 | 用于qBittorrent下载完成后实现以下内容: 4 | 5 | 1. 自动向EMBY/JELLYFIN触发扫描媒体库; 6 | 7 | 2. 自动向[ChineseSubFinder](https://github.com/allanpk716/ChineseSubFinder)触发为刚刚下载完成的视频下载中文字幕。 8 | 9 | ## [nevinee/qbittorrent](https://hub.docker.com/r/nevinee/qbittorrent) 镜像使用本脚本的方法 10 | 11 | 下载 [diy.sh](https://raw.githubusercontent.com/devome/dockerfiles/master/qbittorrent/diy/diy.sh) 放在容器内的`/data/diy/diy.sh`,然后按照该文件注释编辑即可。 12 | 13 | 如果你本来存在`/data/diy/diy.sh`,可以将 [diy.sh](https://raw.githubusercontent.com/devome/dockerfiles/master/qbittorrent/diy/diy.sh) 内容放在你现有的`diy.sh`之后。 14 | 15 | ## 其他 qBittorrent 客户端使用本脚本的方法 16 | 17 | 1. 自行根据你qBittorrent所处的环境确保这几个命令可用:`bash curl find grep jq`; 18 | 19 | 2. 下载 [diy.sh](https://raw.githubusercontent.com/devome/dockerfiles/master/qbittorrent/diy/diy.sh),**增加可执行权限,并按照注释编辑**; 20 | 21 | 3. 在脚本配置区域增加一个变量`qb_url`,qBittorrent的本地地址,形如:`qb_url="https://127.0.0.1:8080"`,其中`127.0.0.1`不要改; 22 | 23 | 4. qBittorrent设置中勾选`对本地主机上的客户端跳过身份验证`; 24 | 25 | 5. qBittorrent设置中勾选`Torrent 完成时运行外部程序`,并填入`/<你的存放路径>/diy.sh "%I"`,如果qBittorrent版本`>=4.4.0`,并且会有`v2 torrent`,则设置为`/<你的存放路径>/diy.sh "%K"`。 26 | 27 | ## 说明 28 | 29 | 如有关对API的疑问请自行前往以下链接查阅。触发ChineseSubFinder后并不是马上就能保证下载好字幕,相关逻辑也请自行查阅ChineseSubFinder文档。 30 | 31 | 1. [ChineseSubFinder API](https://github.com/allanpk716/ChineseSubFinder/blob/docs/DesignFile/Web%E7%95%8C%E9%9D%A2%E8%AE%BE%E8%AE%A1/api%20%E6%8E%A5%E5%8F%A3%E8%AE%BE%E8%AE%A1.md), [ChineseSubFinder APIKEY](https://github.com/allanpk716/ChineseSubFinder/blob/docs/DesignFile/ApiKey%E8%AE%BE%E8%AE%A1/ApiKey%E8%AE%BE%E8%AE%A1.md) 32 | 33 | 2. [Jellyfin API](https://api.jellyfin.org/) 34 | 35 | 3. [Emby API](http://swagger.emby.media/?staticview=true) 36 | 37 | -------------------------------------------------------------------------------- /qbittorrent/pictures/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/1.png -------------------------------------------------------------------------------- /qbittorrent/pictures/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/10.png -------------------------------------------------------------------------------- /qbittorrent/pictures/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/11.png -------------------------------------------------------------------------------- /qbittorrent/pictures/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/12.png -------------------------------------------------------------------------------- /qbittorrent/pictures/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/2.png -------------------------------------------------------------------------------- /qbittorrent/pictures/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/3.png -------------------------------------------------------------------------------- /qbittorrent/pictures/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/4.png -------------------------------------------------------------------------------- /qbittorrent/pictures/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/5.png -------------------------------------------------------------------------------- /qbittorrent/pictures/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/6.png -------------------------------------------------------------------------------- /qbittorrent/pictures/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/7.png -------------------------------------------------------------------------------- /qbittorrent/pictures/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/8.png -------------------------------------------------------------------------------- /qbittorrent/pictures/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/9.png -------------------------------------------------------------------------------- /qbittorrent/pictures/notify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devome/dockerfiles/662017382c91ff502adfd461ba74249420a842e7/qbittorrent/pictures/notify.png -------------------------------------------------------------------------------- /qbittorrent/readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | ## 因 Docker Hub 简介有字数限制,详细教程及全部说明请见 [我的博客](https://evine.win/p/docker-install-qbittorrent/) 4 | 5 | ## 说明 6 | 7 | 为保证用户安全,防止用户因使用反代并代理了127.0.0.1这种情况导致安全性降低,从2023年9月5日更新的镜像开始,创建容器需要新增设置两个环境变量:QB_USERNAME(登陆qBittorrent的用户名)和QB_PASSWORD(登陆qBittorrent的密码)。容器将在创建时使用这两个环境变量去设置(如已存在配置文件则是修改)登陆qBittorent的用户名和密码。如未设置这两个环境变量,或者保持为qBittorrent的默认值(默认用户名:admin,默认密码:adminadmin),则本容器附加的所有脚本、定时任务将无法继续使用。[详情](https://github.com/devome/dockerfiles/issues/101)。也因此镜像默认即安装好python,不再需要设置`INSTALL_PYTHON`这个环境变量。 8 | 9 | ## 声明 10 | 11 | 本镜像非魔改版、非快验版、非Enhanced增强版,qBittorrent自身的行为/功能全部未做任何改动(也不会考虑添加或修改官方客户端行为/功能的内容),全部属于官方客户端的默认行为/功能,在和PT站Tracker服务器交互时反馈的一切信息均是qBittorrent官方版反馈的信息。本镜像只是基于官方客户端附加了一些实用的脚本,脚本全部是合理合法使用qBittorrent官方API获取信息,脚本全部行为都集中在本地,与任何远端服务器无任何联系。增加的脚本全部代码在 [Github](https://github.com/devome/dockerfiles/tree/master/qbittorrent) 或 [Gitee](https://gitee.com/evine/dockerfiles/tree/master/qbittorrent) 均可查看 。绝对不会因为使用此镜像而导致账号被封。 12 | 13 | ## 特点 14 | 15 | - 自动按`tracker`分类或打标签(**可以选择关闭,可以选择采用qBittorrent中的“分类”还是“标签”**)。 16 | 17 | - 下载完成发送通知(**可以选择关闭**),可选途径:钉钉([效果图](https://gitee.com/evine/dockerfiles/raw/master/qbittorrent/pictures/notify.png)), Telegram, ServerChan, 爱语飞飞, PUSHPLUS推送加, 企业微信, Gotify;搭配RSS功能([RSS教程](https://www.jianshu.com/p/54e6137ea4e3))自动下载效果很好;下载完成后还可以补充运行你的自定义脚本。 18 | 19 | - 故障时发送通知,可选途径同上。 20 | 21 | - 按设定的cron检查tracker状态,如发现种子的tracker状态有问题,将给该种子添加`TrackerError`的标签,方便筛选;如果tracker出错数量超过设定的阈值,给设定渠道发送通知。 22 | 23 | - **一些辅助功能:批量修改tracker;检测指定文件夹下未做种的子文件夹/文件;生成做种文件清单;生成未做种文件清单;配合IYUU自动重新校验和自动恢复做种;指定设备上线时自动限速;多时段限速;分析指定目录的重复做种率(辅种率)等等。** 24 | 25 | - **如需要下载完成后自动触发EMBY/JELLYFIN扫描媒体库,触发ChineseSubFinder自动为刚刚下载完成的视频自动下载字幕,请按照 [这里](https://github.com/devome/dockerfiles/tree/master/qbittorrent/diy) 操作。** 26 | 27 | - 日志输出到docker控制台,可从portainer查看。 28 | 29 | - `python`为可选安装项,设置为`true`就自动安装。 30 | 31 | - 体积小,默认中文UI,默认东八区时区。 32 | 33 | - `iyuu`标签集成了[IYUUPlus](https://github.com/ledccn/IYUUPlus),自动设置好下载器,减少IYUUPlus设置复杂程度。 34 | 35 | ## 效果图 36 | 37 | ![iyuu-help](https://s3.bmp.ovh/imgs/2023/03/16/d81ef270f591ed4c.gif) 38 | 39 | ![change-tracker](https://s3.bmp.ovh/imgs/2023/03/16/d0164dc03fa2fcdc.gif) 40 | 41 | ![change-tracker](https://s3.bmp.ovh/imgs/2023/03/16/c68d896355a22dcf.gif) 42 | 43 | ![remove-tracker](https://s3.bmp.ovh/imgs/2023/03/16/1cad397ec970f9e3.gif) 44 | 45 | ![del-unseed-dir](https://s3.bmp.ovh/imgs/2023/03/16/620a163165b3398f.gif) 46 | 47 | ![report-seed-files](https://s3.bmp.ovh/imgs/2023/03/16/08cd619845b95053.gif) 48 | 49 | ![report-unseed-files](https://s3.bmp.ovh/imgs/2023/03/16/0d107538303e9ce2.gif) 50 | 51 | ![gen-dup](https://s3.bmp.ovh/imgs/2023/03/16/cf0b7468ef16760e.gif) 52 | 53 | ## 源代码、问题反馈、意见建议 54 | 55 | 如果镜像好用,请点亮star。如有使用上的问题,或者有其他好的功能建议,请在 [Github这里](https://github.com/devome/dockerfiles/issues) 或 [Gitee这里](https://gitee.com/evine/dockerfiles/issues) 提交。 56 | 57 | [![Docker Pulls](https://img.shields.io/docker/pulls/nevinee/qbittorrent.svg?style=for-the-badge&label=pulls&logo=docker)](https://hub.docker.com/r/nevinee/qbittorrent) [![Docker Stars](https://img.shields.io/docker/stars/nevinee/qbittorrent.svg?style=for-the-badge&label=stars&logo=docker)](https://hub.docker.com/r/nevinee/qbittorrent) [![GitHub Stars](https://img.shields.io/github/stars/devome/dockerfiles.svg?style=for-the-badge&logo=github)](https://github.com/devome/dockerfiles) 58 | 59 | ## 源代码、问题反馈、意见建议 60 | 61 | 如果镜像好用,请点亮star。全套代码见 [Github](https://github.com/devome/dockerfiles/tree/master/qbittorrent) 或 [Gitee](https://gitee.com/evine/dockerfiles/tree/master/qbittorrent)。如有使用上的问题,或者有其他好的功能建议,请直接在本文下方评论,或者在 [Github这里](https://github.com/devome/dockerfiles/issues) 或 [Gitee这里](https://gitee.com/evine/dockerfiles/issues) 提交。 62 | 63 | 提交bug必须反馈的信息,如不反馈以下信息,我就直接无视了。 64 | 65 | - 创建命令或 `docker-compose.yml` 文件,请自行对密码打码; 66 | 67 | - 使用的docker镜像的tag,以及qBittorrent的版本; 68 | 69 | - 进入容器后运行 `bash -x /usr/local/bin/<命令名>` 如 `bash -x /usr/local/bin/report-seed-files` 的输出,请自行对密码打码。 -------------------------------------------------------------------------------- /qbittorrent/root/etc/entrypoint.d/10-add-pkg.sh: -------------------------------------------------------------------------------- 1 | if [[ $EXTRA_PACKAGES ]]; then 2 | echo "Install $EXTRA_PACKAGES ..." 3 | apk add --update --no-cache $EXTRA_PACKAGES 4 | fi 5 | -------------------------------------------------------------------------------- /qbittorrent/root/etc/entrypoint.d/20-mkdir.sh: -------------------------------------------------------------------------------- 1 | echo "Make some folders..." 2 | 3 | cd /data 4 | dirs1=( cache certs config data/logs downloads diy temp torrents watch webui ${QBT_PROFILE}/qBittorrent ) 5 | for dir in ${dirs1[@]}; do 6 | [ ! -d $dir ] && mkdir -p $dir 7 | done 8 | 9 | dirs2=( cache config data ) 10 | for dir in ${dirs2[@]}; do 11 | if [[ $(readlink -f ${QBT_PROFILE}/qBittorrent/$dir 2>/dev/null) != /data/$dir ]]; then 12 | rm -rf ${QBT_PROFILE}/qBittorrent/$dir 13 | ln -sf /data/$dir ${QBT_PROFILE}/qBittorrent/$dir 14 | fi 15 | done 16 | 17 | if [[ $(readlink -f /data/logs 2>/dev/null) != /data/data/logs ]]; then 18 | rm -rf /data/logs 19 | ln -sf data/logs logs 20 | fi 21 | -------------------------------------------------------------------------------- /qbittorrent/root/etc/entrypoint.d/30-config.sh: -------------------------------------------------------------------------------- 1 | QB_CONF_FILE="/data/config/qBittorrent.conf" 2 | QB_PASSWD_HASH=$(gen-qb-passwd "$QB_PASSWORD") 3 | BT_PORT=${BT_PORT:-34567} 4 | WEBUI_PORT=${WEBUI_PORT:-8080} 5 | 6 | if [ ! -s $QB_CONF_FILE ]; then 7 | echo "Initializing qBittorrent configuration..." 8 | cat > $QB_CONF_FILE << EOF 9 | [AutoRun] 10 | enabled=true 11 | program=dl-finish \"%K\" 12 | 13 | [BitTorrent] 14 | Session\DefaultSavePath=/data/downloads 15 | Session\Port=${BT_PORT} 16 | Session\TempPath=/data/temp 17 | 18 | [LegalNotice] 19 | Accepted=true 20 | 21 | [Preferences] 22 | General\Locale=zh_CN 23 | WebUI\Password_PBKDF2=\"@ByteArray($QB_PASSWD_HASH)\" 24 | WebUI\Port=${WEBUI_PORT} 25 | WebUI\Username=${QB_USERNAME} 26 | EOF 27 | fi 28 | 29 | echo "Overriding required parameters..." 30 | sed -i "{ 31 | s!Session\\\Port=.*!Session\\\Port=${BT_PORT}!g; 32 | s!WebUI\\\Port=.*!WebUI\\\Port=${WEBUI_PORT}!g; 33 | s!WebUI\\\LocalHostAuth=.*!WebUI\\\LocalHostAuth=true!g; 34 | }" $QB_CONF_FILE 35 | 36 | if [[ ${QB_USERNAME} == admin && $QB_PASSWORD == adminadmin ]]; then 37 | echo "Please set env QB_USERNAME and QB_PASSWORD to your own, do not set 'QB_USERNAME=admin' and 'QB_PASSWORD=adminadmin' ..." 38 | notify "nevinee/qbittorrent镜像重要更新说明" "为保证用户安全,防止用户因使用反代并代理了127.0.0.1这种情况导致安全性降低,从2023年9月6日更新的镜像开始,创建容器需要新增设置两个环境变量:\n\nQB_USERNAME(登陆qBittorrent的用户名)\nQB_PASSWORD(登陆qBittorrent的密码)\n\n容器将在创建时使用这两个环境变量去设置(如已存在配置文件则是修改)登陆qBittorent的用户名和密码。\n\n如未设置这两个环境变量,或者保持为qBittorrent的默认值(默认用户名:admin,默认密码:adminadmin),则本容器附加的所有脚本、定时任务将无法继续使用。\n\n详情:https://github.com/devome/dockerfiles/issues/101 \n\n本消息只在设置了有效的通知渠道,并且未设置有效的 QB_USERNAME 和 QB_PASSWORD 这两个环境变量时,在创建容器时自动发送一次。" 39 | else 40 | sed -i "{ 41 | s!WebUI\\\Username=.*!WebUI\\\Username=${QB_USERNAME}!; 42 | s!WebUI\\\Password_PBKDF2=.*!WebUI\\\Password_PBKDF2=\"@ByteArray($QB_PASSWD_HASH)\"!; 43 | }" $QB_CONF_FILE 44 | fi 45 | 46 | major_ver=$(qbittorrent-nox --version | sed 's|qBittorrent v||' | awk -F. '{print $1}') 47 | minor_ver=$(qbittorrent-nox --version | sed 's|qBittorrent v||' | awk -F. '{print $2}') 48 | 49 | if [[ $major_ver -eq 4 && $minor_ver -lt 5 ]]; then 50 | sed -i -E 's|General\\Locale=.+|General\\Locale=zh|' $QB_CONF_FILE 51 | sed -i -E 's|program=dl-finish \\"%K\\"|program=dl-finish \\"%I\\"|' $QB_CONF_FILE 52 | else 53 | sed -i -E 's|General\\Locale=.+|General\\Locale=zh_CN|' $QB_CONF_FILE 54 | fi 55 | -------------------------------------------------------------------------------- /qbittorrent/root/etc/entrypoint.d/40-fix-user.sh: -------------------------------------------------------------------------------- 1 | PUID=${PUID:-1000} 2 | PGID=${PGID:-100} 3 | echo "Change owner to user 'qbittorrent' (PUID=$PUID PGID=$PGID)..." 4 | groupmod -o -g "${PGID}" qbittorrent 5 | usermod -o -u "${PUID}" qbittorrent 6 | chown -R qbittorrent:qbittorrent "${QBT_PROFILE}" /data 7 | -------------------------------------------------------------------------------- /qbittorrent/root/etc/entrypoint.d/50-crontab.sh: -------------------------------------------------------------------------------- 1 | ## 清除root的crontab 2 | crontab -r 3 | 4 | ## health-check 5 | if [[ -z ${CRON_HEALTH_CHECK} ]]; then 6 | CRON_HEALTH_CHECK="12 * * * *" 7 | elif [[ ${CRON_HEALTH_CHECK} == off ]]; then 8 | CRON_HEALTH_CHECK="" 9 | fi 10 | if [[ -n "${CRON_HEALTH_CHECK}" ]]; then 11 | echo -e "# qbittorrent客户端健康检查\n${CRON_HEALTH_CHECK} health-check >> /data/diy/crond.log\n" > /tmp/crontab.list 12 | fi 13 | 14 | ## tracker-error 15 | if [[ -z ${CRON_TRACKER_ERROR} ]]; then 16 | CRON_TRACKER_ERROR="52 */4 * * *" 17 | elif [[ ${CRON_TRACKER_ERROR} == off ]]; then 18 | CRON_TRACKER_ERROR="" 19 | fi 20 | if [[ -n "$CRON_TRACKER_ERROR" ]]; then 21 | echo -e "# Tracker出错检查\n${CRON_TRACKER_ERROR} tracker-error >> /data/diy/crond.log\n" >> /tmp/crontab.list 22 | fi 23 | 24 | ## auto-cat 25 | if [[ $ENABLE_AUTO_CATEGORY != false ]]; then 26 | if [[ -z ${CRON_AUTO_CATEGORY} ]]; then 27 | CRON_AUTO_CATEGORY="32 */2 * * *" 28 | fi 29 | echo -e "# 自动分类\n${CRON_AUTO_CATEGORY} auto-cat -a >> /data/diy/crond.log\n" >> /tmp/crontab.list 30 | fi 31 | 32 | ## iyuu-help 33 | if [[ -n "${CRON_IYUU_HELP}" ]]; then 34 | echo -e "# IYUU辅助任务,自动重校验、自动恢复做种\n${CRON_IYUU_HELP} iyuu-help >> /data/diy/crond.log\n" >> /tmp/crontab.list 35 | fi 36 | 37 | ## detect-ip 38 | if [[ -n "${MONITOR_IP}" ]]; then 39 | echo -e "# 每分钟检测局域网指定设备是否在线,若在线则启用备用速度限制\n* * * * * detect-ip &>/dev/null\n" >> /tmp/crontab.list 40 | fi 41 | 42 | ## alter-limits,启用detect-ip时本项不生效 43 | if [[ -z ${MONITOR_IP} ]] && [[ ${CRON_ALTER_LIMITS} ]]; then 44 | cron_alter_limits_on_all=$(echo "${CRON_ALTER_LIMITS}" | awk -F '|' '{print $1}') 45 | cron_alter_limits_on_sum=$(echo "${cron_alter_limits_on_all}" | awk -F ':' '{print NF}') 46 | task_alter_limits_on="# 启用备用速度限制" 47 | for ((i = 1; i <= $cron_alter_limits_on_sum; i++)); do 48 | cron_on_tmp=$(echo "${cron_alter_limits_on_all}" | awk -v var=$i -F ':' '{print $var}') 49 | task_alter_limits_on="$task_alter_limits_on\\n$cron_on_tmp alter-limits on >> /data/diy/crond.log" 50 | done 51 | echo -e "$task_alter_limits_on\n" >> /tmp/crontab.list 52 | 53 | cron_alter_limits_off_all=$(echo "${CRON_ALTER_LIMITS}" | awk -F '|' '{print $2}') 54 | cron_alter_limits_off_sum=$(echo "${cron_alter_limits_off_all}" | awk -F ':' '{print NF}') 55 | task_alter_limits_off="# 关闭备用速度限制" 56 | for ((i = 1; i <= $cron_alter_limits_off_sum; i++)); do 57 | cron_off_tmp=$(echo "${cron_alter_limits_off_all}" | awk -v var=$i -F ':' '{print $var}') 58 | task_alter_limits_off="$task_alter_limits_off\\n$cron_off_tmp alter-limits off >> /data/diy/crond.log" 59 | done 60 | echo -e "$task_alter_limits_off\n" >> /tmp/crontab.list 61 | fi 62 | 63 | ## Set crontab 64 | echo "Set crontab to system..." 65 | su-exec "${PUID}:${PGID}" crontab /tmp/crontab.list 66 | rm -f /tmp/crontab.list 67 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/alter-limits: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | toggle=$1 4 | . /usr/local/bin/share 5 | 6 | current_mode=$($cmd_curl $api_url_base/transfer/speedLimitsMode) 7 | 8 | major_ver=$(qbittorrent-nox --version | sed 's|qBittorrent v||' | awk -F. '{print $1}') 9 | minor_ver=$(qbittorrent-nox --version | sed 's|qBittorrent v||' | awk -F. '{print $2}') 10 | 11 | if [[ $major_ver -eq 4 && $minor_ver -le 4 ]]; then 12 | toggle_cmd=$cmd_curl 13 | else 14 | toggle_cmd=$cmd_curl_post 15 | fi 16 | 17 | if [[ $toggle == off && $current_mode == 1 ]]; then 18 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 关闭备用速度限制..." 19 | $toggle_cmd $api_url_base/transfer/toggleSpeedLimitsMode 20 | elif [[ $toggle == on && $current_mode == 0 ]]; then 21 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 启用备用速度限制..." 22 | $toggle_cmd $api_url_base/transfer/toggleSpeedLimitsMode 23 | elif [[ $toggle == off && $current_mode == 0 ]]; then 24 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 当前已经关闭备用速度限制,无需再次关闭..." 25 | elif [[ $toggle == on && $current_mode == 1 ]]; then 26 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 当前已经启用备用速度限制,无需再次启用..." 27 | fi 28 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/auto-cat: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | base_fun() { 4 | if [[ $ENABLE_AUTO_CATEGORY == true ]]; then 5 | . /usr/local/bin/share 6 | categories_json="/data/config/categories.json" 7 | CATEGORY_OR_TAG=${CATEGORY_OR_TAG:-category} 8 | filter="" 9 | else 10 | echo "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 你已将 ENABLE_AUTO_CATEGORY 设置为 false,禁止自动分类..." 11 | exit 0 12 | fi 13 | if [[ $CATEGORY_OR_TAG != category && $CATEGORY_OR_TAG != tag ]]; then 14 | echo "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] CATEGORY_OR_TAG 赋值错误,仅能赋值 'category' 或 'tag'" 15 | exit 1 16 | fi 17 | } 18 | 19 | gen_tracker() { 20 | local torrent_hash="$1" 21 | local tracker_url=$($cmd_curl "${api_url_base}/torrents/trackers?hash=${torrent_hash}" | jq -r .[].url | grep -m1 -i "http" | awk -F "://|/" '{print $2}') 22 | local tracker=$(echo "$tracker_url" | awk -F "." '{print $((NF - 1))}') 23 | [[ $tracker == edu ]] && tracker=$(echo "$tracker_url" | awk -F "." '{print $((NF - 2))}') 24 | echo "$tracker" 25 | } 26 | 27 | category() { 28 | local torrent_hash="$1" 29 | local tracker=$(gen_tracker "$torrent_hash") 30 | local current_category=$($cmd_curl "${api_url_base}/torrents/info?hashes=${torrent_hash}" | jq -r .[].category | sed "s# #%20#g") 31 | if [[ -z $(cat $categories_json | jq -r 'keys'[] | grep -x "$tracker") ]]; then 32 | $cmd_curl_post -d "category=$tracker" "${api_url_base}/torrents/createCategory" &>/dev/null 33 | fi 34 | if [[ $current_category != $tracker ]]; then 35 | $cmd_curl_post -d "hashes=${torrent_hash}&category=${tracker}" "${api_url_base}/torrents/setCategory" 36 | fi 37 | } 38 | 39 | tag() { 40 | local torrent_hash="$1" 41 | local tracker=$(gen_tracker "$torrent_hash") 42 | $cmd_curl_post -d "hashes=${torrent_hash}&tags=${tracker}" ${api_url_base}/torrents/addTags 43 | } 44 | 45 | cat_all() { 46 | local hashes=( $($cmd_curl "${api_url_base}/torrents/info${filter}" | jq -r .[].hash) ) 47 | for hash in "${hashes[@]}"; do 48 | eval $CATEGORY_OR_TAG "$hash" 49 | done 50 | } 51 | 52 | usage() { 53 | echo "用法:" 54 | echo "auto-cat -a # 当CATEGORY_OR_TAG=category时,将所有未分类的种子按tracker分类;当CATEGORY_OR_TAG=tag时,对所有种子按tracker打标签" 55 | echo "auto-cat -A # 当CATEGORY_OR_TAG=category时,将所有种子按tracker分类;当CATEGORY_OR_TAG=tag时,对所有种子按tracker打标签" 56 | echo "auto-cat -h # 使用帮助" 57 | echo "auto-cat -i # 指定某个种子的hash,当CATEGORY_OR_TAG=category时,将其按tracker分类;当CATEGORY_OR_TAG=tag时,将其按tracker打标签" 58 | } 59 | 60 | main() { 61 | while getopts :aAhi: OPT; do 62 | case $OPT in 63 | a) 64 | base_fun 65 | [[ $CATEGORY_OR_TAG == category ]] && filter="?category=" 66 | cat_all 67 | ;; 68 | A) 69 | base_fun 70 | cat_all 71 | ;; 72 | h) 73 | usage 74 | ;; 75 | i) 76 | base_fun 77 | eval $CATEGORY_OR_TAG "$OPTARG" 78 | ;; 79 | ?) 80 | usage 81 | exit 2 82 | ;; 83 | esac 84 | done 85 | shift $((OPTIND - 1)) 86 | } 87 | 88 | main "$@" 89 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/change-tracker: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | change_tracker() { 4 | local hash=$1 5 | local orig_url=$2 6 | local new_url=$3 7 | local torrent_name=$($cmd_curl "${api_url_base}/torrents/info?hashes=${hash}" | jq -r .[0].name) 8 | 9 | echo "hash: ${hash}, torrent_name: ${torrent_name}" 10 | $cmd_curl_post $api_url_base/torrents/editTracker -d "hash=${hash}&origUrl=${orig_url}&newUrl=${new_url}" 11 | } 12 | 13 | handle_all_match_torrents() { 14 | local method=$1 15 | 16 | . /usr/local/bin/share 17 | echo -e "\n检测种子清单...\n" 18 | hashes=( $($cmd_curl ${api_url_base}/torrents/info | jq -r .[].hash) ) 19 | echo -e "开始替换...\n\n搜索过程可能较慢,请等待程序运行完成...\n\n有以下种子匹配所提供的信息,并完成替换:\n" 20 | local change_count=0 21 | for hash in ${hashes[@]}; do 22 | trackers_url=( $($cmd_curl $api_url_base/torrents/trackers?hash=$hash | jq -r .[].url | sed "s# #_#g") ) 23 | for ((n = $((${#trackers_url[*]} - 1)); n >= 0; n--)); do 24 | if [[ $method == exact && ${trackers_url[n]} == ${tracker_orig_url} ]]; then 25 | change_tracker "$hash" "${tracker_orig_url//&/%26}" "${tracker_new_url//&/%26}" 26 | let change_count++ 27 | break 28 | elif [[ $method == blur && ${trackers_url[n]} == *${orig_string}* ]]; then 29 | tracker_orig_url=${trackers_url[n]} 30 | tracker_new_url=$(echo ${trackers_url[n]} | sed "s#${orig_string}#${new_string}#") 31 | change_tracker "$hash" "${tracker_orig_url//&/%26}" "${tracker_new_url//&/%26}" 32 | let change_count++ 33 | break 34 | fi 35 | done 36 | done 37 | echo -e "\n共修改了${change_count}个种子的tracker,程序运行完成" 38 | } 39 | 40 | usage() { 41 | echo "用法1:change-tracker -m -o <原来的url或字符> -n <修改后的url或字符>" 42 | echo " 命令中直接带上参数,此用法支持由cron定时任务自动运行" 43 | echo " mode允许的值为:1或2,1指精确匹配,匹配整个tracker才进行替换;2指模糊匹配,只要tracker中含有所提供的字符,就进行替换,将tracker中这一部分字符替换为指定字符,其余字符不变" 44 | echo " 当mode为1时,-o后面为原来的完整tracker地址,-n后面为修改后的完整tracker地址;当mode为2时,-o后面为替换前tracker地址中的一段字符串,-n后面为替换后的字符串,请务必确保输入的字符串满足预期!!!" 45 | echo " 示例:change-tracker -m 1 -o http://tracker.example.com/passkey=qwertyuiopasdfghjkll -n https://tracker.example.com/passkey=asdfghjkllqwertyuiop" 46 | echo " 示例:change-tracker -m 2 -o http:// -n https://" 47 | echo 48 | echo "用法2:change-tracker" 49 | echo " 命令中不带参数,这种用法由用户随后根据提示主动输入模式选择和要修改的tracker信息" 50 | } 51 | 52 | main_1() { 53 | while getopts :m:o:n: OPT; do 54 | case $OPT in 55 | m) mode="$OPTARG";; 56 | o) stro="$OPTARG";; 57 | n) strn="$OPTARG";; 58 | ?) usage && exit 2;; 59 | esac 60 | done 61 | shift $((OPTIND - 1)) 62 | [[ -z $stro || -z $strn ]] && usage && exit 3 63 | case $mode in 64 | 1) 65 | tracker_orig_url="$stro" 66 | tracker_new_url="$strn" 67 | handle_all_match_torrents exact 68 | ;; 69 | 2) 70 | orig_string="$stro" 71 | new_string="$strn" 72 | handle_all_match_torrents blur 73 | ;; 74 | *) 75 | usage 76 | exit 4 77 | ;; 78 | esac 79 | } 80 | 81 | main_2() { 82 | echo -e "匹配模式:\n" 83 | echo -e "1. 精确匹配:匹配整个tracker才进行替换。\n" 84 | echo -e "2. 模糊匹配:只要tracker中含有所提供的字符,就进行替换,只将tracker中这一部分字符替换为指定字符,其余字符不变。\n" 85 | read -p "请选择匹配模式 [1/2]:" match_method 86 | echo 87 | case $match_method in 88 | 1) 89 | read -p "请输入要替换的tracker:" tracker_orig_url 90 | echo 91 | read -p "请输入替换后的tracker:" tracker_new_url 92 | echo 93 | echo -e "替换前:$tracker_orig_url\n" 94 | echo -e "替换后:$tracker_new_url\n" 95 | read -p "请确认信息无误 [y/N]:" choice1 96 | if [[ $choice1 == [Yy] || $choice1 == [Yy][Ee][Ss] ]]; then 97 | handle_all_match_torrents exact 98 | fi 99 | ;; 100 | 2) 101 | read -p "请输入要替换的字符串:" orig_string 102 | echo 103 | read -p "请输入替换后的字符串:" new_string 104 | echo 105 | echo -e "替换前:$orig_string\n" 106 | echo -e "替换后:$new_string\n" 107 | read -p "请确认信息无误 [y/N]:" choice2 108 | if [[ $choice2 == [Yy] || $choice2 == [Yy][Ee][Ss] ]]; then 109 | handle_all_match_torrents blur 110 | fi 111 | ;; 112 | *) 113 | echo "输入错误,退出脚本(请输入'1'或'2')" 114 | exit 1 115 | ;; 116 | esac 117 | } 118 | 119 | if [[ -n "$@" ]]; then 120 | main_1 "$@" 121 | else 122 | main_2 123 | fi 124 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/del-unseed-dir: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . /usr/local/bin/share 4 | list_detect_path=/tmp/detect_path.list 5 | list_content_path=/tmp/torrents_content_path.list 6 | 7 | [[ -f $list_detect_path ]] && rm -f $list_detect_path 8 | [[ -f $list_content_path ]] && rm -f $list_content_path 9 | 10 | ## 输入检测路径 11 | echo -e "本脚本用来检测指定文件夹下,所有子文件夹/文件是否在本qbittorrent客户端中做种或下载,如某个子文件夹/文件当前没有做种或下载,可以选择是否删除它。\n" 12 | echo -e "注意:检测只针对指定文件夹的下一级文件夹/文件,不会检测再下一级的文件夹/文件以及更底层的文件夹/文件。\n" 13 | echo -e "请输入容器内你想检测的文件夹路径,请注意是容器内的绝对路径,多个路径之间使用半角冒号分隔,路径允许使用空格(形如 /data/downloads:/movies:/tv )\n" 14 | read -p "请输入:" detect_path 15 | echo 16 | 17 | detect_path=$(echo "$detect_path" | sed 's|:|\n|g' | sort -u) 18 | while read path; do 19 | if [[ ! -d "$path" || "$path" != "/"* ]]; then 20 | echo -e "路径 '$path' 不存在,退出脚本\n" 21 | exit 1 22 | fi 23 | done <<< $(echo "$detect_path") 24 | 25 | while read path; do 26 | tmpfile=$(mktemp) 27 | find "$path" -mindepth 1 -maxdepth 1 > $tmpfile 28 | path_sum=$(cat $tmpfile | wc -l) 29 | echo -e "将要检测的路径:\"$path\",该路径下共有 $path_sum 个子文件夹/文件。\n" 30 | cat $tmpfile >> $list_detect_path 31 | rm $tmpfile 32 | sleep 1 33 | done <<< $(echo "$detect_path") 34 | 35 | ## 检出qbittorrent的content_path 36 | echo -e "开始检测qbittorrent客户端中的种子保存路径,可能比较耗时,请耐心等待...\n" 37 | sleep 1 38 | torrents_info=$($cmd_curl ${api_url_base}/torrents/info) 39 | torrents_sum=( $(echo $torrents_info | jq '.|length') ) 40 | echo "$torrents_info" | jq -r .[].content_path | sed "s|\(.*\)|\1\/|" > $list_content_path 41 | 42 | ## 确认是否删除未做种的文件夹 43 | echo -e "qbittorrent客户端中共有 $torrents_sum 个种子...\n\n开始检测指定路径下的文件夹/文件是否在qbittorrent客户端中下载或做种...\n" 44 | sleep 3 45 | while read dir; do 46 | echo "检测 \"$dir\"" 47 | if [[ -z $(grep -F "$dir/" $list_content_path 2>/dev/null) ]]; then 48 | ( 49 | echo -en "\n在本qbittorrent客户端中没有检测到保存路径包含 \"$dir\" 的种子...\n\n请确认是否删除 \"$dir\" [y/N]:" 50 | exec /dev/null 64 | echo -e "\n程序运行结束。\n" 65 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/detect-ip: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $MONITOR_IP ]]; then 4 | alter_limits_switch=off 5 | for ip in $MONITOR_IP; do 6 | if ping -c 2 $ip &>/dev/null; then 7 | alter_limits_switch=on 8 | break 9 | fi 10 | done 11 | alter-limits $alter_limits_switch 12 | else 13 | echo "未设置 MONITOR_IP 环境变量,退出" 14 | exit 1 15 | fi -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/dl-finish: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | send_notify() { 4 | local hash="$1" 5 | local torrent_info=$($cmd_curl "${api_url_base}/torrents/info?hashes=${hash}" | jq .[0]) 6 | local torrent_properties=$($cmd_curl "${api_url_base}/torrents/properties?hash=${hash}") 7 | local torrent_files=$($cmd_curl "${api_url_base}/torrents/files?hash=${hash}") 8 | 9 | local hostname=$(cat /etc/hostname) 10 | local torrent_name=$(echo "$torrent_info" | jq -r .name) 11 | local save_path=$(echo "$torrent_properties" | jq -r .save_path) 12 | local category=$(echo "$torrent_info" | jq -r .category) 13 | local size=$(echo "$torrent_info" | jq .size | xargs -I {} nice-size {}) 14 | local files_sum=$(echo $torrent_files | jq '.|length') 15 | local addition_date=$(echo "$torrent_properties" | jq .addition_date) 16 | local addition_date_format=$(date +'%Y-%m-%d %H:%M:%S' -d @$addition_date) 17 | local completion_date=$(echo "$torrent_properties" | jq .completion_date) 18 | if [[ "$completion_date" != "-1" ]]; then 19 | local completion_date_format=$(date +'%Y-%m-%d %H:%M:%S' -d @$completion_date) 20 | local download_time=$(nice-time $(($completion_date - $addition_date))) 21 | else 22 | local completion_date_format="" 23 | local download_time="" 24 | fi 25 | 26 | if [[ $torrent_name ]]; then 27 | notify \ 28 | "${hostname}种子下载$(if [[ "$completion_date" != "-1" ]]; then echo "完成"; else echo "开始"; fi)" \ 29 | "种子名称:$torrent_name\n保存路径:$save_path\n$(if [[ -n $category ]]; then echo "种子分类:$category\n"; fi)选定大小:$size\n文件数量:$files_sum\n开始时间:$addition_date_format\n$(if [[ "$completion_date" != "-1" ]]; then echo "完成时间:$completion_date_format\n下载用时:$download_time\n"; fi)" 30 | fi 31 | } 32 | 33 | torrent_hash="$1" ## hash必须是第一个传入参数 34 | if [[ $torrent_hash =~ ^[0-9a-f]+$ ]]; then 35 | . /usr/local/bin/share 36 | auto-cat -i "$torrent_hash" 37 | 38 | if [[ $DL_FINISH_NOTIFY == true ]]; then 39 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送种子下载完成的通知消息..." 40 | send_notify "$torrent_hash" 41 | else 42 | echo "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 已设置为不发送种子下载完成的通知消息..." 43 | fi 44 | 45 | if [[ -f /data/diy/diy.sh ]]; then 46 | . /data/diy/diy.sh 47 | fi 48 | else 49 | echo "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 传入参数不正确,请将HASH作为第1个传入参数,形如:dl-finish \"%K\"..." 50 | fi 51 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for file in /etc/entrypoint.d/*.sh; do 4 | . "$file" 5 | done 6 | 7 | echo "Start crond..." 8 | if [[ $(realpath /data/diy/crond.log) != /data/diy/crond.log ]]; then 9 | rm /data/diy/crond.log 10 | fi 11 | crond 12 | 13 | echo "Start qbittorrent-nox..." 14 | if [[ -n ${UMASK_SET} ]]; then 15 | umask ${UMASK_SET} 16 | fi 17 | exec su-exec "${PUID}:${PGID}" qbittorrent-nox 18 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/gen-dup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | detect_pathes="$1" 4 | 5 | usage() { 6 | echo "用途:粗略估计指定的目录的重复做种率(辅种率)" 7 | echo "用法:gen-dup \"<要分析的目录>\",多个目录间以半角冒号(:)分隔" 8 | echo "示例:gen-dup \"/movies\" 或 gen-dup \"/movies:/tv:/music:/video:/ebook\"" 9 | echo "说明:输出包含四列信息,第一列为所指定的目录,第二列为该目录的做种体积,第三列为该目录的实际占用体积,第四列为第二列占第三列的百分比" 10 | echo "注意:如果指定目录下含有太多不在qBittorrent客户端中做种的文件,将会导致第三列、第四列数值偏差较大" 11 | } 12 | 13 | if [[ -z $detect_pathes ]]; then 14 | usage 15 | exit 0 16 | fi 17 | 18 | detect_pathes=$(echo $detect_pathes | sed 's|:|\n|g' | sort -u) 19 | lenth_v=0 20 | while read path; do 21 | if [[ ! -d "$path" ]]; then 22 | echo -e "路径 '$path' 不存在\n" 23 | usage 24 | exit 1 25 | else 26 | lenth_v_tmp=${#path} 27 | if [[ $lenth_v_tmp -gt $lenth_v ]]; then 28 | lenth_v=$lenth_v_tmp 29 | fi 30 | fi 31 | done <<< $(echo "$detect_pathes") 32 | if [[ $lenth_v -lt 5 ]]; then 33 | lenth_v=5 34 | fi 35 | 36 | tmppaste1=$(mktemp) 37 | tmppaste2=$(mktemp) 38 | tmppaste3=$(mktemp) 39 | byte_torrent_total=0 40 | byte_du_total=0 41 | 42 | . /usr/local/bin/share 43 | 44 | torrents_info=$($cmd_curl ${api_url_base}/torrents/info) 45 | echo "$torrents_info" | jq -r .[].save_path | sed -e "s|^|\/|" -e "s|$|\/|" > $tmppaste1 46 | echo "$torrents_info" | jq -r .[].size > $tmppaste2 47 | paste -d ":" $tmppaste1 $tmppaste2 > $tmppaste3 48 | 49 | printf "%-${lenth_v}s %10s %10s %7s\n" PATH SZ_TORRENT SZ_LOCAL DUP_PCT 50 | while read path; do 51 | byte_torrent=$(grep -F "/${path}/" $tmppaste3 | awk -F: '{sum += $2} END {print sum}' 2>/dev/null) 52 | byte_torrent_total=$(( $byte_torrent_total + ${byte_torrent:-0} )) 53 | size_torrent=$(nice-size ${byte_torrent:-0}) 54 | byte_du=$(du -b -d 0 "$path" | awk '{print $1}') 55 | byte_du_total=$(( $byte_du_total + ${byte_du:-0} )) 56 | size_du=$(nice-size ${byte_du:-0}) 57 | [[ $byte_torrent -gt 0 && $byte_du -gt 0 ]] && perc=$(echo "scale=2; $byte_torrent * 100 / $byte_du" | bc)% || perc=0% 58 | printf "%-${lenth_v}s %10s %10s %7s\n" "$path" "$size_torrent" "$size_du" "$perc" 59 | done <<< $(echo "$detect_pathes") 60 | 61 | size_torrent_total=$(nice-size ${byte_torrent_total:-0}) 62 | size_du_total=$(nice-size ${byte_du_total:-0}) 63 | [[ $byte_torrent_total -gt 0 && $byte_du_total -gt 0 ]] && perc_total=$(echo "scale=2; $byte_torrent_total * 100 / $byte_du_total" | bc)% || perc_total=0% 64 | printf "%-${lenth_v}s %10s %10s %7s\n" "total" "$size_torrent_total" "$size_du_total" "$perc_total" 65 | 66 | rm $tmppaste1 $tmppaste2 $tmppaste3 67 | 68 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/gen-qb-passwd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ## https://github.com/swizzin/swizzin/blob/master/scripts/qbittorrent.Userpass.py 4 | 5 | import sys 6 | import hashlib 7 | import base64 8 | import uuid 9 | 10 | password = sys.argv[1] 11 | salt = uuid.uuid4() 12 | salt_bytes = salt.bytes 13 | 14 | password = str.encode(password) 15 | hashed_password = hashlib.pbkdf2_hmac('sha512', password, salt_bytes, 100000, dklen=64) 16 | b64_salt = base64.b64encode(salt_bytes).decode("utf-8") 17 | b64_password = base64.b64encode(hashed_password).decode("utf-8") 18 | password_string = "{salt}:{password}".format(salt=b64_salt,password=b64_password) 19 | print(password_string) 20 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/health-check: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . /usr/local/bin/share 4 | 5 | if ! $cmd_curl ${api_url_base}/app/version &>/dev/null; then 6 | echo "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] ${HOSTNAME} 已经宕机了,发送通知消息..." 7 | notify "${HOSTNAME}已经宕机啦" "检测到${HOSTNAME}已经宕机啦,快检查一下吧!\n发送时间:$(date +'%Y-%m-%d %H:%M:%S')" 8 | fi 9 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/iyuu-help: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## IyuuAutoReseed辅助脚本,实现以下功能: 4 | ## 1. 检查下载清单(就是qbittorrent筛选“下载”的清单),检测该清单中处于暂停状态、并且下载完成率为0%(辅种的种子在校验前也是0%)的种子,将这些种子请求重新校验。已经请求过校验并且完成率大于0%的种子不会再次校验。 5 | ## 2. 检查暂停清单(就是qbittorrent筛选“暂停”的清单),检测该清单中100%下载完成/100%校验通过的种子,将这些种子恢复做种。校验未通过不达100%完成率的种子不会启动,仍然保持暂停状态。 6 | 7 | . /usr/local/bin/share 8 | if [[ $(qbittorrent-nox -v | awk '{print $2}') == "v5."* ]]; then 9 | mark_states=stopped 10 | mark_start=start 11 | else 12 | mark_states=paused 13 | mark_start=resume 14 | fi 15 | 16 | ## 检测出需要校验的种子并发起校验 17 | downloading_info=$($cmd_curl "${api_url_base}/torrents/info?filter=downloading") 18 | downloading_hashes=( $(echo $downloading_info | jq -r .[].hash) ) 19 | downloading_states=( $(echo $downloading_info | jq -r .[].state) ) 20 | recheck_hashes="" 21 | for ((i=0; i<${#downloading_hashes[*]}; i++)); do 22 | piece_states="" 23 | piece_states=$($cmd_curl "$api_url_base/torrents/pieceStates?hash=${downloading_hashes[i]}") 24 | if [[ ${downloading_states[i]} == ${mark_states}DL && ${piece_states} != *2* ]]; then 25 | recheck_hashes="${recheck_hashes}|${downloading_hashes[i]}" 26 | fi 27 | done 28 | echo "hashes=${recheck_hashes/|/}" | $cmd_curl_post "$api_url_base/torrents/recheck" -d @- 29 | recheck_hashes_sum=$(echo ${recheck_hashes/|/} | awk -F "|" '{print NF}') 30 | if [[ $recheck_hashes_sum -gt 0 ]]; then 31 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] qbittorrent客户端对 ${recheck_hashes_sum} 个种子发起重新检验" 32 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 重新校验的种子hash分别为 ${recheck_hashes/|/}" 33 | elif [[ $recheck_hashes_sum -eq 0 ]]; then 34 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 当前没有需要重新校验的种子" 35 | fi 36 | 37 | ## 检测校验完成的种子,并对100%完成率的种子恢复做种 38 | sleep 1 39 | paused_info=$($cmd_curl "${api_url_base}/torrents/info?filter=${mark_states}") 40 | paused_hashes=( $(echo $paused_info | jq -r .[].hash) ) 41 | paused_states=( $(echo $paused_info | jq -r .[].state) ) 42 | resume_hashes="" 43 | for ((i=0; i<${#paused_hashes[*]}; i++)); do 44 | piece_states="" 45 | piece_states=$($cmd_curl "$api_url_base/torrents/pieceStates?hash=${paused_hashes[i]}") 46 | if [[ ${paused_states[i]} == ${mark_states}UP && ${piece_states} != *0* && ${piece_states} != *1* ]]; then 47 | resume_hashes="${resume_hashes}|${paused_hashes[i]}" 48 | fi 49 | done 50 | echo "hashes=${resume_hashes/|/}" | $cmd_curl_post "$api_url_base/torrents/$mark_start" -d @- 51 | resume_hashes_sum=$(echo ${resume_hashes/|/} | awk -F "|" '{print NF}') 52 | if [[ $resume_hashes_sum -gt 0 ]]; then 53 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] qbittorrent客户端对 ${resume_hashes_sum} 个种子恢复做种" 54 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 恢复做种的种子hash分别为 ${resume_hashes/|/}" 55 | elif [[ $resume_hashes_sum -eq 0 ]]; then 56 | echo "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 当前没有需要恢复做种的种子" 57 | fi 58 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/nice-size: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | size_byte=$1 4 | 5 | if [[ ${#size_byte} -ge 13 ]]; then 6 | size=$(echo "scale=2; $size_byte/1024^4" | bc) 7 | unit="TiB" 8 | elif [[ ${#size_byte} -ge 10 ]]; then 9 | size=$(echo "scale=2; $size_byte/1024^3" | bc) 10 | unit="GiB" 11 | elif [[ ${#size_byte} -ge 7 ]]; then 12 | size=$(echo "scale=2; $size_byte/1024^2" | bc) 13 | unit="MiB" 14 | else 15 | size=$(echo "scale=2; $size_byte/1024" | bc) 16 | unit="KiB" 17 | fi 18 | 19 | if [[ $size == .* ]]; then 20 | size=0$size 21 | fi 22 | 23 | echo "$size $unit" 24 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/nice-time: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pam=$1 4 | 5 | if [[ $pam -ge 86400 ]]; then 6 | nice_day=$(($pam / 86400)) 7 | nice_hour=$(( ($pam % 86400) / 3600 )) 8 | nice_min=$(( ($pam % 3600) / 60 )) 9 | nice_sec=$(($pam % 60)) 10 | echo "$nice_day天$nice_hour小时$nice_min分$nice_sec秒" 11 | elif [[ $pam -ge 3600 ]]; then 12 | nice_hour=$(($pam / 3600)) 13 | nice_min=$(( ($pam % 3600) / 60 )) 14 | nice_sec=$(($pam % 60)) 15 | echo "$nice_hour小时$nice_min分$nice_sec秒" 16 | elif [[ $pam -ge 60 ]]; then 17 | nice_min=$(($pam / 60)) 18 | nice_sec=$(($pam % 60)) 19 | echo "$nice_min分$nice_sec秒" 20 | else 21 | echo "$pam秒" 22 | fi 23 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/notify: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## 钉钉通知,参考https://github.com/hzgjq/DingTalkRobot,$1:消息内容 4 | notify_dingding_bot () { 5 | local message="{\"msgtype\": \"text\",\"text\": {\"content\": \"$1\"}}" 6 | local dd_api_url_base=https://oapi.dingtalk.com/robot/send 7 | local timestamp sign dd_api_url send_result err_code err_message 8 | 9 | timestamp=$(date -u "+%s000") 10 | sign=$(echo -ne "$timestamp\n$DD_BOT_SECRET" | openssl dgst -sha256 -hmac "$DD_BOT_SECRET" -binary | openssl base64) 11 | dd_api_url="${dd_api_url_base}?access_token=${DD_BOT_TOKEN}×tamp=${timestamp}&sign=${sign}" 12 | send_result=$(curl -Ssk -H "Content-Type:application/json" -X POST -d "$message" "$dd_api_url") 13 | err_code=$(echo "$send_result" | jq .errcode) 14 | err_message=$(echo "$send_result" | jq -r .errmsg) 15 | if [[ $err_code -eq 0 ]]; then 16 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送钉钉BOT通知成功\n" 17 | else 18 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送钉钉BOT通知失败,错误代码:$err_code,错误消息:$err_message\n" 19 | fi 20 | } 21 | 22 | ## 发送Telegram通知,$1:消息内容 23 | notify_telegram () { 24 | local message="$(echo -e $1 | sed 's!&!%26!g')" 25 | ## local tg_api_url="https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" 26 | local send_result err_code err_message 27 | local cmd_proxy_user cmd_proxy 28 | 29 | ## 使用 Telegram API 反代地址替代原始 API 地址 30 | if [ -z "$TG_API_HOST" ]; then 31 | local tg_api_url="https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" 32 | else 33 | if [[ "${TG_API_HOST: -1}" != "/" ]]; then 34 | TG_API_HOST="${TG_API_HOST}/" 35 | fi 36 | if [[ "http://" == "${TG_API_HOST:0:7}" || "https://" == "${TG_API_HOST:0:8}" ]]; then 37 | local tg_api_url="${TG_API_HOST}bot${TG_BOT_TOKEN}/sendMessage" 38 | else 39 | local tg_api_url="https://${TG_API_HOST}bot${TG_BOT_TOKEN}/sendMessage" 40 | fi 41 | fi 42 | 43 | [[ $TG_PROXY_USER ]] && cmd_proxy_user="--proxy-user ${TG_PROXY_USER}" || cmd_proxy_user="" 44 | [[ $TG_PROXY_ADDRESS ]] && cmd_proxy="--proxy $TG_PROXY_ADDRESS $cmd_proxy_user" || cmd_proxy="" 45 | 46 | send_result=$(curl -Ssk $cmd_proxy -H "Content-Type:application/x-www-form-urlencoded" -X POST -d "chat_id=${TG_USER_ID}&text=${message}&disable_web_page_preview=true" "$tg_api_url") 47 | send_result=$(echo "$send_result" | sed '{:label; N; s/\n/\\n/g; b label; s/\\n$//}') 48 | err_code=$(echo "$send_result" | jq .ok) 49 | if [[ $err_code == true ]]; then 50 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送Telegram通知成功\n" 51 | else 52 | err_code=$(echo "$send_result" | jq .err_code) 53 | [[ err_code == 400 ]] && err_message="请主动给bot发送一条消息并检查接收用户ID是否正确。" 54 | [[ err_code == 401 ]] && err_message="Telegram Bot Token 填写错误。" 55 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送Telegram通知失败,错误代码:$err_code,错误消息:$err_message\n" 56 | fi 57 | } 58 | 59 | ## 爱语飞飞通知,$1:标题;$2:内容 60 | notify_iyuu () { 61 | local title="$(echo $1 | sed 's!&!%26!g')" 62 | local desp="$(echo -e $2 | sed 's!&!%26!g')" 63 | local iyuu_url=http://iyuu.cn/${IYUU_TOKEN}.send 64 | local send_result err_code err_message 65 | 66 | send_result=$(curl -Ss -X POST -d "text=${title}&desp=${desp}" $iyuu_url) 67 | err_code=$(echo "$send_result" | jq .errcode) 68 | err_message=$(echo "$send_result" | jq -r .errmsg) 69 | if [[ $err_code -eq 0 ]]; then 70 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送爱语飞飞通知成功\n" 71 | else 72 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送爱语飞飞通知失败,错误代码:$err_code,错误消息:$err_message\n" 73 | fi 74 | } 75 | 76 | ## Server酱通知,$1:标题;$2:内容 77 | notify_serverchan () { 78 | local title="$(echo $1 | sed 's!&!%26!g')" 79 | local desp="$(echo -e $2 | sed 's!&!%26!g')" 80 | local serverchan_url send_result 81 | 82 | [[ $SCKEY == SCT* ]] && serverchan_url=https://sctapi.ftqq.com/${SCKEY}.send || serverchan_url=https://fcqq.com/${SCKEY}.send 83 | send_result=$(curl -Ssk -X POST -d "text=${title}&desp=${desp}" $serverchan_url) 84 | if [[ $(echo "$send_result" | jq .code) -eq 0 ]]; then 85 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送Server酱通知成功\n" 86 | else 87 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送Server酱通知失败,错误消息:$send_result\n" 88 | fi 89 | } 90 | 91 | ## PushPlus,$1:标题;$2:内容 92 | notify_pushplus() { 93 | local title="$1" 94 | local desp="$(echo -e $2)" 95 | local pushplus_url=http://www.pushplus.plus/send 96 | local message="{\"token\": \"${PUSHPLUS_TOKEN}\", \"title\": \"${title}\", \"content\": \"${desp}\", \"channel\": \"wechat\", \"webhook\": \"\", \"callbackUrl\": \"\"}" 97 | local send_result 98 | 99 | send_result=$(curl -Ssk -X POST -H "Content-Type: application/json" -d "$message" $pushplus_url) 100 | if [[ $(echo $send_result | jq .code) -eq 200 ]]; then 101 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送PushPlus通知成功\n" 102 | else 103 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送PushPlus通知失败,错误消息:$(echo $send_result | jq -r .msg)\n" 104 | fi 105 | } 106 | 107 | ## 企业微信群机器人消息,$1:消息内容 108 | notify_work_wechat_bot() { 109 | local work_wechat_bot_url="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${WORK_WECHAT_BOT_KEY}" 110 | local message="{\"msgtype\": \"text\", \"text\": {\"content\": \"$1\"}}" 111 | local send_result err_code err_message 112 | 113 | send_result=$(curl -Ssk -H "Content-Type:application/json" -X POST -d "$message" "$work_wechat_bot_url") 114 | err_code=$(echo "$send_result" | jq .errcode) 115 | err_message=$(echo "$send_result" | jq -r .errmsg) 116 | if [[ $err_code -eq 0 ]]; then 117 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送企业微信群BOT通知成功\n" 118 | else 119 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送企业微信群BOT通知失败,错误代码:$err_code,错误消息:$err_message\n" 120 | fi 121 | } 122 | 123 | ## Gotify通知,$1:标题;$2:内容 124 | notify_gotify() { 125 | local title="$1" 126 | local desp="$(echo -e $2)" 127 | local send_result err_code err_message 128 | 129 | send_result=$(curl -Ssk "${GOTIFY_URL}/message?token=${GOTIFY_APP_TOKEN}" -F "title=$title" -F "message=$desp" -F "priority=${GOTIFY_PRIORITY:-5}") 130 | if [[ $(echo $send_result | jq -r .date) != null ]]; then 131 | echo -e "(N) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送GOTIFY通知成功\n" 132 | elif [[ $(echo $send_result | jq -r .errorCode) != null ]]; then 133 | err_code=$(echo "$send_result" | jq -r .errorCode) 134 | err_message=$(echo "$send_result" | jq -r .errorDescription) 135 | echo -e "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 发送GOTIFY通知失败,错误代码:$err_code,错误消息:$err_message\n" 136 | fi 137 | } 138 | 139 | ## 发送通知,$1:标题;$2:内容 140 | title=$(echo "$1") 141 | desp=$(echo "$2") 142 | [[ $DD_BOT_TOKEN ]] && [[ $DD_BOT_SECRET ]] && notify_dingding_bot "$title\n\n$desp" 143 | [[ $TG_BOT_TOKEN ]] && [[ $TG_USER_ID ]] && notify_telegram "$title\n\n$desp" 144 | [[ $IYUU_TOKEN ]] && notify_iyuu "$title" "$desp" 145 | [[ $SCKEY ]] && notify_serverchan "$title" "$desp" 146 | [[ $PUSHPLUS_TOKEN ]] && notify_pushplus "$title" "$desp" 147 | [[ $WORK_WECHAT_BOT_KEY ]] && notify_work_wechat_bot "$title\n\n$desp" 148 | [[ $GOTIFY_URL ]] && [[ $GOTIFY_APP_TOKEN ]] && notify_gotify "$title" "$desp" 149 | [[ -z $DD_BOT_TOKEN && -z $DD_BOT_SECRET && -z $TG_BOT_TOKEN && -z $TG_USER_ID && -z $IYUU_TOKEN && -z $SCKEY && -z $PUSHPLUS_TOKEN && -z $WORK_WECHAT_BOT_KEY && -z $GOTIFY_URL && -z $GOTIFY_APP_TOKEN ]] && echo "(W) $(date +'%Y-%m-%dT%H:%M:%S') - [$(basename $0)] 没有有效的通知渠道,不发送通知消息..." 150 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/remove-tracker: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | handle_all_match_torrents() { 4 | local method=$1 5 | 6 | . /usr/local/bin/share 7 | echo -e "\n检测种子清单...\n" 8 | hashes=( $($cmd_curl ${api_url_base}/torrents/info | jq -r .[].hash) ) 9 | echo -e "开始删除指定的tracker...\n\n搜索过程可能较慢,请等待程序运行完成...\n\n有以下种子匹配所提供的信息,并完成删除:\n" 10 | local change_count=0 11 | for hash in ${hashes[@]}; do 12 | trackers_url=( $($cmd_curl $api_url_base/torrents/trackers?hash=$hash | jq -r .[].url | sed "s# #_#g") ) 13 | for ((n = $((${#trackers_url[*]} - 1)); n >= 0; n--)); do 14 | if [[ $method == exact && ${trackers_url[n]} == ${tracker_orig_url} ]] || [[ $method == blur && ${trackers_url[n]} == *${orig_string}* ]]; then 15 | local torrent_name=$($cmd_curl "${api_url_base}/torrents/info?hashes=${hash}" | jq -r .[0].name) 16 | echo "hash: ${hash}, torrent_name: ${torrent_name}" 17 | $cmd_curl_post $api_url_base/torrents/removeTrackers -d "hash=${hash}&urls=${trackers_url[n]//&/%26}" 18 | let change_count++ 19 | break 20 | fi 21 | done 22 | done 23 | echo -e "\n共删除了${change_count}个种子的tracker,程序运行完成" 24 | } 25 | 26 | usage() { 27 | echo "用法1:remove-tracker -m -s " 28 | echo " 命令中直接带上参数,此用法支持由cron定时任务自动运行" 29 | echo " mode允许的值为:1或2,1指精确匹配,匹配整个tracker才进行删除;2指模糊匹配,只要tracker中含有所提供的字符,就进行删除,使用此模式一定要慎重,务必确保输入的字符满足预期!!!" 30 | echo " 当mode为1时,string为完整的tracker地址;当mode为2时,string为要删除的tracker含有的字符,请务必确保输入的字符满足预期!!!" 31 | echo " 示例:remove-tracker -m 1 -s https://tracker.example.com/passkey=qwertyuiopasdfghjkll" 32 | echo " 示例:remove-tracker -m 2 -s tracker.example.com" 33 | echo 34 | echo "用法2:remove-tracker" 35 | echo " 命令中不带参数,这种用法由用户随后根据提示主动输入模式选择和要删除的tracker信息" 36 | } 37 | 38 | main_1() { 39 | while getopts :m:s: OPT; do 40 | case $OPT in 41 | m) mode="$OPTARG";; 42 | s) str="$OPTARG";; 43 | ?) usage && exit 2;; 44 | esac 45 | done 46 | shift $((OPTIND - 1)) 47 | [[ -z $str ]] && usage && exit 3 48 | case $mode in 49 | 1) 50 | tracker_orig_url="$str" 51 | handle_all_match_torrents exact 52 | ;; 53 | 2) 54 | orig_string="$str" 55 | handle_all_match_torrents blur 56 | ;; 57 | *) 58 | usage 59 | exit 4 60 | ;; 61 | esac 62 | } 63 | 64 | main_2() { 65 | echo -e "匹配模式:\n" 66 | echo -e "1. 精确匹配:匹配整个tracker才进行删除。\n" 67 | echo -e "2. 模糊匹配:只要tracker中含有所提供的字符,就进行删除,使用此模式一定要慎重,务必确保输入的字符满足预期!!!\n" 68 | read -p "请选择匹配模式 [1/2]:" match_method 69 | echo 70 | case $match_method in 71 | 1) 72 | read -p "请输入要删除的tracker:" tracker_orig_url 73 | echo 74 | echo -e "要删除的tracker为:$tracker_orig_url\n" 75 | read -p "请确认信息无误 [y/N]:" choice1 76 | if [[ $choice1 == [Yy] || $choice1 == [Yy][Ee][Ss] ]]; then 77 | handle_all_match_torrents exact 78 | fi 79 | ;; 80 | 2) 81 | read -p "请输入要删除含有什么字符的tracker:" orig_string 82 | echo 83 | echo -e "若tracker中含有以下字符就删除:'$orig_string'\n" 84 | read -p "请确认信息无误 [y/N]:" choice2 85 | if [[ $choice2 == [Yy] || $choice2 == [Yy][Ee][Ss] ]]; then 86 | handle_all_match_torrents blur 87 | fi 88 | ;; 89 | *) 90 | echo "输入错误,退出脚本(请输入'1'或'2')" 91 | exit 1 92 | ;; 93 | esac 94 | } 95 | 96 | if [[ -n "$@" ]]; then 97 | main_1 "$@" 98 | else 99 | main_2 100 | fi 101 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/report-seed-files: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | tmplist=$(mktemp) 4 | tmppaste1=$(mktemp) 5 | tmppaste2=$(mktemp) 6 | tmppaste3=$(mktemp) 7 | seed_files=/data/diy/seed_files.list 8 | 9 | . /usr/local/bin/share 10 | 11 | echo -e "本脚本用于生成本qBittorrent客户端中所有种子中的文件清单,生成的清单位于容器内的:$seed_files\n" 12 | echo -e "种子越多,生成清单也就越耗时,请勿在生成清单过程中打断...\n" 13 | read -p "请确认是否继续执行本脚本 [y/N]:" is_report 14 | echo 15 | if [[ $is_report == [Yy] || $is_report == [Yy][Ee][Ss] ]]; then 16 | read -p "是否在控制台显示处理进度(即是否显示当前正在处理的种子编号和hash,如不显示可大约减少40%运行时间) [Y/n]:" is_console 17 | echo -e "\n开始生成做种文件清单...\n" 18 | torrents_info=$($cmd_curl ${api_url_base}/torrents/info) 19 | hashes=( $(echo "$torrents_info" | jq -r .[].hash | tee $tmppaste1) ) 20 | sed -i "s|^|_|g" $tmppaste1 21 | echo "$torrents_info" | jq .[].save_path > $tmppaste2 22 | paste -d "=" $tmppaste1 $tmppaste2 > $tmppaste3 23 | . $tmppaste3 24 | if [[ $is_console == [Nn] || $is_console == [Nn][Oo] ]]; then 25 | for ((i=0; i<${#hashes[@]}; i++)); do 26 | eval save_path=\$_${hashes[i]} 27 | $cmd_curl "${api_url_base}/torrents/files?hash=${hashes[i]}" | jq -r .[].name | sed "s|^|$save_path/|g" >> $tmplist 28 | done 29 | else 30 | for ((i=0; i<${#hashes[@]}; i++)); do 31 | echo "$(( $i + 1)): ${hashes[i]}" 32 | eval save_path=\$_${hashes[i]} 33 | $cmd_curl "${api_url_base}/torrents/files?hash=${hashes[i]}" | jq -r .[].name | sed "s|^|$save_path/|g" >> $tmplist 34 | done 35 | fi 36 | sort -u -o $seed_files $tmplist 37 | rm $tmplist $tmppaste1 $tmppaste2 $tmppaste3 38 | [[ $(id -u) -eq 0 ]] && chown "${PUID}:${PGID}" $seed_files 39 | echo -e "\n生成完毕,生成的清单文件为:$seed_files\n" 40 | fi 41 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/report-unseed-files: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | seed_files=/data/diy/seed_files.list 4 | unseed_files=/data/diy/unseed_files.list 5 | 6 | echo -e "本脚本用来检测指定的文件夹中所有文件(包括所有下级文件)是否在本qBittorrent客户端中做种,并将未做种的文件形成一份清单。\n" 7 | echo -e "生成的未做种文件清单位于容器内的:$unseed_files,再次运行本脚本将会重新生成该文件。\n" 8 | echo -e "继续执行前请确认以下两个前提条件是否已经满足:\n" 9 | echo -e "1. 已经运行过 'report-seed-files' 脚本,并已经生成了做种文件清单:$seed_files;\n" 10 | echo -e "2. 已经生成的 $seed_files 是本qBittorrent客户端的当前最新状态。\n" 11 | read -p "请确认是否继续执行本脚本 [y/N]:" is_report 12 | echo 13 | 14 | if [[ $is_report == [Yy] || $is_report == [Yy][Ee][Ss] ]]; then 15 | if [[ ! -f $seed_files ]]; then 16 | echo -e "做种文件清单 '$seed_files' 不存在,请确认前提条件是否已经满足\n" 17 | exit 1 18 | else 19 | modtime=$(date +'%Y-%m-%d %H:%M:%S' -d @$(stat -c %Y $seed_files)) 20 | echo -e "检测到做种文件清单 '$seed_files' 已存在,该清单的最后修改时间为:$modtime。\n" 21 | read -p "请确认该文件是本qBittorrent客户端的最新状态 [y/N]:" is_new 22 | echo 23 | if [[ $is_new != [Yy] && $is_new != [Yy][Ee][Ss] ]]; then 24 | exit 2 25 | fi 26 | fi 27 | echo -e "请输入要检测的文件夹的绝对路径,多个路径之间使用半角冒号分隔,形如 /movies:/tv:/music\n" 28 | read -p "请输入所有检测路径:" detect_pathes 29 | echo 30 | detect_pathes=$(echo $detect_pathes | sed 's|:|\n|g' | sort -u) 31 | while read path; do 32 | if [[ ! -d "$path" ]]; then 33 | echo -e "路径 '$path' 不存在,退出脚本" 34 | exit 3 35 | fi 36 | done <<< $(echo "$detect_pathes") 37 | 38 | [[ -f $unseed_files ]] && rm $unseed_files 39 | echo -e "开始生成未做种文件清单,请等待...\n" 40 | tmpfile=$(mktemp) 41 | echo "$detect_pathes" | while read path; do 42 | find "$path" -type f | sort >> "$tmpfile" 43 | done 44 | grep -Fxv -f "$seed_files" "$tmpfile" > "$unseed_files" 45 | rm "$tmpfile" 46 | [[ $(id -u) -eq 0 ]] && chown "${PUID}:${PGID}" $unseed_files 47 | echo -e "已成功生成指定路径下所有未做种文件清单:$unseed_files\n" 48 | echo -e "如果需要删除某些未做种文件,请按以下流程操作:\n" 49 | echo -e "1. 打开清单 '$unseed_files',并将想保留在系统中的文件从该清单中删除,也就是仅将想要删除的文件保留在这个清单中;\n" 50 | echo -e "2. 再三确认该清单中所有文件都是想要删除的文件,务必确保这一点;\n" 51 | echo -e "3. 最后在容器中运行此命令即可进行批量删除:cat $unseed_files | while read file; do rm \"\$file\"; done\n" 52 | fi 53 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/share: -------------------------------------------------------------------------------- 1 | WEBUI_PORT=${WEBUI_PORT:-34567} 2 | 3 | urlencode() { 4 | while read -n1 char; do 5 | case $char in 6 | [a-zA-Z0-9.~_-]) printf "%s" "$char";; 7 | *) printf "%%%02X" "'$char";; 8 | esac 9 | done 10 | printf '\n' 11 | } 12 | 13 | get_qb_url() { 14 | local is_ssl=$(grep -i "WebUI\\\HTTPS\\\Enabled=" /data/config/qBittorrent.conf | awk -F "=" '{print $2}') 15 | local url_prefix 16 | 17 | if [[ $is_ssl == true ]]; then 18 | url_prefix="https://" 19 | else 20 | url_prefix="http://" 21 | fi 22 | 23 | local qb_url="${url_prefix}127.0.0.1:${WEBUI_PORT}" 24 | echo "$qb_url" 25 | } 26 | 27 | get_qb_ck() { 28 | local QB_PASSWORD=$(echo -en $QB_PASSWORD | urlencode) 29 | local info=$(curl -iksS -H "Referer: $qb_url" -d "username=${QB_USERNAME}&password=${QB_PASSWORD}" $api_url_base/auth/login) 30 | local qb_cookie=$(echo "$info" | awk '/set-cookie/{print $2}') 31 | if [[ -n $qb_cookie ]]; then 32 | echo $qb_cookie 33 | fi 34 | } 35 | 36 | if [[ $QB_USERNAME == admin && $QB_PASSWORD == adminadmin ]]; then 37 | echo "环境变量 QB_USERNAME 和 QB_PASSWORD 为默认值,无法使用本脚本,请修改这两项环境变量为非默认值后再试。" 38 | echo "Environmental variable QB_USERNAME and QB_PASSWORD is the default value and cannot be used in this script. Please modify these two environment variables to non default values and try again." 39 | exit 1 40 | fi 41 | 42 | qb_url=$(get_qb_url) 43 | api_url_base="$qb_url/api/v2" 44 | cmd_curl="curl -sk -b $(get_qb_ck)" 45 | cmd_curl_post="$cmd_curl -X POST" 46 | -------------------------------------------------------------------------------- /qbittorrent/root/usr/local/bin/tracker-error: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | tag_name="TrackerError" 4 | 5 | ## 处理所有torrent 6 | . /usr/local/bin/share 7 | hashes=( $($cmd_curl ${api_url_base}/torrents/info | jq -r .[].hash) ) 8 | tracker_error_count=0 9 | add_hashes="" 10 | $cmd_curl_post -d "hashes=all&tags=${tag_name}" ${api_url_base}/torrents/removeTags 11 | for hash in "${hashes[@]}"; do 12 | if [[ -z $($cmd_curl "${api_url_base}/torrents/trackers?hash=${hash}" | jq '.[] | select(.tier >= 0)' | jq -r '.status | select(. <= 3)') ]]; then 13 | add_hashes="${add_hashes}|${hash}" 14 | fi 15 | done 16 | 17 | ## 调整标签 18 | if [[ -n $add_hashes ]]; then 19 | echo "hashes=${add_hashes/|/}&tags=${tag_name}" | $cmd_curl_post -d @- ${api_url_base}/torrents/addTags 20 | 21 | ## 发送通知 22 | TRACKER_ERROR_COUNT_MIN=${TRACKER_ERROR_COUNT_MIN:-3} 23 | tracker_error_count=$(echo ${add_hashes/|/} | awk -F "|" '{print NF}') 24 | if [[ $tracker_error_count -ge $TRACKER_ERROR_COUNT_MIN ]]; then 25 | notify "tracker出错数量超过阈值" "主机:${HOSTNAME}\n时间:$(date +'%Y-%m-%d %H:%M:%S')\n注意:当前有${tracker_error_count}个种子tracker出错,建议检查一下\n说明:您收到本通知是因为您设置了通知阈值TRACKER_ERROR_COUNT_MIN=${TRACKER_ERROR_COUNT_MIN}(默认值:3)" 26 | fi 27 | fi 28 | 29 | -------------------------------------------------------------------------------- /qbittorrent/root2/etc/entrypoint.d/60-crontab2.sh: -------------------------------------------------------------------------------- 1 | ## 补充IYUU更新脚本并重启程序的的cron 2 | minute=$(($RANDOM % 60)) 3 | hour_start=$(($RANDOM % 6)) 4 | hour_interval=$(($RANDOM % 4 + 6)) 5 | CRON_UPDATE="${minute} ${hour_start}-23/${hour_interval} * * *" 6 | echo -e "$(su-exec "${PUID}:${PGID}" crontab -l)\n\n# 更新并重启IYUU\n${CRON_UPDATE} cd /iyuu && git fetch --all && git reset --hard origin/master && git pull && php start.php restart -d >> /data/diy/crond.log" | su-exec "${PUID}:${PGID}" crontab - 7 | -------------------------------------------------------------------------------- /qbittorrent/root2/etc/entrypoint.d/70-iyuu.sh: -------------------------------------------------------------------------------- 1 | cd /iyuu 2 | 3 | ## 更新一次IYUU 4 | if [[ ! -d .git ]]; then 5 | echo "Clone IYUUAutoReseed script..." 6 | rm -rf /iyuu/* 2>/dev/null 7 | git clone ${IYUU_REPO_URL} /tmp/iyuu 8 | find /tmp/iyuu -mindepth 1 -maxdepth 1 | xargs -I {} cp -r {} /iyuu 9 | rm -rf /tmp/iyuu 10 | else 11 | echo "Update IYUUAutoReseed script..." 12 | git remote set-url origin ${IYUU_REPO_URL} 13 | git fetch --all 14 | git reset --hard origin/master 15 | git pull 16 | fi 17 | 18 | ## 复制.env 19 | if [[ ! -s .env ]]; then 20 | cp -f .env.example .env 21 | fi 22 | 23 | ## 创建/data/iyuu_db文件夹,并软连接到/iyuu/db 24 | IYUU_DB=/data/iyuu_db 25 | [ ! -d ${IYUU_DB} ] && mkdir ${IYUU_DB} 26 | if [[ $(readlink -f /iyuu/db 2>/dev/null) != ${IYUU_DB} ]]; then 27 | rm -rf /iyuu/db 2>/dev/null 28 | ln -sf ${IYUU_DB} /iyuu/db 29 | fi 30 | 31 | get_qb_url() { 32 | local is_ssl=$(grep -i "WebUI\\\HTTPS\\\Enabled=" /data/config/qBittorrent.conf | awk -F "=" '{print $2}') 33 | local url_prefix 34 | 35 | if [[ $is_ssl == true ]]; then 36 | url_prefix="https://" 37 | else 38 | url_prefix="http://" 39 | fi 40 | 41 | local qb_url="${url_prefix}127.0.0.1:${WEBUI_PORT}" 42 | echo "$qb_url" 43 | } 44 | 45 | ## 写入/data/iyuu_db/clients.json 46 | CLIENT_FILE=/data/iyuu_db/clients.json 47 | HOST=$(get_qb_url | sed "s|/|\\\\\\\/|g") 48 | if [[ ! -s ${CLIENT_FILE} ]]; then 49 | cur_timestamp=$(( $(date +'%s') * 1000 + $RANDOM % 1000 )) 50 | PID="pid$$_${cur_timestamp}" 51 | CLIENT_INFO="eyJQSUQiOnsidHlwZSI6InFCaXR0b3JyZW50IiwidXVpZCI6IlBJRCIsIm5hbWUiOiJsb2NhbGhvc3QiLCJob3N0IjoiSE9TVCIsImVuZHBvaW50IjoiIiwidXNlcm5hbWUiOiJRQl9VU0VSTkFNRSIsInBhc3N3b3JkIjoiUUJfUEFTU1dPUkQiLCJkb2NrZXIiOiJvbiIsImRlZmF1bHQiOiJvbiIsInJvb3RfZm9sZGVyIjoib24iLCJ3YXRjaCI6IlwvZGF0YVwvd2F0Y2giLCJkb3dubG9hZHNEaXIiOiJcL2RhdGFcL2Rvd25sb2FkcyIsIkJUX2JhY2t1cCI6IlwvZGF0YVwvZGF0YVwvQlRfYmFja3VwIn19" 52 | echo -en "$CLIENT_INFO" | base64 -d > ${CLIENT_FILE} 53 | chmod 666 ${CLIENT_FILE} 54 | sed -i "{s#PID#$PID#g; s#HOST#$HOST#g;}" ${CLIENT_FILE} 55 | if [[ ${QB_USERNAME} != admin || $QB_PASSWORD != adminadmin ]]; then 56 | sed -i "{ 57 | s|QB_USERNAME|${QB_USERNAME}|g; 58 | s|QB_PASSWORD|${QB_PASSWORD}|g; 59 | }" ${CLIENT_FILE} 60 | fi 61 | else 62 | sed -i "{ 63 | s|\(\"host\":\"\)[^\"]*127\.0\.0\.1[^\"]*\(\"\)|\1$HOST\2|g; 64 | s|\(\"username\":\"\)[^\"]*\(\"\)|\1${QB_USERNAME}\2|g; 65 | s|\(\"password\":\"\)[^\"]*\(\"\)|\1${QB_PASSWORD}\2|g; 66 | }" ${CLIENT_FILE} 67 | fi 68 | 69 | ## 以Daemon形式启动IYUU 70 | chown -R "${PUID}:${PGID}" ${IYUU_DB} /iyuu 71 | su-exec "${PUID}:${PGID}" php start.php start -d 72 | -------------------------------------------------------------------------------- /subfinder/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !entrypoint.sh 3 | !Dockerfile* -------------------------------------------------------------------------------- /subfinder/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG ALPINE_VERSION=latest 2 | FROM alpine:${ALPINE_VERSION} 3 | ENV INTERVAL=2h \ 4 | UMASK=022 \ 5 | PUID=1000 \ 6 | PGID=100 \ 7 | PS1="\u@\h:\w \$ " 8 | COPY --from=nevinee/loop:latest / / 9 | COPY entrypoint.sh /usr/bin/entrypoint.sh 10 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ 11 | && apk add --update --no-cache \ 12 | python3 \ 13 | py3-pip \ 14 | unzip \ 15 | unrar \ 16 | su-exec \ 17 | tini \ 18 | libxml2 \ 19 | libxslt \ 20 | && apk add --update --no-cache --virtual .build \ 21 | build-base \ 22 | python3-dev \ 23 | musl-dev \ 24 | libxml2-dev \ 25 | libxslt-dev \ 26 | libffi-dev \ 27 | && ln -sf /usr/bin/python3 /usr/bin/python \ 28 | && pip install subfinder \ 29 | && apk del --purge --no-cache .build \ 30 | && rm -rf \ 31 | /tmp/* \ 32 | /root/.cache \ 33 | /var/cache/apk/* 34 | VOLUME ["/config", "/media"] 35 | ENTRYPOINT ["tini", "entrypoint.sh"] 36 | -------------------------------------------------------------------------------- /subfinder/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/subfinder" 4 | arch="linux/amd64,linux/arm64,linux/arm/v7" 5 | ver=$(curl -s https://api.github.com/repos/ausaki/subfinder/releases/latest | jq -r .tag_name | sed "s/v//") 6 | alpine_ver=${1:-latest} 7 | 8 | buildx() { 9 | docker pull tonistiigi/binfmt 10 | docker run --privileged --rm tonistiigi/binfmt --install all 11 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 12 | docker buildx inspect --bootstrap 13 | docker buildx build \ 14 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 15 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 16 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 17 | --platform "$arch" \ 18 | --tag ${repo}:${ver} \ 19 | --tag ${repo}:latest \ 20 | --push \ 21 | . 22 | docker pushrm -s "自动下载中文字幕,支持平台:amd64/arm64/armv7,镜像体积小" $repo # https://github.com/christian-korneck/docker-pushrm 23 | } 24 | 25 | if [[ $ver ]]; then 26 | [[ ! -d logs ]] && mkdir logs 27 | echo "alpine_ver=${1:-latest}" 28 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 29 | else 30 | echo "未获取到最新版本号" 31 | fi 32 | -------------------------------------------------------------------------------- /subfinder/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -s /config/subfinder.json ]; then 4 | echo '文件 "/config/subfinder.json" 不存在,使用默认配置...' 5 | echo 'ewogICJleHRzIjogWyJhc3MiLCAic3J0Il0sCiAgIm1ldGhvZCI6IFsiemltdWt1IiwgInN1YmhkIiwgInNob290ZXIiXSwKICAidmlkZW9fZXh0cyI6IFsiLm1rdiIsICIubXA0IiwgIi50cyIsICIuaXNvIl0sCiAgImFwaV91cmxzIjogewogICAgInppbXVrdSI6ICJodHRwczovL3d3dy56aW11a3UucHcvc2VhcmNoIiwKICAgICJzdWJoZCI6ICJodHRwczovL3N1YmhkLnR2L3NlYXJjaCIsCiAgICAic3ViaGRfYXBpX3N1YnRpdGxlX2Rvd25sb2FkIjogIi9hamF4L2Rvd25fYWpheCIsCiAgICAic3ViaGRfYXBpX3N1YnRpdGxlX3ByZXZpZXciOiAiL2FqYXgvZmlsZV9hamF4IgogIH0KfQoK' | base64 -d > /config/subfinder.json 6 | else 7 | echo '文件 "/config/subfinder.json" 已存在,使用该文件作为配置...' 8 | fi 9 | 10 | chown -R "${PUID}:${PGID}" /config 11 | umask ${UMASK:-022} 12 | exec su-exec "${PUID}:${PGID}" loop -e ${INTERVAL} -- subfinder -c /config/subfinder.json /media 13 | -------------------------------------------------------------------------------- /subfinder/readme.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | 中文字幕自动下载,是这个项目的Docker实现:https://github.com/ausaki/subfinder 4 | 5 | 基于alpine实现,镜像体积小,支持 amd64/arm64/armv7 三大主流架构。 6 | 7 | 还有另外一个作者的同类项目目前仍在更新:[ChineseSubFinder](https://github.com/allanpk716/ChineseSubFinder) ,该项目官方镜像:[allanpk716/chinesesubfinder](https://hub.docker.com/r/allanpk716/chinesesubfinder) ,以及我基于apline重新制作的,略微减小体积,减少层数的镜像:[nevinee/chinesesubfinder](https://hub.docker.com/r/nevinee/chinesesubfinder)。 8 | 9 | ## 创建 10 | 11 | **docker cli** 12 | 13 | ``` 14 | docker run -d \ 15 | --name subfinder \ 16 | --hostname subfiner \ 17 | -v $(pwd)/config:/config `# 冒号左边请修改为你想在主机上保存配置文件的路径` \ 18 | -v $(pwd)/media:/media `# 冒号左边请修改为需要下载字幕的媒体目录` \ 19 | -e INTERVAL=2h `# 每间隔多长时间扫描一次媒体目录,并下载字幕` \ 20 | -e PUID=1000 \ 21 | -e PGID=100 \ 22 | nevinee/subfinder 23 | ``` 24 | 25 | **docker-compose** 26 | 27 | 新建`docker-compose.yml`文件如下,并以命令`docker-compose up -d`启动。 28 | 29 | ``` 30 | version: "3" 31 | services: 32 | subfinder: 33 | image: nevinee/subfinder:latest 34 | volumes: 35 | - ./config:/config # 冒号左边请修改为你想保存配置的路径 36 | - ./media:/media # 冒号左边请修改为你的媒体目录 37 | environment: 38 | - PUID=1000 39 | - PGID=100 40 | - INTERVAL=2h 41 | restart: always 42 | network_mode: bridge 43 | hostname: subfinder 44 | container_name: subfinder 45 | #security_opt: #armv7设备请解除这两行注释 46 | #- seccomp=unconfined 47 | ``` 48 | 49 | ## 关于环境变量的说明 50 | 51 | - 如在使用诸如emby、jellyfin、plex、qbittorrent、transmission、deluge、jackett、sonarr、radarr等等的docker镜像,请务必保证创建本容器时的PUID/PGID和它们一样。 52 | 53 | - `INTERVAL`表示检测媒体目录的间隔,可以设置的形式如:`INTERVAL=5h`(每5小时)、`INTERVAL=30m`(每30分钟)、`INTERVAL=1d`(每1天),默认为:`INTERVAL=2h`。 54 | 55 | ## 关于多个资源目录如何配置的问题 56 | 57 | 将所有资源目录映射在/media的下一层即可,形如`-v /你的资源目录1:/media/目录1 -v /你的资源目录2:/media/目录2 -v /你的资源目录3:/media/目录3`。 58 | 59 | ## 关于配置文件的说明 60 | 61 | 默认配置如下,如不想使用默认配置,请参考:https://github.com/ausaki/subfinder ,修改`config/subfinder.json`即可。 62 | 63 | ```json 64 | { 65 | "exts": ["ass", "srt"], 66 | "method": ["zimuku", "subhd", "shooter"], 67 | "video_exts": [".mkv", ".mp4", ".ts", ".iso"], 68 | "api_urls": { 69 | "zimuku": "https://www.zimuku.pw/search", 70 | "subhd": "https://subhd.tv/search", 71 | "subhd_api_subtitle_download": "/ajax/down_ajax", 72 | "subhd_api_subtitle_preview": "/ajax/file_ajax" 73 | } 74 | } 75 | ``` 76 | 77 | ## 关于armv7设备的补充说明 78 | 79 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 80 | 81 | 解决办法如下: 82 | 83 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 84 | 85 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 86 | 87 | ``` 88 | security_opt: 89 | - seccomp=unconfined 90 | ``` 91 | 92 | ## 源码 93 | 94 | https://gitee.com/evine/dockerfiles/tree/master/subfinder 95 | 96 | https://github.com/devome/dockerfiles/tree/master/subfinder 97 | -------------------------------------------------------------------------------- /team/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine 2 | ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ 3 | LANG=zh_CN.UTF-8 \ 4 | SHELL=/bin/bash \ 5 | PS1="\u@\h:\w \$ " 6 | COPY team/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh 7 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ 8 | && apk update -f \ 9 | && apk upgrade \ 10 | && apk --no-cache add -f bash coreutils moreutils git wget nano tzdata perl openssl openssh-client \ 11 | && rm -rf /var/cache/apk/* \ 12 | && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ 13 | && echo "Asia/Shanghai" > /etc/timezone \ 14 | && echo -e "\n\nHost ${REPO}\nStrictHostKeyChecking no\n" >> /etc/ssh/ssh_config \ 15 | && npm install --registry=https://registry.npm.taobao.org -g pm2 \ 16 | && chmod 777 /usr/local/bin/docker-entrypoint.sh 17 | WORKDIR /root 18 | ENTRYPOINT ["docker-entrypoint.sh"] -------------------------------------------------------------------------------- /team/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2.0" 2 | services: 3 | team: 4 | image: team:latest 5 | container_name: team 6 | restart: always 7 | tty: true 8 | network_mode: "bridge" 9 | hostname: team 10 | volumes: 11 | - ./:/root 12 | ports: 13 | - 5670:5670 14 | labels: 15 | com.centurylinklabs.watchtower.enable: false 16 | 17 | -------------------------------------------------------------------------------- /team/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | crond 5 | 6 | if [[ -s /root/config/crontab.list ]]; then 7 | echo -e "检测到 /root/config/crontab.list 存在,自动导入定时任务...\n" 8 | crontab /root/config/crontab.list 9 | echo -e "成功添加定时任务...\n" 10 | else 11 | echo -e "/root/config/crontab.list 不存在..." 12 | fi 13 | 14 | if [[ -s /root/panel/server.js && -d /root/panel/node_modules ]]; then 15 | pm2 start /root/panel/server.js 16 | echo -e "控制面板启动成功...\n" 17 | else 18 | echo "控制面板未启动,请检查..." 19 | fi 20 | 21 | if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then 22 | set -- node "$@" 23 | fi 24 | 25 | exec "$@" 26 | -------------------------------------------------------------------------------- /tieba-cloud-sign/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !s6-overlay* 3 | !Dockerfile* -------------------------------------------------------------------------------- /tieba-cloud-sign/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | ENV LANG=zh_CN.UTF-8 \ 3 | TZ=Asia/Shanghai \ 4 | WORKDIR=/var/www \ 5 | CRON_TASK="* * * * *" \ 6 | PS1="\u@\h:\w \$ " 7 | RUN apk add --no-cache \ 8 | bash \ 9 | busybox-suid \ 10 | caddy \ 11 | git \ 12 | php8 \ 13 | php8-curl \ 14 | php8-fpm \ 15 | php8-gd \ 16 | php8-json \ 17 | php8-mbstring \ 18 | php8-mysqli \ 19 | php8-session \ 20 | php8-zip \ 21 | s6-overlay \ 22 | shadow \ 23 | tzdata \ 24 | && caddy upgrade \ 25 | && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \ 26 | && echo -e "${TZ}" > /etc/timezone \ 27 | && echo -e "max_execution_time = 3600\nupload_max_filesize=128M\npost_max_size=128M\nmemory_limit=1024M\ndate.timezone=${TZ}" > /etc/php8/conf.d/99-overrides.ini \ 28 | && echo -e "[global]\nerror_log = /dev/stdout\ndaemonize = no\ninclude=/etc/php8/php-fpm.d/*.conf" > /etc/php8/php-fpm.conf \ 29 | && echo -e "[www]\nuser = caddy\ngroup = caddy\nlisten = 127.0.0.1:9000\nlisten.owner = caddy\nlisten.group = caddy\npm = ondemand\npm.max_children = 75\npm.max_requests = 500\npm.process_idle_timeout = 10s\nchdir = $WORKDIR" > /etc/php8/php-fpm.d/www.conf \ 30 | && echo -e ":8080\nroot * $WORKDIR\nlog {\n level warn\n}\nphp_fastcgi 127.0.0.1:9000\nfile_server" > /etc/caddy/Caddyfile \ 31 | && rm -rf $WORKDIR/* /var/cache/apk/* /tmp/* \ 32 | && git config --global pull.ff only \ 33 | && git clone --depth=1 -b master https://github.com/MoeNetwork/Tieba-Cloud-Sign $WORKDIR \ 34 | && sed -i 's/dl-cdn.alpinelinux.org/mirrors.bfsu.edu.cn/' /etc/apk/repositories 35 | COPY s6-overlay / 36 | WORKDIR $WORKDIR 37 | ENTRYPOINT ["/init"] -------------------------------------------------------------------------------- /tieba-cloud-sign/buildx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | repo="nevinee/tieba-cloud-sign" 4 | arch="linux/386,linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/ppc64le,linux/s390x" 5 | ver=$(curl -s https://raw.githubusercontent.com/MoeNetwork/Tieba-Cloud-Sign/master/init.php | grep "'SYSTEM_VER'" | awk -F "'" '{print $4}') 6 | alpine_ver=${1:-latest} 7 | 8 | buildx() { 9 | docker pull tonistiigi/binfmt 10 | docker run --privileged --rm tonistiigi/binfmt --install all 11 | docker buildx create --name builder --use 2>/dev/null || docker buildx use builder 12 | docker buildx inspect --bootstrap 13 | docker buildx build \ 14 | --cache-from "type=local,src=/tmp/.buildx-cache" \ 15 | --cache-to "type=local,dest=/tmp/.buildx-cache" \ 16 | --build-arg "ALPINE_VERSION=$alpine_ver" \ 17 | --platform "$arch" \ 18 | --tag ${repo}:${ver} \ 19 | --tag ${repo}:latest \ 20 | --push \ 21 | . 22 | docker pushrm $repo # https://github.com/christian-korneck/docker-pushrm 23 | } 24 | 25 | if [[ $ver ]]; then 26 | [[ ! -d logs ]] && mkdir logs 27 | echo "alpine_ver=${1:-latest}" 28 | buildx 2>&1 | ts "[%Y-%m-%d %H:%M:%.S]" | tee -a logs/${ver}.log 29 | else 30 | echo "未获取到最新版本号" 31 | fi 32 | -------------------------------------------------------------------------------- /tieba-cloud-sign/readme.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 官方镜像也是本人维护的,现在可以直接使用官方镜像。https://hub.docker.com/r/moenetwork/tieba-cloud-sign 4 | 5 | ## 创建 6 | 7 | `docker-compose.yml`文件如下,**除了镜像名称不同外,其余同 [官方教程](https://github.com/MoeNetwork/Tieba-Cloud-Sign) 一致。** 8 | 9 | 创建好后访问`http://:8080`进行下一步操作。 10 | 11 | ``` 12 | version: "2.0" 13 | services: 14 | web: 15 | image: nevinee/tieba-cloud-sign # 本镜像名称 16 | container_name: tieba 17 | restart: always 18 | hostname: tieba 19 | environment: 20 | - PUID=1000 # 可修改为你想以什么用户运行caddy,该用户的UID 21 | - PGID=1000 # 可修改为你想以什么用户运行caddy,该用户的UID 22 | - DB_HOST=db:3306 23 | - DB_USER=root 24 | - DB_PASSWD=janejane123456 # 数据库密码 25 | - DB_NAME=tiebacloud # 数据库名 26 | - CSRF=true 27 | - CRON_TASK=* * * * * # 执行do.php的cron,默认每分钟执行,明白这是何含义的可以自己改 28 | ports: 29 | - 8080:8080 30 | links: 31 | - db 32 | depends_on: 33 | - db 34 | #security_opt: # armv7设备请解除这两行注释 35 | #- seccomp=unconfined 36 | 37 | db: 38 | image: agrozyme/mariadb #如若此镜像在你的平台上不可用,可以自行在docker hub上搜索你平台可用的mariadb镜像 39 | environment: 40 | - MYSQL_DATABASE=tiebacloud 41 | - MYSQL_ROOT_PASSWORD=janejane123456 42 | volumes: 43 | - ./mysql:/var/lib/mysql 44 | ``` 45 | 46 | [mysql官方镜像](https://hub.docker.com/_/mysql) 可用平台:`amd64`。 47 | 48 | [mariadb官方镜像](https://hub.docker.com/_/mariadb) 可用平台:`amd64` `arm64` `ppc64le`。 49 | 50 | [agrozyme/mariadb镜像](https://hub.docker.com/r/agrozyme/mariadb) 可用平台:`amd64` `386` `arm64` `arm/v7` `arm/v6` `ppc64le` `s390x`。 51 | 52 | ## 关于armv7设备的补充说明 53 | 54 | armv7设备如若无法使用网络,可能是seccomp问题,详见 [这里](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.13.0)。 55 | 56 | 解决办法如下: 57 | 58 | - docker cli方式可以在创建命令中增加一行`--security-opt seccomp=unconfined \`。 59 | 60 | - docker-compose方式请在`docker-compose.yml`最后增加两行: 61 | 62 | ``` 63 | security_opt: 64 | - seccomp=unconfined 65 | ``` 66 | 67 | ## Dockerfile 68 | 69 | https://gitee.com/evine/dockerfiles/tree/master/tieba-cloud-sign 70 | 71 | https://github.com/devome/dockerfiles/tree/master/tieba-cloud-sign 72 | 73 | [![dockeri.co](http://dockeri.co/image/nevinee/tieba-cloud-sign)](https://hub.docker.com/r/nevinee/tieba-cloud-sign/) -------------------------------------------------------------------------------- /tieba-cloud-sign/s6-overlay/etc/cont-init.d/10-fix-owner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | fix_owner() { 4 | PUID=${PUID:-1000} 5 | PGID=${PGID:-1000} 6 | echo "Change $WORKDIR owner to user caddy..." 7 | echo "PUID=${PUID}" 8 | echo "PGID=${PGID}" 9 | groupmod -o -g "$PGID" caddy 10 | usermod -o -u "$PUID" caddy 11 | chown -R caddy:caddy $WORKDIR 12 | } 13 | 14 | fix_owner 2>&1 | sed "s#^#[cont-init.d] $(basename $0): \1#g" 15 | -------------------------------------------------------------------------------- /tieba-cloud-sign/s6-overlay/etc/cont-init.d/20-fix-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | fix_config() { 4 | DB_HOST=${DB_HOST:-127.0.0.1} 5 | DB_USER=${DB_USER:-root} 6 | DB_NAME=${DB_NAME:-tiebacloud} 7 | CSRF=${CSRF:-true} 8 | 9 | file_config=$WORKDIR/config.php 10 | 11 | echo "Modify $WORKDIR/config.php to the value set by the user..." 12 | sed -i ''"$(cat $file_config -n | grep "DB_HOST" | awk '{print $1}')"'c '"$(echo "define('DB_HOST','${DB_HOST}');")"'' $file_config 13 | sed -i ''"$(cat $file_config -n | grep "DB_USER" | awk '{print $1}')"'c '"$(echo "define('DB_USER','${DB_USER}');")"'' $file_config 14 | sed -i ''"$(cat $file_config -n | grep "DB_PASSWD" | awk '{print $1}')"'c '"$(echo "define('DB_PASSWD','${DB_PASSWD}');")"'' $file_config 15 | sed -i ''"$(cat $file_config -n | grep "DB_NAME" | awk '{print $1}')"'c '"$(echo "define('DB_NAME','${DB_NAME}');")"'' $file_config 16 | sed -i ''"$(cat $file_config -n | grep "ANTI_CSRF" | awk '{print $1}')"'c '"$(echo "define('ANTI_CSRF',"${CSRF}");")"'' $file_config 17 | } 18 | 19 | fix_config 2>&1 | sed "s#^#[cont-init.d] $(basename $0): \1#g" 20 | -------------------------------------------------------------------------------- /tieba-cloud-sign/s6-overlay/etc/cont-init.d/30-set-crontab: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | set_crontab() { 4 | echo "Set crontab to system..." 5 | echo -e "${CRON_TASK} php $WORKDIR/do.php" | s6-setuidgid caddy crontab - 6 | } 7 | 8 | set_crontab 2>&1 | sed "s#^#[cont-init.d] $(basename $0): \1#g" 9 | -------------------------------------------------------------------------------- /tieba-cloud-sign/s6-overlay/etc/services.d/caddy/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | exec s6-setuidgid caddy caddy run -config /etc/caddy/Caddyfile 4 | -------------------------------------------------------------------------------- /tieba-cloud-sign/s6-overlay/etc/services.d/crond/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | exec crond -f 4 | -------------------------------------------------------------------------------- /tieba-cloud-sign/s6-overlay/etc/services.d/php-fpm/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | exec php-fpm8 4 | --------------------------------------------------------------------------------