diff --git a/.gitignore b/.gitignore
index 7cc7f776ca7312f70a64210231bccd9517eec68e..714e3c31be7ca70bb942342f4590c2144a157c40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,7 +25,8 @@
 .LSOverride
 
 # Icon must end with two \r
-Icon

+Icon
+
 
 # Thumbnails
 ._*
@@ -105,3 +106,10 @@ $RECYCLE.BIN/
 
 # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
 
+.env
+docker-compose.yml
+Dockerfile
+
+custom/**
+
+!.keep
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ff08893a80a9e6172bcb469d12d8b7f1604a0419
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,86 @@
+.before-script-build: &before-script-build
+  - |
+    if [[ ! -z "$CI_BUILD_PLATFORMS" ]]; then
+      export OS_ARCH=`echo $CI_BUILD_PLATFORMS | tr ' ' '\n' | \
+      sed 's|\/||2' | sed 's|\/|-|' | tr '\n' ' '`
+    fi
+  - export CI_APP_REPO=${CI_APP_REPO:-$CI_REGISTRY_IMAGE}
+  - >
+    echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER
+    --password-stdin $CI_REGISTRY
+  - |
+    if [[ -z "$GIT_LFS_VERSION" ]]; then
+      export GIT_LFS_VERSION=`sed -n "s|GIT_LFS_VERSION=\(.*\)|\1|p" sample..env`
+    fi
+
+.build:
+  image: registry.gitlab.b-data.ch/docker/docker-buildx:latest
+  stage: build
+  services:
+    - docker:dind
+  variables:
+    DOCKER_DRIVER: overlay2
+    DOCKER_TLS_CERTDIR: "/certs"
+  before_script:
+    - *before-script-build
+
+build:version-linux-amd64:
+  extends: .build
+  tags:
+    - arch:amd64
+    - os:linux
+  script:
+    - >
+      docker build
+      --build-arg IMAGE
+      --build-arg GIT_LFS_VERSION
+      -t $CI_APP_REPO:$GIT_LFS_VERSION-linux-amd64
+      -f build.Dockerfile .
+    - |
+      docker push $CI_APP_REPO:$GIT_LFS_VERSION-linux-amd64
+  rules:
+    - if: $CI_COMMIT_BRANCH == "main" && $CI_BUILD_PLATFORMS =~ /(linux\/amd64)/
+      changes:
+        - build.Dockerfile
+        - sample..env
+
+build:version-linux-arm64v8:
+  extends: .build
+  tags:
+    - arch:arm64/v8
+    - os:linux
+  script:
+    - >
+      docker build
+      --build-arg IMAGE
+      --build-arg GIT_LFS_VERSION
+      -t $CI_APP_REPO:$GIT_LFS_VERSION-linux-arm64v8
+      -f build.Dockerfile .
+    - |
+      docker push $CI_APP_REPO:$GIT_LFS_VERSION-linux-arm64v8
+  rules:
+    - if: $CI_COMMIT_BRANCH == "main" && $CI_BUILD_PLATFORMS =~ /(linux\/arm64\/v8)/
+      changes:
+        - build.Dockerfile
+        - sample..env
+
+build-manifest:version-linux-multiarch:
+  extends: .build
+  stage: deploy
+  script:
+    - |
+      for i in $OS_ARCH; do
+        export CI_MANIFEST_LIST="$CI_MANIFEST_LIST $CI_APP_REPO:$GIT_LFS_VERSION-$i"
+      done
+    - |
+      docker manifest create $CI_APP_REPO:$GIT_LFS_VERSION $CI_MANIFEST_LIST
+      if echo $OS_ARCH | grep "linux-arm64v8" >/dev/null ; then
+        docker manifest annotate --variant v8 $CI_APP_REPO:$GIT_LFS_VERSION \
+          $CI_APP_REPO:$GIT_LFS_VERSION-linux-arm64v8
+      fi
+      docker manifest push $CI_APP_REPO:$GIT_LFS_VERSION
+  rules:
+    - if: $CI_COMMIT_BRANCH == "main"
+      changes:
+        - build.Dockerfile
+        - sample..env
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000000000000000000000000000000000..1dd899201772f033ff60c0e3021106f1006de465
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for
+moderation decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail
+address, posting via an official social media account, or acting as an
+appointed representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+<info@b-data.ch>. All complaints will be reviewed and investigated
+promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..34af33a0a6fc2586964850f4e1800fbf5340dcc1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+[![minimal-readme compliant](https://img.shields.io/badge/readme%20style-minimal-brightgreen.svg)](https://github.com/RichardLitt/standard-readme/blob/master/example-readmes/minimal-readme.md) [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) <a href="https://benz0li.b-data.io/donate?project=4"><img src="https://benz0li.b-data.io/donate/static/donate-with-fosspay.png" alt="Donate with fosspay"></a> <a href="https://liberapay.com/benz0li/donate"><img src="https://liberapay.com/assets/widgets/donate.svg" alt="Donate using Liberapay" height="20"></a>
+
+# Git LFS install
+
+[This project](https://gitlab.com/b-data/git-lfs/glfsi) is intended for system
+administrators who want to perform an installation of Git LFS on any Linux
+distribution.
+
+## Table of Contents
+
+*  [Prerequisites](#prerequisites)
+*  [Install](#install)
+*  [Usage](#usage)
+*  [Contributing](#contributing)
+*  [License](#license)
+
+## Prerequisites
+
+This projects requires an installation of docker and docker compose.
+
+### Docker
+
+To install docker, follow the instructions for your platform:
+
+*  [Install Docker Engine | Docker Documentation > Supported platforms](https://docs.docker.com/engine/install/#supported-platforms)
+*  [Post-installation steps for Linux](https://docs.docker.com/engine/install/linux-postinstall/)
+
+### Docker Compose
+
+*  [Install Docker Compose](https://docs.docker.com/compose/install/)
+
+## Install
+
+Clone the source code of this project:
+
+```bash
+git clone https://gitlab.com/b-data/git-lfs/glfsi.git
+```
+
+## Usage
+
+Change directory and make a copy of all `sample.` files:
+
+```bash
+cd glfsi
+
+for file in sample.*; do cp "$file" "${file#sample.}"; done;
+```
+
+In `.env`, set `GIT_LFS_VERSION` to the desired version of Git LFS
+(`<major>.<minor>.<patch>`) and `PREFIX` to the location, where you want the
+`git-lfs` programm to be installed (default: `/usr/local`).
+
+Then, create and start container _glfsi_ using options `--build` (_Build images
+before starting containers_) and `-V` (_Recreate anonymous volumes instead of
+retrieving data from the previous containers_):
+
+```bash
+docker-compose up --build -V
+```
+
+## Contributing
+
+PRs accepted.
+
+This project follows the
+[Contributor Covenant](https://www.contributor-covenant.org)
+[Code of Conduct](CODE_OF_CONDUCT.md).
+
+## License
+
+[MIT](LICENSE) © 2022 b-data GmbH
diff --git a/build.Dockerfile b/build.Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..6913041852ab27cc484b9f73704e057458c800df
--- /dev/null
+++ b/build.Dockerfile
@@ -0,0 +1,30 @@
+ARG IMAGE
+ARG PREFIX=/usr/local
+
+FROM ${IMAGE} as installer
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+ARG GIT_LFS_VERSION
+ARG PREFIX
+ARG MODE=install
+
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends \
+  curl \
+  ca-certificates
+
+COPY scripts/*.sh /usr/bin/
+
+RUN start.sh
+
+FROM ${IMAGE}
+
+LABEL org.opencontainers.image.licenses="MIT" \
+      org.opencontainers.image.source="https://gitlab.com/b-data/git-lfs/glfsi" \
+      org.opencontainers.image.vendor="b-data GmbH" \
+      org.opencontainers.image.authors="Olivier Benz <olivier.benz@b-data.ch>"
+
+ARG PREFIX
+
+COPY --from=installer ${PREFIX} ${PREFIX}
diff --git a/custom/.keep b/custom/.keep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/sample..env b/sample..env
new file mode 100644
index 0000000000000000000000000000000000000000..b1bf149f9cadcad4cda4be004a3347190dfe890c
--- /dev/null
+++ b/sample..env
@@ -0,0 +1,11 @@
+IMAGE=debian:bullseye
+
+# Git LFS version
+GIT_LFS_VERSION=3.2.0
+
+# Installation prefix
+PREFIX=/usr/local
+
+# Execution mode (default: install)
+# other: uninstall
+MODE=
diff --git a/sample.Dockerfile b/sample.Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..856a69f483b7e14c2720c8802f521d72a6a89a68
--- /dev/null
+++ b/sample.Dockerfile
@@ -0,0 +1,16 @@
+ARG IMAGE
+
+FROM ${IMAGE}
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+ARG GIT_LFS_VERSION
+
+RUN apt-get update \
+  && apt-get install -y --no-install-recommends \
+  curl \
+  ca-certificates
+
+COPY scripts/*.sh /usr/bin/
+
+CMD ["start.sh"]
diff --git a/sample.docker-compose.yml b/sample.docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ab8dc91121dbfd5b01d1321809482af52ae88f47
--- /dev/null
+++ b/sample.docker-compose.yml
@@ -0,0 +1,18 @@
+version: '3.9'
+
+services:
+  glfsi:
+    build:
+      context: .
+      args:
+        - IMAGE=${IMAGE}
+    image: glfsi
+    container_name: glfsi
+    network_mode: host
+    volumes:
+      - ${PREFIX}:${PREFIX}
+    environment:
+      - GIT_LFS_VERSION=${GIT_LFS_VERSION}
+      - PREFIX=${PREFIX}
+      - MODE=${MODE:-install}
+    userns_mode: host
diff --git a/scripts/start.sh b/scripts/start.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b917b22f479070877dbbcdc6a44939bb4495b435
--- /dev/null
+++ b/scripts/start.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Copyright (c) 2022 b-data GmbH.
+# Distributed under the terms of the MIT License.
+
+set -e
+
+cd /tmp
+curl -sSLO https://github.com/git-lfs/git-lfs/releases/download/v${GIT_LFS_VERSION}/git-lfs-linux-$(dpkg --print-architecture)-v${GIT_LFS_VERSION}.tar.gz
+tar xfz git-lfs-linux-$(dpkg --print-architecture)-v${GIT_LFS_VERSION}.tar.gz --no-same-owner
+cd git-lfs-${GIT_LFS_VERSION}
+
+sed -i 's/git lfs install/#git lfs install/g' install.sh
+echo '
+mkdir -p $prefix/share/man/man1
+rm -rf $prefix/share/man/man1/git-lfs*
+
+pushd "$( dirname "${BASH_SOURCE[0]}" )/man/man1" > /dev/null
+  for g in git-lfs*; do
+    install -m0644 $g "$prefix/share/man/man1/$g"
+  done
+popd > /dev/null
+
+mkdir -p $prefix/share/man/man5
+rm -rf $prefix/share/man/man5/git-lfs*
+
+pushd "$( dirname "${BASH_SOURCE[0]}" )/man/man5" > /dev/null
+  for g in git-lfs*; do
+    install -m0644 $g "$prefix/share/man/man5/$g"
+  done
+popd > /dev/null' >> install.sh
+
+echo '#!/usr/bin/env bash
+set -eu
+
+prefix="/usr/local"
+
+if [ "${PREFIX:-}" != "" ] ; then
+  prefix=${PREFIX:-}
+elif [ "${BOXEN_HOME:-}" != "" ] ; then
+  prefix=${BOXEN_HOME:-}
+fi
+
+rm -rf $prefix/bin/git-lfs*
+rm -rf $prefix/share/man/man1/git-lfs*
+rm -rf $prefix/share/man/man5/git-lfs*' > uninstall.sh
+chmod +x uninstall.sh
+
+if [[ -f "${MODE}.sh" ]]; then
+  ./${MODE}.sh
+  echo "Git LFS at ${PREFIX} ${MODE}ed."
+else
+  echo "Execution mode '${MODE}' not supported!"
+fi