From eb69a3efc3bedc181ece982c84b54897cea8a3dd Mon Sep 17 00:00:00 2001 From: Xavier Rubio Jansana Date: Mon, 26 May 2025 23:32:43 +0200 Subject: [PATCH 1/6] Rewrite the Dockerfile to use Alpine Linux --- Dockerfile | 21 +++++++-------------- start.sh | 31 ------------------------------- 2 files changed, 7 insertions(+), 45 deletions(-) delete mode 100644 start.sh diff --git a/Dockerfile b/Dockerfile index 7642703..e3dac55 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,10 @@ -FROM arm32v7/ubuntu:14.04 +FROM alpine:3.21.3 -RUN apt-get update \ - && apt-get install -y openssh-server bash git vim lighttpd libcgi-pm-perl busybox-syslogd \ - && rm -rf /var/lib/apt/lists/* \ - && rm /etc/update-motd.d/* \ - && addgroup --gid 1000 git \ - && adduser --home /home/git --shell /bin/bash --uid 1000 --gid 1000 --gecos "" --disabled-password git \ - && mkdir /var/run/sshd \ - && /usr/bin/ssh-keygen -A \ - && rm /etc/pam.d/sshd +RUN apk add --no-cache openssh-server git \ + && addgroup -g 1000 git \ + && adduser -h /home/git -s /bin/bash -u 1000 -G git -g "" -D git \ + && /usr/bin/ssh-keygen -A -ADD start.sh /start.sh +EXPOSE 22 -EXPOSE 22 1234 - -CMD ["/start.sh"] +CMD ["/usr/sbin/sshd", "-D"] diff --git a/start.sh b/start.sh deleted file mode 100644 index 05c44a0..0000000 --- a/start.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -echo "Verifying configuration..." - -if [ "$(stat -c %a%u%g /home/git)" != "70010001000" ]; then - echo "User git does not have valid homedir !" - echo "Dump /home/" - ls -alh /home/ - exit 1 -fi - -if [ "$(stat -c %a%u%g /home/git/.ssh)" != "70010001000" ]; then - echo "User git does not have valid ~/.ssh !" - echo "Dump /home/git/" - ls -alh /home/git/ - exit 1 -fi - -if [ "$(stat -c %a%u%g /home/git/.ssh/authorized_keys)" != "60010001000" ]; then - echo "User git does not have valid ~/.ssh/authorized_keys !" - echo "Dump ~/.ssh/" - ls -alh /home/git/.ssh/ - exit 1 -fi - -if [ ! -e "/pub" ]; then - ln -s /home/git/pub /pub -fi - -echo "Start ssh server" -/usr/sbin/sshd -D From 15242593caac977e9aff534894d58382c536129d Mon Sep 17 00:00:00 2001 From: Xavier Rubio Jansana Date: Mon, 26 May 2025 23:33:31 +0200 Subject: [PATCH 2/6] GitHub Actions --- .github/workflows/build-and-publish.yml | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/build-and-publish.yml diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml new file mode 100644 index 0000000..54d1547 --- /dev/null +++ b/.github/workflows/build-and-publish.yml @@ -0,0 +1,46 @@ +name: Build and Push Docker Image + +on: + push: + tags: + - 'v*.*.*' + +env: + IMAGE_NAME: xrubioj/qnap-git-server + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Extract version from tag + id: extract_version + run: | + echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: all + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_PAT }} + + - name: Build and push multi-platform image + uses: docker/build-push-action@v5 + with: + context: . + push: true + platforms: linux/amd64,linux/386,linux/arm/v7,linux/arm64 + tags: | + ${{ env.IMAGE_NAME }}:${{ steps.extract_version.outputs.TAG_NAME }} + ${{ env.IMAGE_NAME }}:latest From 34919a8accbafe4e3c6f28697bb3f2392095b371 Mon Sep 17 00:00:00 2001 From: Xavier Rubio Jansana Date: Mon, 26 May 2025 23:33:45 +0200 Subject: [PATCH 3/6] Update README.md --- README.md | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d50103e..1cb102a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ Host your own Git repositories on QNAP server ## Introduction -QNAP is a linux-based Network Attached Storage. It has a lot of nice features but there is no option for hosting git repositories by default. Fortunately there is an application named _Container Station_ which allows you to run Docker or LXC images. So it’s pretty easy to extend functions and for example install _GitLab_ to host git repositories (it’s QNAP recommendation). _Gitlab_ is a quite big system and if you need a just simple git server you can use this [qnap-git-server](https://github.com/tomplus/qnap-git-server). +QNAP is a linux-based Network Attached Storage. It has a lot of nice features but there is no option for hosting git repositories by default. Fortunately there is an application named _Container Station_ which allows you to run Docker or LXC images. So it’s pretty easy to extend functions and for example install _GitLab_ to host git repositories (it’s QNAP recommendation). _Gitlab_ is a quite big system and if you need a just simple git server you can use this [xrubioj/qnap-git-server](https://github.com/xrubioj/qnap-git-server). + +This project is based on the unmaintained [tomplus/qnap-git-server](https://github.com/tomplus/qnap-git-server), but it has been rewritten from the scratch to use a more lightweight alternative (Alpine Linux). Also, it builds images for Intel/AMD and ARM CPUs. ## Instalation @@ -22,7 +24,7 @@ $ ssh admin@my-qnap.local [/share] chmod 600 git/.ssh/authorized_keys ``` -Now you can use _Container Station_ to start the image [tpimages/qnap-git-server](https://hub.docker.com/r/tpimages/qnap-git-server/). This image is prepared for arm32v7 only. +Now you can use _Container Station_ to start the image [xrubioj/qnap-git-server](https://hub.docker.com/r/xrubioj/qnap-git-server/). This image is prepared for linux/amd64, linux/386, linux/arm/v7 (32 bits) and linux/arm64. You have to mount prepared directory as /home/git and expose port 22 as for example 2222 to connect it from your local network. You can also start it from command line: ``` @@ -61,15 +63,3 @@ If you store there only one key, ensure that there are not additional new lines To check logs from syslogd you can use command `docker exec` to run `syslogd`. It'll start the deamon syslogd and all logs will be writting to /var/log/messages. - -If you get errors like `exec user process caused "exec format error"` it means that your qnap -has different architecture (eg. amd64) than the prepared image (arm32v7). It this case try to replace -the base image in `Dockerfile` from -``` -FROM arm32v7/ubuntu:14.04 -``` -to for example: -``` -FROM amd64/ubuntu:14.04 -``` -and build your own image. From 7183204a923fcf5b32f81ba83d32dfffdf5f0277 Mon Sep 17 00:00:00 2001 From: Xavier Rubio Jansana Date: Tue, 27 May 2025 14:30:10 +0200 Subject: [PATCH 4/6] Fix git user creation --- Dockerfile | 3 ++- README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index e3dac55..b2828af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,8 @@ FROM alpine:3.21.3 RUN apk add --no-cache openssh-server git \ && addgroup -g 1000 git \ - && adduser -h /home/git -s /bin/bash -u 1000 -G git -g "" -D git \ + && adduser -h /home/git -s /bin/sh -u 1000 -G git -g "" -D git \ + && passwd -d git \ && /usr/bin/ssh-keygen -A EXPOSE 22 diff --git a/README.md b/README.md index 1cb102a..68c6a32 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Initialized empty Git repository in /home/git/pub/project.git/ and then you can clone the repository ``` -$ git clone ssh://git@my-qnap.local:2222/pub/project.git +$ git clone ssh://git@my-qnap.local:2222/home/git/pub/project.git ``` From f10f03adc67d2b6367a566d0ea9f147a0d1d7b9c Mon Sep 17 00:00:00 2001 From: Xavier Rubio Jansana Date: Wed, 28 May 2025 23:04:11 +0200 Subject: [PATCH 5/6] Update LICENSE --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index 5aa0003..81f26eb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2018 Tomasz Prus +Copyright (c) 2025 Xavier Rubio Jansana Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From b926948754b2cbb192bef85421563fbc5341913b Mon Sep 17 00:00:00 2001 From: Xavier Rubio Jansana Date: Tue, 30 Sep 2025 23:18:21 +0200 Subject: [PATCH 6/6] Automate the configuration process Summary: Test Plan: --- Dockerfile | 1 + README.md | 40 +++++++++++++++++++++++++++++++++------- init.sh | 24 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100755 init.sh diff --git a/Dockerfile b/Dockerfile index b2828af..4362ea2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ RUN apk add --no-cache openssh-server git \ && addgroup -g 1000 git \ && adduser -h /home/git -s /bin/sh -u 1000 -G git -g "" -D git \ && passwd -d git \ + && ln -s /home/git/pub /pub \ && /usr/bin/ssh-keygen -A EXPOSE 22 diff --git a/README.md b/README.md index 68c6a32..f78f69c 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,22 @@ Host your own Git repositories on QNAP server QNAP is a linux-based Network Attached Storage. It has a lot of nice features but there is no option for hosting git repositories by default. Fortunately there is an application named _Container Station_ which allows you to run Docker or LXC images. So it’s pretty easy to extend functions and for example install _GitLab_ to host git repositories (it’s QNAP recommendation). _Gitlab_ is a quite big system and if you need a just simple git server you can use this [xrubioj/qnap-git-server](https://github.com/xrubioj/qnap-git-server). -This project is based on the unmaintained [tomplus/qnap-git-server](https://github.com/tomplus/qnap-git-server), but it has been rewritten from the scratch to use a more lightweight alternative (Alpine Linux). Also, it builds images for Intel/AMD and ARM CPUs. +This project is based on [tomplus/qnap-git-server](https://github.com/tomplus/qnap-git-server), but it has been rewritten from the scratch to use a more lightweight alternative (Alpine Linux). Also, it builds images for Intel/AMD and ARM CPUs. ## Instalation First, you have to prepare a directory which will be attached to Docker. This directory has to contain your ssh public key and it is also a place where your repositories will be stored. +You can use the following script: + +``` +$ ./init.sh @ +# e.g. +$ ./init.sh admin@my-qnap.local ~/.ssh/id_rsa.pub +``` + +Alternatively, you can run the steps manually by `ssh`ing to your QNAP box as `admin` and manually running the commands like so: + ``` $ ssh admin@my-qnap.local [~] cd /share @@ -31,22 +41,39 @@ You have to mount prepared directory as /home/git and expose port 22 as for exam [~] docker run -d -v /share/git:/home/git -p 2222:22 --rm tpimages/qnap-git-server:latest ``` +## Accessing git repositories from your home directory + +You can link your `pub` directory to be visible from your QNAP user's home directory. In my case: + +``` +$ ssh -p 2222 git@my-qnap.local + +# Confirm where /share/homes point to +[~] ls -l /share/homes +lrwxrwxrwx 1 admin administrators 23 2024-08-16 09:25 /share/homes -> CE_CACHEDEV1_DATA/homes/ + +# Link /share/git to git directory in your user network share (based on the result of the previous ls command) +[~] ln -s /share/git/ /share/CE_CACHEDEV1_DATA/homes/my_user/git +``` + +## Creating your first repository + Now your server is up and running. You can connect to it via SSH to create a bare repository: ``` $ ssh -p 2222 git@my-qnap.local -$ mkdir pub/project.git -$ cd pub/project.git/ -$ git init --bare +[~] mkdir pub/project.git +[~] cd pub/project.git/ +[~] git init --bare Initialized empty Git repository in /home/git/pub/project.git/ ``` -and then you can clone the repository +and then you can clone the repository: + ``` $ git clone ssh://git@my-qnap.local:2222/home/git/pub/project.git ``` - ## Building If you want to build you own custom version of this image your can do it simple by docker build command: @@ -55,7 +82,6 @@ If you want to build you own custom version of this image your can do it simple docker build -t qnap-git-server:my-own-version . ``` - ## Troubleshooting Structure of file `git/.ssh/authorized_keys` requires that each key is stored in separate lines. diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..0d6268e --- /dev/null +++ b/init.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +if [ "$#" -ne 2 ]; then + echo "Initializes the required environment in your QNAP NAS." + echo "Requires admin access." + echo + echo "Usage: $0 @ " + echo " e.g.: $0 admin@my-qnap.local ~/.ssh/id_rsa.pub" + exit 1 +fi + +public_key=$(cat "$2") + +embedded_script="cd /share && +mkdir -p git/.ssh && +mkdir -p git/pub && +echo \"$public_key\" > git/.ssh/authorized_keys && +chown 1000:1000 -R git/ && +chmod 700 git/ && +chmod 700 git/.ssh/ && +chmod 600 git/.ssh/authorized_keys" + +output=$(ssh "$1" -v -t "/bin/sh" "-c" "'$embedded_script'" 2>&1) +echo $output