User:Halcon/HOWTO cgit uwsgi nginx
HOWTO install and configure cgit + uwsgi + nginx in a domain subdirectory without webapp-config (using OpenRC).
Following this HOWTO, please don't forget to replace "example" values (such as someuser, subdirectory, www.your-domain.something) with real ones.
cgit
Installing
If Nginx is not yet installed, install it first, otherwise cgit will install by default www-servers/apache.
The package www-apps/cgit can be installed without dependency on app-admin/webapp-config from halcon-overlay (run by the author of this article).
root #
echo "*/*::halcon-overlay" >> /etc/portage/package.mask
root #
echo "www-apps/cgit::halcon-overlay" >> /etc/portage/package.unmask
root #
echo "www-apps/cgit ~amd64" >> /etc/portage/package.accept_keywords
root #
echo "www-apps/cgit nginx" >> /etc/portage/package.use/cgit
root #
eselect repository add halcon-overlay git https://github.com/halcon74/halcon-overlay.git
root #
emerge --sync halcon-overlay
root #
emerge --ask --verbose www-apps/cgit
Alternatively, you could copy the content of www-apps/cgit directory of that overlay to your local overlay and install the package from there.
Configuring
Create a special system user (it will be needed for configuring write access to the repositories):
root #
useradd -m -s /bin/bash someuser
Set a password for this user:
root #
passwd someuser
Log in as this user and make a directory for repositories:
root #
su - someuser
user $
mkdir ~/repos
user $
chown someuser:nginx ~/repos
user $
chmod 750 ~/repos
Then, create the configuration file for cgit:
# Make cgit generate link using absolute URL
virtual-root=/subdirectory/
# The maximum number of entries in the cgit cache. When set to "0",
# caching is disabled.
cache-size=0
# Cache time to live
# All cache ttl values are in minutes. Negative ttl values indicate that a page
# type will never expire, and thus the first time a URL is accessed, the result
# will be cached indefinitely, even if the underlying git repository changes.
# Conversely, when a ttl value is zero, the cache is disabled for that
# particular page type, and the page type is never cached.
cache-dynamic-ttl=0
cache-repo-ttl=0
# Specify some default clone urls using macro expansion
clone-url=https://www.your-domain.something/subdirectory/$CGIT_REPO_URL
# Specify the css url
css=/cgit.css
# Show owner on index page
enable-index-owner=0
# Allow http transport git clone
enable-http-clone=1
# Show extra links for each repository on the index page
enable-index-links=1
# Remove .git suffix from project display
remove-suffix=1
# Enable ASCII art commit history graph on the log pages
enable-commit-graph=1
# Show number of affected files per commit on the log pages
enable-log-filecount=1
# Show number of added/removed lines per commit on the log pages
enable-log-linecount=1
# Sort branches by date
branch-sort=age
# Add a cgit favicon
favicon=/favicon.ico
# Use a custom logo
logo=/cgit.png
# Enable statistics per week, month and quarter
max-stats=year
# Set the title and heading of the repository index page
root-title=Git repositories
# Set a subheading for the repository index page
root-desc=Fast web front end for Git repositories
# Allow download of tar.gz, tar.bz2 and zip-files
snapshots=tar.bz2
# List of common mimetypes
# See https://www.sitepoint.com/mime-types-complete-list/
mimetype.html=text/html
mimetype.js=text/javascript
mimetype.css=text/css
mimetype.pl=text/x-script.perl
mimetype.pm=text/x-script.perl-module
mimetype.py=text/x-script.python
mimetype.png=image/png
mimetype.gif=image/gif
mimetype.jpg=image/jpeg
mimetype.jpeg=image/jpeg
# Highlight source code with python pygments-based highligher
source-filter=/usr/lib64/cgit/filters/syntax-highlighting.py
# Format markdown, restructuredtext, manpages, text files, and html files
# through the right converters
about-filter=/usr/local/lib/cgit/filters/about-formatting.sh
# Search for these files in the root of the default branch of repositories
# for coming up with the about page:
readme=:README.md
readme=:readme.md
readme=:README.mkd
readme=:readme.mkd
readme=:README.rst
readme=:readme.rst
readme=:README.html
readme=:readme.html
readme=:README.htm
readme=:readme.htm
readme=:README.txt
readme=:readme.txt
readme=:README
readme=:readme
readme=:INSTALL.md
readme=:install.md
readme=:INSTALL.mkd
readme=:install.mkd
readme=:INSTALL.rst
readme=:install.rst
readme=:INSTALL.html
readme=:install.html
readme=:INSTALL.htm
readme=:install.htm
readme=:INSTALL.txt
readme=:install.txt
readme=:INSTALL
readme=:install
# Repositories.
# There are 2 options, please choose one:
#
# Option 1 - separate entries for each repo
#
#repo.url=My-Repo
#repo.path=/home/someuser/repos/My-Repo
#repo.desc=Some description
#repo.owner=author@some.email
#repo.readme=info/web/about.html
#
# Option 2 - a list with all repos
# (description, owner etc can be indicated inside repos)
#
enable-git-config=1
project-list=/home/someuser/project.list
scan-path=/home/someuser/repos
For the Option 2, content of the file /home/someuser/project.list could be:
My-Repo
(Don't forget to create this file not as root, but as someuser)
uwsgi
Installing
root #
echo "www-servers/uwsgi cgi" >> /etc/portage/package.use/uwsgi
root #
emerge --ask --verbose www-servers/uwsgi
Configuring
Create the main configuration file (as someuser):
[uwsgi]
; enables logging via the system-default syslog program
; (for example, syslog-ng)
logger = syslog
; recommended for all your apps, unless you're using emperor
; https://stackoverflow.com/a/35080578
master = true
; can be nginx or of other web-server
; CAN NOT BE ROOT !!
uid = nginx
gid = nginx
; please tune according to your needs
processes = 1
threads = 1
; cgit requires cgi
plugins = cgi
; location where all uwsgi plugins were installed
plugins-dir = /usr/lib64/uwsgi/
; modifier for uwsgi packets to fit into cgi standard
; https://uwsgi-docs.readthedocs.io/en/latest/Protocol.html
http-modifier1 = 9
; name can be any
socket = /run/uwsgi_cgit/uwsgi_cgit.sock
chmod-socket = 600
; can be any address:port on localhost
; useful for debugging - just curl that address
; http = 127.0.0.7:7777
; location where the cgi binary was installed
; MUST BE CHANGED accordingly in case of installing another cgit version
chdir = /usr/share/webapps/cgit/1.2.3-r103/hostroot/cgi-bin
; cgi binary name
cgi = cgit.cgi
; this is an alternative to nginx rewrite rule
; "rewrite ^/subdirectory/(.*)$ /subdirectory/$1?url=/$1 break;"
route-uri = ^/subdirectory/(.*) rewrite:/$1
Create a non-emperor uwsgi OpenRC service:
root #
ln -s /etc/init.d/uwsgi /etc/init.d/uwsgi.cgit
Create the configuration file for the service:
# Distributed under the terms of the GNU General Public License v2
# Additional options you might want to pass to uWSGI
#
UWSGI_EXTRA_OPTIONS="--ini /home/someuser/uwsgi.cgit.ini"
# The application will run as nginx:nginx even without these,
# because uid and gid are set to nginx in /home/someuser/uwsgi.cgit.ini,
# but these are necessary for changing permissions of the directory
# /run/uwsgi_cgit (and permitting the application to create a socket there)
#
UWSGI_USER=nginx
UWSGI_GROUP=nginx
nginx
Configuring
The corresponding sections of the configuration file /etc/nginx/nginx.conf:
http { upstream uwsgi_cgit { server unix:///run/uwsgi_cgit/uwsgi_cgit.sock; } server { ... location ~* ^.+(cgit.(css|png)|favicon.ico) { root /usr/share/webapps/cgit/1.2.3-r103/htdocs/; expires 30d; } location /subdirectory/ { uwsgi_pass uwsgi_cgit; include uwsgi_params; uwsgi_modifier1 9; } } }
("root" value MUST BE CHANGED accordingly in case of installing another cgit version)
Working with git
Read access (git clone, git pull)
Create a testing repo:
root #
su - someuser
user $
mkdir ~/repos/My-Repo
user $
cd ~/repos/My-Repo
user $
touch a
user $
git init
user $
git add .
user $
git config user.name "Author Name"
user $
git config user.email "author@some.email"
user $
git commit -a -m "initial commit"
Start the service:
root #
rc-service uwsgi.cgit start
Restart nginx:
root #
rc-service nginx restart
Try to clone the repo by https:
user $
git clone https://www.your-domain.something/subdirectory/My-Repo
After the successful testing, add the service to default run level, if you need that:
root #
rc-update add uwsgi.cgit default
Write access (git push)
Cgit does not support "git push" - at all, no such feature. But it's not a problem. It can be configured via SSH. After performing all the necessary steps (creating keys, adding the public key to /home/someuser/.ssh/authorized_keys etc), first test if someuser can log in via ssh in the usual way (without git). After testing that, "git push via ssh" can be configured as follows.
Re-create the repository My-Repo on the server. It should be empty and bare:
root #
su - someuser
user $
cd ~/repos/My-Repo
user $
rm -rf ./.git
user $
rm a
user $
git init
user $
git config --bool core.bare true
On a machine you plan to push from, in the repository folder:
user $
git remote add origin ssh://someuser@www.your-domain.something/home/someuser/repos/My-Repo
or
user $
git remote set-url origin ssh://someuser@www.your-domain.something/home/someuser/repos/My-Repo
user $
git config core.sshCommand "ssh -i /path/to/your/private/key"
user $
git push --set-upstream origin master
or
user $
git push origin
And look at the page www.your-domain.something/subdirectory/My-Repo in a browser.
Troubleshooting
repository not found
If there is such a message on cgit web page, sooner of all, it means that there is a problem with permissions. If cgit is configured to read a file like project.list and can't read it, it warns about it. So, if you don't see that message, it means that cgit has read the list successfully and the problem is somewhere in the repository.
other issues with web page
As a general tip, it should be debugged starting from upstream. First, run
root #
sudo -u nginx /usr/share/webapps/cgit/1.2.3-r103/hostroot/cgi-bin/cgit.cgi
If it does not help to identify the problem, you could enable "http" directive for uwsgi and run uwsgi not as OpenRC service, but directly:
root #
uwsgi /home/someuser/uwsgi.cgit.ini &
And then to see the result with curl, as it was recommended in the comments in uwsgi.cgit.ini.
account is locked
If, while trying to log in via ssh, the server warns "someuser not allowed because account is locked", it means that you forgot to create user password (even if you configured the authorization via public key).
External resources
- https://www.tyil.nl/post/2020/01/08/running-cgit-on-gentoo/ - An article about cgit on Gentoo in Tyil's personal blog.