Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Build and Push Multi-Arch Docker Image

on:
push:
branches:
- master
tags:
- 'v*.*.*'
pull_request:
branches:
- master

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
*.iml
out
gen

# AI files
.claude
15 changes: 7 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM alpine:3.4
FROM alpine:3.22

MAINTAINER Carlos Bernárdez "carlos@z4studios.com"
LABEL maintainer="Carlos Bernárdez <carlos@z4studios.com>"

# "--no-cache" is new in Alpine 3.3 and it avoid using
# "--update + rm -rf /var/cache/apk/*" (to remove cache)
Expand All @@ -18,12 +18,11 @@ RUN ssh-keygen -A

WORKDIR /git-server/

# -D flag avoids password generation
# -s flag changes user's shell
RUN mkdir /git-server/keys \
&& adduser -D -s /usr/bin/git-shell git \
&& echo git:12345 | chpasswd \
&& mkdir /home/git/.ssh
# PUID and PGID for configurable user/group IDs (Docker convention)
ENV PUID=1000 PGID=1000

# Create directories (user creation deferred to start.sh for PUID/PGID support)
RUN mkdir /git-server/keys

# This is a login shell for SSH accounts to provide restricted Git access.
# It permits execution only of server-side Git commands implementing the
Expand Down
56 changes: 52 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
# git-server-docker
A lightweight Git Server Docker image built with Alpine Linux. Available on [GitHub](https://github.com/jkarlosb/git-server-docker) and [Docker Hub](https://hub.docker.com/r/jkarlos/git-server-docker/)
A lightweight Git Server Docker image built with Alpine Linux. Available on [GitHub](https://github.com/mwulffn/git-server-docker) and [GitHub Container Registry](https://github.com/mwulffn/git-server-docker/pkgs/container/git-server-docker)

!["image git server docker" "git server docker"](https://raw.githubusercontent.com/jkarlosb/git-server-docker/master/git-server-docker.jpg)

## Features

- **Multi-Architecture Support**: Supports both `linux/amd64` and `linux/arm64` platforms
- **Configurable UID/GID**: Use `PUID` and `PGID` environment variables to match your host user (default: 1000)
- **Automated Builds**: GitHub Actions automatically builds and pushes multi-arch images on every commit and tag
- **Alpine Linux**: Lightweight and secure base image

### Basic Usage

How to run the container in port 2222 with two volumes: keys volume for public keys and repos volume for git repositories:

$ docker run -d -p 2222:22 -v ~/git-server/keys:/git-server/keys -v ~/git-server/repos:/git-server/repos jkarlos/git-server-docker
$ docker run -d -p 2222:22 -v ~/git-server/keys:/git-server/keys -v ~/git-server/repos:/git-server/repos ghcr.io/mwulffn/git-server-docker:latest

#### With Custom UID/GID

To avoid permission issues with mounted volumes, match the container's git user UID/GID with your host user:

$ docker run -d -p 2222:22 \
-e PUID=1001 \
-e PGID=1001 \
-v ~/git-server/keys:/git-server/keys \
-v ~/git-server/repos:/git-server/repos \
ghcr.io/mwulffn/git-server-docker:latest

Find your host UID/GID with: `id -u` and `id -g`

How to use a public key:

Expand Down Expand Up @@ -52,6 +72,9 @@ How clone a repository:
* **Volumes**:
* */git-server/keys*: Volume to store the users public keys
* */git-server/repos*: Volume to store the repositories
* **Environment Variables**:
* `PUID`: User ID for the git user (default: 1000)
* `PGID`: Group ID for the git user (default: 1000)

### SSH Keys

Expand All @@ -65,12 +88,37 @@ How upload quickly a public key to host volume:

### Build Image

How to make the image:
#### Local Build (Single Architecture)

$ docker build -t git-server-docker .

#### Multi-Architecture Build

To build for multiple architectures (amd64 and arm64):

# Create buildx builder (first time only)
$ docker buildx create --name multiarch --use

# Build and push multi-arch image
$ docker buildx build --platform linux/amd64,linux/arm64 \
-t ghcr.io/mwulffn/git-server-docker:latest \
--push .

#### Automated Builds

This repository uses GitHub Actions to automatically build and push multi-arch images:
- **On push to master**: Builds and pushes with `latest` tag
- **On version tags** (e.g., `v1.0.0`): Builds and pushes with version tags

To trigger a new build, simply push to master or create a new tag:

$ git tag v1.0.0
$ git push origin v1.0.0

### Docker-Compose

You can edit docker-compose.yml and run this container with docker-compose:
You can edit docker-compose.yml and run this container with docker-compose. The compose file includes PUID/PGID configuration:

$ docker-compose up -d

The docker-compose.yml file includes environment variables for PUID/PGID. Uncomment and adjust them to match your host user to avoid permission issues with mounted volumes
9 changes: 8 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '2'
services:

git-server:
image: jkarlos/git-server-docker
image: ghcr.io/mwulffn/git-server-docker:latest
#build: .
restart: always
container_name: git-server
Expand All @@ -12,4 +12,11 @@ services:
volumes:
- ~/git-server/keys:/git-server/keys
- ~/git-server/repos:/git-server/repos
environment:
- PUID=1000
- PGID=1000
# Uncomment and adjust to match your host user's UID/GID to avoid permission issues
# You can find your UID/GID with: id -u and id -g
#- PUID=1001
#- PGID=1001

33 changes: 33 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
#!/bin/sh

# Create or update git user with configurable PUID/PGID
echo "Setting up git user with PUID=${PUID} and PGID=${PGID}"

# Create group if it doesn't exist
if ! getent group git > /dev/null 2>&1; then
addgroup -g ${PGID} git
else
# Update GID if it's different
CURRENT_GID=$(getent group git | cut -d: -f3)
if [ "${CURRENT_GID}" != "${PGID}" ]; then
groupmod -g ${PGID} git
fi
fi

# Create user if it doesn't exist
if ! id git > /dev/null 2>&1; then
adduser -D -u ${PUID} -G git -s /usr/bin/git-shell git
echo git:12345 | chpasswd
else
# Update UID if it's different
CURRENT_UID=$(id -u git)
if [ "${CURRENT_UID}" != "${PUID}" ]; then
usermod -u ${PUID} git
fi
# Ensure user is in correct group and has correct shell
usermod -g ${PGID} -s /usr/bin/git-shell git
fi

# Ensure home directory and .ssh directory exist with proper permissions
mkdir -p /home/git/.ssh
chown -R git:git /home/git
chmod 700 /home/git/.ssh

# If there is some public key in keys folder
# then it copies its contain in authorized_keys file
if [ "$(ls -A /git-server/keys/)" ]; then
Expand Down