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 diff --git a/Dockerfile b/Dockerfile index 7642703..4362ea2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,12 @@ -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/sh -u 1000 -G git -g "" -D git \ + && passwd -d git \ + && ln -s /home/git/pub /pub \ + && /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/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 diff --git a/README.md b/README.md index d50103e..f78f69c 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,24 @@ 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 [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 @@ -22,29 +34,46 @@ $ 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: ``` [~] 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/pub/project.git +$ 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: @@ -53,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. @@ -61,15 +89,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. 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 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