├── .github ├── renovate.json └── workflows │ ├── docker-image.yml │ └── renovate_config_validator.yml ├── Dockerfile ├── LICENSE ├── README.md ├── compose-test.yaml ├── run └── run-test.sh /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | 4 | "extends": [ 5 | "github>nabeken/renovate-config-oss", 6 | "github>nabeken/renovate-config-oss:recommended", 7 | "github>nabeken/renovate-config-oss:groupGoVersionUpgrade", 8 | "github>nabeken/renovate-config-oss:githubLocalActionsDefaultVersions", 9 | "github>nabeken/renovate-config-oss:groupGithubActions", 10 | 11 | "docker:enableMajor", 12 | "docker:pinDigests" 13 | ], 14 | 15 | "packageRules": [ 16 | { 17 | "matchUpdateTypes": ["digest"], 18 | "matchManagers": ["dockerfile"], 19 | "matchPackageNames": [ 20 | "/^debian$/" 21 | ], 22 | "automerge": true 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | push: 7 | branches: 8 | - master 9 | 10 | env: 11 | DOCKER_TEST_TAG: action-local-test 12 | IMAGE_NAME: docker-volume-container-rsync 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 20 | 21 | - name: Docker meta 22 | uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5 23 | id: meta 24 | with: 25 | # list of Docker images to use as base name for tags 26 | images: | 27 | ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} 28 | 29 | # generate Docker tags based on the following events/attributes 30 | tags: | 31 | type=ref,event=branch 32 | type=ref,event=pr 33 | type=semver,pattern={{version}} 34 | type=semver,pattern={{major}}.{{minor}} 35 | # set latest tag for default branch 36 | type=raw,value=latest,enable={{is_default_branch}} 37 | 38 | - name: Set up QEMU 39 | uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3 40 | 41 | - name: Set up Docker Buildx 42 | uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3 43 | 44 | - name: Build for the test 45 | uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6 46 | with: 47 | context: . 48 | load: true 49 | tags: ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ env.DOCKER_TEST_TAG }} 50 | 51 | - name: Test 52 | run: | 53 | ./run-test.sh 54 | 55 | - name: Login to GHCR 56 | if: github.event_name != 'pull_request' 57 | uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 58 | with: 59 | registry: ghcr.io 60 | username: ${{ github.repository_owner }} 61 | password: ${{ secrets.GITHUB_TOKEN }} 62 | 63 | - name: Build and push 64 | uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6 65 | with: 66 | push: ${{ github.event_name != 'pull_request' }} 67 | platforms: linux/amd64,linux/arm64 68 | tags: ${{ steps.meta.outputs.tags }} 69 | labels: ${{ steps.meta.outputs.labels }} 70 | -------------------------------------------------------------------------------- /.github/workflows/renovate_config_validator.yml: -------------------------------------------------------------------------------- 1 | name: renovate-config-validator 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | - master 8 | push: 9 | branches: 10 | - main 11 | - master 12 | 13 | jobs: 14 | validate: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 18 | - name: Validate the config 19 | uses: suzuki-shunsuke/github-action-renovate-config-validator@c22827f47f4f4a5364bdba19e1fe36907ef1318e # v1.1.1 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:12@sha256:bd73076dc2cd9c88f48b5b358328f24f2a4289811bd73787c031e20db9f97123 2 | MAINTAINER TANABE Ken-ichi 3 | 4 | SHELL ["/bin/bash" , "-c"] 5 | 6 | RUN set -euxo pipefail; \ 7 | apt-get update; \ 8 | apt-get upgrade -y; \ 9 | apt-get install -y --no-install-recommends rsync; \ 10 | rm -rf /var/lib/apt/lists/* 11 | 12 | EXPOSE 873 13 | VOLUME /docker 14 | ADD ./run /usr/local/bin/run 15 | 16 | ENTRYPOINT ["/usr/local/bin/run"] 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 TANABE Ken-ichi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-volume-container-rsync 2 | [![Docker Image CI](https://github.com/nabeken/docker-volume-container-rsync/actions/workflows/docker-image.yml/badge.svg)](https://github.com/nabeken/docker-volume-container-rsync/actions/workflows/docker-image.yml) 3 | 4 | `docker-volume-container-rsync` is to provide RSYNC access to a mounted volume. You can synchronize your local file over RSYNC into a container volume very fast. 5 | 6 | ## News (as of Dec 2, 2022) 7 | 8 | I've moved to GHCR (Github Container Registery) and a new repository provides multi-arch images for Linux/amd64 and Linux/arm64. 9 | 10 | I'll not remove old images but please migrate to the new location. 11 | 12 | ## Usage 13 | 14 | First, you can launch a volume container exposing a volume with rsync. 15 | 16 | ```sh 17 | CID=$(docker run -d -p 10873:873 ghcr.io/nabeken/docker-volume-container-rsync:latest) 18 | ``` 19 | 20 | You can connect to rsync server inside a container like this: 21 | 22 | ```sh 23 | rsync rsync://:10873/ 24 | volume docker volume 25 | ``` 26 | 27 | To sync: 28 | 29 | ```sh 30 | rsync -avP /path/to/dir rsync://:10873/volume/ 31 | ``` 32 | 33 | Next, you can launch a container connected with the volume under `/docker`. 34 | 35 | ```sh 36 | docker run -it --volumes-from $CID ubuntu /bin/sh 37 | ``` 38 | 39 | ## Advanced 40 | 41 | In default, rsync server accepts a connection only from `192.168.0.0/16` and `172.16.0.0/12` for security reasons. 42 | You can override via an environment variable like this: 43 | 44 | ```sh 45 | docker run -d -p 10873:873 -e ALLOW='10.0.0.0/8 x.x.x.x/y' ghcr.io/nabeken/docker-volume-container-rsync:latest 46 | ``` 47 | 48 | ## Using with different directory 49 | 50 | Let's say you want to use `/data` rather than `/docker`. 51 | 52 | First, you must launch a volume container exposing `/data` directory: 53 | 54 | ```sh 55 | CID=$(docker run --volume /data -d -e VOLUME=/data -p 10873:873 ghcr.io/nabeken/docker-volume-container-rsync:latest) 56 | ``` 57 | 58 | Finally, you can mount the volumes from the container: 59 | 60 | ```sh 61 | docker run -it --volumes-from $CID ubuntu /bin/sh 62 | ``` 63 | -------------------------------------------------------------------------------- /compose-test.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | rsync: 3 | image: ghcr.io/nabeken/docker-volume-container-rsync:action-local-test 4 | volumes: 5 | - vol:/volume 6 | ports: 7 | - "10873:873" 8 | 9 | volumes: 10 | vol: 11 | -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | VOLUME=${VOLUME:-/docker} 3 | ALLOW=${ALLOW:-192.168.0.0/16 172.16.0.0/12} 4 | OWNER=${OWNER:-nobody} 5 | GROUP=${GROUP:-nogroup} 6 | 7 | chown "${OWNER}:${GROUP}" "${VOLUME}" 8 | 9 | [ -f /etc/rsyncd.conf ] || cat < /etc/rsyncd.conf 10 | uid = ${OWNER} 11 | gid = ${GROUP} 12 | use chroot = yes 13 | log file = /dev/stdout 14 | reverse lookup = no 15 | 16 | [volume] 17 | hosts deny = * 18 | hosts allow = ${ALLOW} 19 | read only = false 20 | path = ${VOLUME} 21 | comment = docker volume 22 | EOF 23 | 24 | exec /usr/bin/rsync --no-detach --daemon --config /etc/rsyncd.conf "$@" 25 | -------------------------------------------------------------------------------- /run-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | die() { 3 | echo "NOT OK: ${@}" >&2 4 | exit 1 5 | } 6 | 7 | ok() { 8 | echo "OK: ${@}" >&2 9 | } 10 | 11 | RSYNC_HOST=rsync://127.0.0.1:10873 12 | 13 | echo "Running the tests..." 14 | 15 | docker compose -f compose-test.yaml up -d || die "unable to launch" 16 | 17 | sleep 3 18 | 19 | rsync "${RSYNC_HOST}"/volume/ > /dev/null || die "unable to connect" 20 | 21 | T1=$(mktemp) 22 | trap "rm -f ${T1}" EXIT 23 | 24 | echo "hello" > "${T1}" 25 | 26 | rsync "${T1}" "${RSYNC_HOST}"/volume/ || die "unable to copy" 27 | 28 | F1=$(rsync "${RSYNC_HOST}"/volume/ | grep $(basename "${T1}")) 29 | if [ -z "${F1}" ]; then 30 | die "file doesn't exist" 31 | else 32 | echo "${F1}" 33 | ok "file exists!" 34 | fi 35 | 36 | T2=$(mktemp) 37 | trap "rm -f ${T2}" EXIT 38 | 39 | rsync "${RSYNC_HOST}"/volume/"$(basename ${T1})" "${T2}" 40 | 41 | if [ "$(cat ${T1})" = "$(cat ${T2})" ]; then 42 | ok "content is same" 43 | else 44 | die "content isn't same" 45 | fi 46 | 47 | docker compose -f compose-test.yaml down || die "unable to terminate" 48 | --------------------------------------------------------------------------------