├── .gitignore
├── data
└── example-config
│ ├── dav_svn.passwd
│ └── dav_svn.authz
├── files
├── dav_svn.conf
├── svn-backuper.sh
├── svn-project-creator.sh
└── svn-entrypoint.sh
├── docker-compose.yml
├── get-version.sh
├── Dockerfile
├── LICENSE
├── README.md
└── .github
└── workflows
└── docker-publish.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | data/data
--------------------------------------------------------------------------------
/data/example-config/dav_svn.passwd:
--------------------------------------------------------------------------------
1 | testuser:Subversion:5d1b8d8c9a69af4b0180cdafe09cb907
--------------------------------------------------------------------------------
/files/dav_svn.conf:
--------------------------------------------------------------------------------
1 |
2 | DAV svn
3 | SVNParentPath /var/local/svn/
4 | SVNListParentPath on
5 |
6 | AuthzSVNAccessFile /etc/apache2/dav_svn/dav_svn.authz
7 |
8 | Satisfy any
9 | Require valid-user
10 | AuthType Digest
11 | AuthName "Subversion"
12 | AuthUserFile /etc/apache2/dav_svn/dav_svn.passwd
13 |
14 |
--------------------------------------------------------------------------------
/files/svn-backuper.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # variables
4 | SVNDIR="/var/local/svn/"
5 | BACKUPDIR="/var/svn-backup"
6 |
7 | find $SVNDIR* -maxdepth 0 -type d | while IFS= read -r DIR
8 | do
9 | NAME=`expr match "$DIR" '.*\(/.*\)'`
10 | echo "svnadmin dump $DIR > $BACKUPDIR$NAME.dump"
11 | svnadmin dump $DIR > $BACKUPDIR$NAME.dump
12 | done
13 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.3'
2 |
3 | services:
4 |
5 | subversion:
6 | build: .
7 | image: ghcr.io/marvambass/subversion
8 | restart: always
9 | volumes:
10 | - ./data/data/backup:/var/local/svn
11 | - ./data/data/svn:/var/svn-backup
12 | - ./data/example-config:/etc/apache2/dav_svn/
13 | ports:
14 | - "8080:80"
--------------------------------------------------------------------------------
/data/example-config/dav_svn.authz:
--------------------------------------------------------------------------------
1 | [groups]
2 | admin = user1,user2, testuser
3 | devgroup = user5, user6
4 |
5 | [project1:/]
6 | @admin = rw
7 | @devgroup = r
8 |
9 | # devgroup members are able to read and write on project2
10 | [project2:/]
11 | @devgroup = rw
12 |
13 | # admins have control over every project - and can list all projects on the root point
14 | [/]
15 | @admin = rw
16 |
17 | # everybody is able to read repos and sees all projects
18 | [/]
19 | * = r
--------------------------------------------------------------------------------
/files/svn-project-creator.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # variables
4 | SVNDIR="/var/local/svn/"
5 |
6 | find $SVNDIR* -maxdepth 0 -type d | while IFS= read -r DIR
7 | do
8 | NAME=`expr match "$DIR" '.*\(/.*\)'`
9 |
10 | if [ -f "$DIR/README.txt" ] && [ `cat "$DIR/README.txt" | grep "This is a Subversion repository" | wc -l` -eq 1 ]
11 | then
12 | echo "$DIR is already a SVN Filesystem"
13 | else
14 | echo "creating new SVN Filesystem: $DIR"
15 | svnadmin create --fs-type fsfs "$DIR"
16 | chown -R www-data:www-data "$DIR"
17 | fi
18 | done
19 |
20 | chown -R www-data:www-data "$SVNDIR"
21 |
--------------------------------------------------------------------------------
/get-version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export IMG=$(docker build -q --pull --no-cache -t 'get-version' .)
3 |
4 | export DEBIAN_VERSION=$(docker run --rm -t get-version cat /etc/debian_version | tail -n1 | tr -d '\r')
5 | export SUBVERSION_VERSION=$(docker run --rm -t get-version dpkg --list subversion | grep '^ii' | sed 's/^[^0-9]*//g' | cut -d ' ' -f1 | sed 's/[+=:~]/_/g' | tr -d '\r')
6 | [ -z "$DEBIAN_VERSION" ] && exit 1
7 |
8 | export IMGTAG=$(echo "$1""d$DEBIAN_VERSION-s$SUBVERSION_VERSION")
9 | export IMAGE_EXISTS=$(docker pull "$IMGTAG" 2>/dev/null >/dev/null; echo $?)
10 |
11 | # return latest, if container is already available :)
12 | if [ "$IMAGE_EXISTS" -eq 0 ]; then
13 | echo "$1""latest"
14 | else
15 | echo "$IMGTAG"
16 | fi
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ghcr.io/servercontainers/apache2-ssl-secure
2 |
3 | ENV LANG C.UTF-8
4 |
5 | RUN apt-get update && apt-get install -y \
6 | subversion \
7 | libapache2-mod-svn
8 |
9 | RUN a2enmod dav_svn
10 | RUN a2enmod auth_digest
11 |
12 | RUN mkdir /var/svn-backup
13 | RUN mkdir -p /var/local/svn
14 | RUN mkdir /etc/apache2/dav_svn
15 |
16 | ADD files/dav_svn.conf /etc/apache2/mods-available/dav_svn.conf
17 |
18 | ADD files/svn-backuper.sh /usr/local/bin/
19 | ADD files/svn-project-creator.sh /usr/local/bin/
20 | ADD files/svn-entrypoint.sh /usr/local/bin/
21 |
22 | RUN chmod a+x /usr/local/bin/svn*
23 |
24 | RUN echo "*/10 * * * * root /usr/local/bin/svn-project-creator.sh" >> /etc/crontab
25 | RUN echo "0 0 * * * root /usr/local/bin/svn-backuper.sh" >> /etc/crontab
26 |
27 | RUN sed -i 's/# CMD/&\n echo "$@" | grep runit && svn-entrypoint.sh/g' /container/scripts/entrypoint.sh
28 |
29 | VOLUME ["/var/local/svn", "/var/svn-backup", "/etc/apache2/dav_svn"]
30 |
--------------------------------------------------------------------------------
/files/svn-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cat < /etc/apache2/dav_svn/dav_svn.authz
26 | # disable protection - everybody can do what he wants
27 | [/]
28 | * = rw
29 | EOF
30 | fi
31 |
32 | if [ ! -f /etc/apache2/dav_svn/dav_svn.passwd ]
33 | then
34 | echo "generating empty htpasswd file for svn users"
35 | echo "# no users in this htpasswd file" > /etc/apache2/dav_svn/dav_svn.passwd
36 | fi
37 |
38 | chown -R www-data:www-data "/var/local/svn/"
39 | cron -f &
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Marvin
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 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Subversion Container (ghcr.io/marvambass/subversion) based on secured Apache SSL PHP on debian:bullseye [x86 + arm]
2 | _maintained by MarvAmBass_
3 |
4 | ## What is it
5 |
6 | A Docker Subversion Apache2 Container (based on `ghcr.io/servercontainers/apache2-ssl-secure`).
7 |
8 | Features automatic daily dumps of your SVN Repos for Backup purposes.
9 |
10 | You can control the access of your Project with a htpasswd file in combination with a authz file.
11 |
12 | ## Build & Variants
13 |
14 | You can specify `DOCKER_REGISTRY` environment variable (for example `my.registry.tld`)
15 | and use the build script to build the main container and it's variants for _x86_64, arm64 and arm_
16 |
17 | You'll find all images tagged like `d11.2-s1.2.1-2.1` which means `d-s`.
18 | This way you can pin your installation/configuration to a certian version. or easily roll back if you experience any problems
19 | (don't forget to open a issue in that case ;D).
20 |
21 | To build a `latest` tag run `./build.sh release`
22 |
23 | ## Changelogs
24 |
25 | * 2023-03-22
26 | * github action to build container
27 | * implemented ghcr.io as new registry
28 | * added example config and `docker-compose.yml`
29 | * new baseimage `ghcr.io/servercontainers/apache2-ssl-secure`
30 |
31 |
32 | ## Creating a project
33 |
34 | You are able to create a new Project by simply adding a new Folder to your repository root directory (`/var/local/svn`).
35 | A cron running every 10 minutes will eventually pick it up.
36 |
37 | ## How to access your repository
38 |
39 | By defdault the repository is host on `/svn`, so for instance you can checkout `yourRepo` using `svn checkout http://yourDockerIp/svn/yourRepo`
40 |
41 |
42 | ## pre run configuration (optional)
43 |
44 | You may create the following two files. If you don't need access control you can just skip this step.
45 |
46 | Create authz file like this example:
47 |
48 | __$DAV_SVN_CONF/dav_svn.authz__
49 |
50 | ```
51 | [groups]
52 | admin = user1,user2, testuser
53 | devgroup = user5, user6
54 |
55 | [project1:/]
56 | @admin = rw
57 | @devgroup = r
58 |
59 | # devgroup members are able to read and write on project2
60 | [project2:/]
61 | @devgroup = rw
62 |
63 | # admins have control over every project - and can list all projects on the root point
64 | [/]
65 | @admin = rw
66 |
67 | # everybody is able to read repos and sees all projects
68 | [/]
69 | * = r
70 | ```
71 |
72 | __$DAV_SVN_CONF/dav_svn.passwd__
73 |
74 | To add a new User like 'testuser' with password 'test' use the following command
75 |
76 | ```
77 | htdigest -c $DAV_SVN_CONF/dav_svn.passwd Subversion testuser
78 | ```
79 |
80 | Or if you're to lazy, just use this line for your file (for testing only!)
81 |
82 | ```
83 | testuser:Subversion:5d1b8d8c9a69af4b0180cdafe09cb907
84 | ```
85 |
86 | ## Run the container
87 |
88 | ```
89 | docker run \
90 | -d \
91 | -v $SVN:/var/local/svn \
92 | -v $SVN_BACKUP:/var/svn-backup \
93 | -v $DAV_SVN_CONF/:/etc/apache2/dav_svn/ \
94 | --name subversion ghcr.io/marvambass/subversion
95 | ```
--------------------------------------------------------------------------------
/.github/workflows/docker-publish.yml:
--------------------------------------------------------------------------------
1 | name: Docker
2 |
3 | # This workflow uses actions that are not certified by GitHub.
4 | # They are provided by a third-party and are governed by
5 | # separate terms of service, privacy policy, and support
6 | # documentation.
7 |
8 | on:
9 | schedule:
10 | - cron: '0 0 * * 0' # weekly
11 | push:
12 | branches: [ "master" ]
13 | # Publish semver tags as releases.
14 | tags: [ 'v*.*.*' ]
15 | pull_request:
16 | branches: [ "master" ]
17 |
18 | env:
19 | # Use docker.io for Docker Hub if empty
20 | REGISTRY: ghcr.io
21 | # github.repository as /
22 | IMAGE_NAME: MarvAmBass/subversion
23 |
24 |
25 | jobs:
26 | build:
27 |
28 | runs-on: ubuntu-latest
29 | permissions:
30 | contents: read
31 | packages: write
32 | # This is used to complete the identity challenge
33 | # with sigstore/fulcio when running outside of PRs.
34 | id-token: write
35 |
36 | steps:
37 | - name: Checkout repository
38 | uses: actions/checkout@v3
39 |
40 | # Install the cosign tool except on PR
41 | # https://github.com/sigstore/cosign-installer
42 | - name: Install cosign
43 | if: github.event_name != 'pull_request'
44 | uses: sigstore/cosign-installer@f3c664df7af409cb4873aa5068053ba9d61a57b6 #v2.6.0
45 | with:
46 | cosign-release: 'v1.13.1'
47 |
48 |
49 | # Workaround: https://github.com/docker/build-push-action/issues/461
50 | - name: Setup Docker buildx
51 | uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
52 |
53 | # Login against a Docker registry except on PR
54 | # https://github.com/docker/login-action
55 | - name: Log into registry ${{ env.REGISTRY }}
56 | if: github.event_name != 'pull_request'
57 | uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
58 | with:
59 | registry: ${{ env.REGISTRY }}
60 | username: ${{ github.actor }}
61 | password: ${{ secrets.GITHUB_TOKEN }}
62 |
63 | # Extract metadata (tags, labels) for Docker
64 | # https://github.com/docker/metadata-action
65 | - name: Extract Docker metadata
66 | id: meta
67 | uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
68 | with:
69 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
70 |
71 | - name: Extract Docker Version Tag
72 | id: docker_version_tag
73 | run: |
74 | ./get-version.sh $(echo "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:" | tr '[:upper:]' '[:lower:]') | sed 's/^/tag=/g' >> $GITHUB_OUTPUT
75 |
76 | # Build and push Docker image with Buildx (don't push on PR)
77 | # https://github.com/docker/build-push-action
78 | - name: Build and push Docker image
79 | id: build-and-push
80 | uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
81 | with:
82 | context: .
83 | push: ${{ github.event_name != 'pull_request' }}
84 | tags: ${{ steps.docker_version_tag.outputs.tag }}
85 | platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
86 | labels: ${{ steps.meta.outputs.labels }}
87 | cache-from: type=gha
88 | cache-to: type=gha,mode=max
89 |
90 |
91 | # Sign the resulting Docker image digest except on PRs.
92 | # This will only write to the public Rekor transparency log when the Docker
93 | # repository is public to avoid leaking data. If you would like to publish
94 | # transparency data even for private images, pass --force to cosign below.
95 | # https://github.com/sigstore/cosign
96 | - name: Sign the published Docker image
97 | if: ${{ github.event_name != 'pull_request' }}
98 | env:
99 | COSIGN_EXPERIMENTAL: "true"
100 | # This step uses the identity token to provision an ephemeral certificate
101 | # against the sigstore community Fulcio instance.
102 | run: echo "${{ steps.meta.outputs.tags }}" | xargs -I {} cosign sign {}@${{ steps.build-and-push.outputs.digest }}
--------------------------------------------------------------------------------