From ef34b26068c4e25f929a584edda63b8878c063b3 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 4 Jul 2026 16:31:13 +0530 Subject: Create local dockerfiles override to manage send/cgit users/groups --- .gitignore | 1 + cgit/Dockerfile | 67 ++++++++++++++++++++++++++++++++++++++ cgit/docker-entrypoint.sh | 17 ++++++++++ cgit/nginx.conf | 35 -------------------- cgit/nginx/conf.d/default.conf | 35 ++++++++++++++++++++ cgit/nginx/nginx.conf | 73 ++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 25 ++++++++------- justfile | 6 +++- send/Dockerfile | 4 +++ setup.sh | 33 +++++++++++++++---- 10 files changed, 241 insertions(+), 55 deletions(-) create mode 100644 cgit/Dockerfile create mode 100755 cgit/docker-entrypoint.sh delete mode 100644 cgit/nginx.conf create mode 100644 cgit/nginx/conf.d/default.conf create mode 100644 cgit/nginx/nginx.conf create mode 100644 send/Dockerfile diff --git a/.gitignore b/.gitignore index f1f78d5..08e7762 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.ignore .env +tmp/ diff --git a/cgit/Dockerfile b/cgit/Dockerfile new file mode 100644 index 0000000..86b3005 --- /dev/null +++ b/cgit/Dockerfile @@ -0,0 +1,67 @@ +FROM nginx:1.28.1-alpine3.23 + +ARG VERSION=0.0.0 +ENV VERSION=${VERSION} + +RUN addgroup -S git -g 1001 && adduser -S -G git -u 1001 -D git + +# CGit +ARG CGIT_VERSION=1.2.3-r5 +ENV CGIT_VERSION=${CGIT_VERSION} + +LABEL version="${VERSION}" \ + description="The hyperfast web frontend for Git repositories on top of Alpine and Nginx." \ + maintainer="Jose Quintana " + +RUN set -eux \ + && apk add --no-cache \ + ca-certificates \ + cgit=${CGIT_VERSION} \ + fcgiwrap \ + git \ + lua5.3-libs \ + py3-markdown \ + py3-pygments \ + py3-docutils \ + groff \ + python3 \ + spawn-fcgi \ + tzdata \ + xz \ + zlib \ + && rm -rf /var/cache/apk/* \ + && rm -rf /tmp/* \ + && true + +COPY docker-entrypoint.sh / +RUN chmod +x /docker-entrypoint.sh +COPY nginx/ /etc/nginx + +# RUN set -eux \ +# && echo "Creating application directories..." \ +# && mkdir -p /var/cache/cgit \ +# && mkdir -p /srv/git \ +# && true + +RUN set -eux \ + && echo "Testing Nginx server configuration files..." \ + && nginx -c /etc/nginx/nginx.conf -t \ + && true + +RUN ls -la /docker-entrypoint.sh + +ENTRYPOINT [ "/docker-entrypoint.sh" ] + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD [ "nginx", "-g", "daemon off;" ] + +# Metadata +LABEL org.opencontainers.image.vendor="Jose Quintana" \ + org.opencontainers.image.url="https://github.com/joseluisq/alpine-cgit" \ + org.opencontainers.image.title="cgit" \ + org.opencontainers.image.description="The hyperfast web frontend for Git repositories on top of Alpine and Nginx." \ + org.opencontainers.image.version="${VERSION}" \ + org.opencontainers.image.documentation="https://github.com/joseluisq/alpine-cgit" diff --git a/cgit/docker-entrypoint.sh b/cgit/docker-entrypoint.sh new file mode 100755 index 0000000..0c13086 --- /dev/null +++ b/cgit/docker-entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +set -eux + +CGIT_USER=git +CGIT_GROUP=git + +id + +chown $CGIT_USER:$CGIT_GROUP /var/cache/cgit +chmod u+g /var/cache/cgit + +spawn-fcgi \ + -u $CGIT_USER -g $CGIT_GROUP \ + -s /var/run/fcgiwrap.sock \ + -n -- /usr/bin/fcgiwrap \ + & exec "$@" diff --git a/cgit/nginx.conf b/cgit/nginx.conf deleted file mode 100644 index a850744..0000000 --- a/cgit/nginx.conf +++ /dev/null @@ -1,35 +0,0 @@ -server { - listen 80; - server_name localhost; - root /usr/share/webapps/cgit; - - location / { - try_files $uri @cgit; - } - - location ~* ^.+(favicon.ico|robots.txt) { - root /usr/share/webapps/cgit; - expires 30d; - } - - location @cgit { - include /etc/nginx/fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi; - fastcgi_param PATH_INFO $uri; - fastcgi_param QUERY_STRING $args; - fastcgi_param HTTP_HOST $server_name; - fastcgi_pass unix:/var/run/fcgiwrap.sock; - } - - error_page 404 /404.html; - error_page 401 /401.html; - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - - location ~ /\.ht { - deny all; - } -} diff --git a/cgit/nginx/conf.d/default.conf b/cgit/nginx/conf.d/default.conf new file mode 100644 index 0000000..a850744 --- /dev/null +++ b/cgit/nginx/conf.d/default.conf @@ -0,0 +1,35 @@ +server { + listen 80; + server_name localhost; + root /usr/share/webapps/cgit; + + location / { + try_files $uri @cgit; + } + + location ~* ^.+(favicon.ico|robots.txt) { + root /usr/share/webapps/cgit; + expires 30d; + } + + location @cgit { + include /etc/nginx/fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi; + fastcgi_param PATH_INFO $uri; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + fastcgi_pass unix:/var/run/fcgiwrap.sock; + } + + error_page 404 /404.html; + error_page 401 /401.html; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location ~ /\.ht { + deny all; + } +} diff --git a/cgit/nginx/nginx.conf b/cgit/nginx/nginx.conf new file mode 100644 index 0000000..c5a713f --- /dev/null +++ b/cgit/nginx/nginx.conf @@ -0,0 +1,73 @@ +user git; +worker_processes auto; +error_log stderr crit; +pid /var/run/nginx.pid; + +events { + worker_connections 2048; + use epoll; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + open_file_cache max=200000 inactive=20s; + open_file_cache_valid 30s; + open_file_cache_min_uses 2; + open_file_cache_errors on; + + access_log off; + error_log stderr crit; + + sendfile on; + sendfile_max_chunk 512k; + tcp_nopush on; + tcp_nodelay on; + types_hash_max_size 4096; + + keepalive_timeout 35; + + gzip on; + gzip_min_length 10240; + gzip_comp_level 1; + gzip_vary on; + gzip_disable msie6; + gzip_proxied expired no-cache no-store private auth; + # text/html is always compressed by HttpGzipModule + gzip_types + text/css + text/javascript + text/xml + text/plain + text/x-component + application/javascript + application/x-javascript + application/json + application/xml + application/rss+xml + application/atom+xml + font/truetype + font/opentype + application/vnd.ms-fontobject + image/svg+xml; + + reset_timedout_connection on; + client_body_timeout 10; + send_timeout 5; + + server_tokens off; + add_header X-Frame-Options SAMEORIGIN; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + + client_body_buffer_size 128k; + large_client_header_buffers 4 256k; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + include /etc/nginx/conf.d/*.conf; +} diff --git a/docker-compose.yml b/docker-compose.yml index f8316af..646cb11 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,35 +1,36 @@ services: send: profiles: [services] - image: 'registry.gitlab.com/timvisee/send:v3.4.27' + build: + context: ./send restart: always ports: - '1234:1234' - volumes: - - /uploads:/uploads environment: - VIRTUAL_PORT=1234 - VIRTUAL_HOST=send.ediblemonad.dev - LETSENCRYPT_HOST=send.ediblemonad.dev - DHPARAM_GENERATION=false - # - LETSENCRYPT_EMAIL=ediblemonad@gmail.com + # send - NODE_ENV=production - BASE_URL=https://send.ediblemonad.dev - PORT=1234 - REDIS_HOST=redis - FILE_DIR=/uploads - # upload limits - - EXPIRE_TIMES_SECONDS=3600,86400,604800,2592000,31536000 + - EXPIRE_TIMES_SECONDS=3600,86400,604800,2592000 - DEFAULT_EXPIRE_SECONDS=86400 - - MAX_EXPIRE_SECONDS=31536000 + - MAX_EXPIRE_SECONDS=2592000 # 30 days - MAX_DOWNLOADS=100 - - MAX_FILE_SIZE=1073741824 + - MAX_FILE_SIZE=536870912 # 512M + volumes: + - ${SEND_UPLOADS_ROOT:-/uploads}:/uploads depends_on: - redis cgit: profiles: [services] - image: 'joseluisq/alpine-cgit:2.9' + build: + context: ./cgit restart: always ports: - 8080:80 @@ -39,12 +40,12 @@ services: - LETSENCRYPT_HOST=git.ediblemonad.dev - DHPARAM_GENERATION=false - USE_CUSTOM_CONFIG=true + - GIT_REPOS_ROOT=${GIT_REPOS_ROOT:-/git} volumes: - cgit-cache:/var/cache/cgit - - /home/imsohexy/dev/projects:/srv/git:ro + - ${GIT_REPOS_ROOT:-/git}:/srv/git:ro - ./cgit/cgitrc:/etc/cgitrc:ro - ./cgit/static:/usr/share/webapps/cgit/ediblemonad:ro - - ./cgit/nginx.conf:/etc/nginx/conf.d/default.conf:ro - ./cgit/filters:/usr/lib/cgit/filters/ediblemonad:ro - ./favicon.ico:/usr/share/webapps/cgit/favicon.ico:ro @@ -73,7 +74,7 @@ services: - DEFAULT_EMAIL=ediblemonad@gmail.com - NGINX_PROXY_CONTAINER=nginx-proxy - NGINX_DOCKER_GEN_CONTAINER=nginx-proxy - - ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory + # - ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - proxy-certs:/etc/nginx/certs diff --git a/justfile b/justfile index b07928e..67528c2 100644 --- a/justfile +++ b/justfile @@ -23,4 +23,8 @@ setup *args: just ssh "{{TARGET_DIR}}/setup.sh" "$@" local-setup *args: - ROOT_DIR="$PWD" ./setup.sh "$@" + mkdir -p ./tmp/uploads + ROOT_DIR="$PWD" \ + GIT_REPOS_ROOT="$HOME/dev/projects" \ + SEND_UPLOADS_ROOT="$PWD/tmp/uploads" SEND_USER="$(id -u):$(id -g)" \ + ./setup.sh "$@" diff --git a/send/Dockerfile b/send/Dockerfile new file mode 100644 index 0000000..47144c0 --- /dev/null +++ b/send/Dockerfile @@ -0,0 +1,4 @@ +FROM registry.gitlab.com/timvisee/send:v3.4.27 +USER root +RUN addgroup -g 1002 send && adduser -D -u 1002 -G send send +USER send diff --git a/setup.sh b/setup.sh index 3742d48..3f05f3b 100755 --- a/setup.sh +++ b/setup.sh @@ -4,37 +4,56 @@ set -eu ROOT_DIR=${ROOT_DIR:-"/opt/project"} -setup() { packages; firewall; } +configure() { + configure_user && configure_fs && configure_packages && configure_firewall +} services() { cd "$ROOT_DIR"; docker compose --profile services "$@"; } core() { cd "$ROOT_DIR"; docker compose --profile core "$@"; } # TODO: use --wait and add health checks -start() { stop || true; services up -d; } +start() { stop || true; services up -d "$@"; } + +startfg() { stop || true; services up "$@"; } stop() { services down; } -packages() { +configure_packages() { apt install \ docker.io docker-buildx docker-compose-v2 \ ufw } -firewall() { +configure_firewall() { ufw allow 443/tcp ufw allow 80/tcp ufw allow 22 ufw enable } +configure_user() { + groupadd -f -g 1001 git + useradd --shell /usr/sbin/nologin --no-create-home git --uid 1001 --gid 1001 || true + groupadd -f -g 1002 send + useradd --shell /usr/sbin/nologin --no-create-home send --uid 1002 --gid 1002 || true +} + +configure_fs() { + mkdir -p /git + chown -R git:git /git + mkdir -p /uploads + chown -R send:send /uploads +} + update() { - apt update; - services build --pull; + apt update + services build --pull } cmd="$1"; shift; case "$cmd" in - setup|update|start|stop|firewall|packages|services|core) "$cmd" "$@" ;; + update|start|startfg|stop|services|core) "$cmd" "$@" ;; + configure|configure_firewall|configure_user|configure_fs|configure_packages) "$cmd" "$@" ;; *) echo "Invalid command: $cmd"; exit 1 ;; esac -- cgit v1.3.1