The first web application I'll use is my own: pyragit. This app renderes markdown files from a git repository as a website - you are currently looking at it ;-)

To get this up and running, a couple of steps must be taken:

  1. create a separate user for serving git repositories
  2. create a content repository
  3. install pyragit
  4. setup a uwsgi vassal to serve the webapp
  5. adjust the nginx config

add a user fo serving git repos

I just like to have a separate user serving git repos, than my default user. Therfore I'll add a separate user. The only special thing is, that the login group of the user will be set to www. This simplifies the access controll from the web app to the content repository.

remote> sudo adduser
Username: git
Full name: git
Uid (Leave empty for default): 
Login group [git]: www
Login group is www. Invite git into other groups? []:
Login class [default]: 
Shell (sh csh tcsh zsh rzsh nologin) [sh]: git-shell
Home directory [/home/git]: 
Home directory permissions (Leave empty for default): 
Use password-based authentication? [no]: 

Now some public key for the user git should be added, just like in the first steps section.

create a content repository

To serve some content with pyragit, there must be a (non-empty) content repository. The repository must be created as the user git, else there will be problems with file permissions:

remote> cd /home/git
remote> sudo -u www git --bare init content-repo.git

On the local machine, we can now clone the conten repository, make the first addition and push the changes back:

local> git clone git@<servername>:conten-repo.git website-content
local> cd website-content
local> vim
# welcome
I you see this, it works \o/
local> git add .
local> git commit -m "welcome message"
local> git push

installing pyragit

I don't deem pyragit to be mature or useful enough to upload it to pypi. I'lll install pyragit directly from it's repository. This has the advantage, that updating it is quite easy for me.

I'll install all web applications into /usr/local/webapps:

remote> cd /usr/local
remote> sudo mkdir webapps

Since the webapp should be served from the user www, I need to be careful about file permissions after cloning the pyragit repository:

remote> cd /usr/local/webapps
remote> sudo git clone pyragit
remote> sudo chown -R www:www pyragit

The webapplication should be installed in a virtual environment to keep the system wide installation clean.

remote> cd /usr/local/webapps/pyragit
remote> sudo -u www python -m venv .venv
remote> sudo -u www source .venv/bin/activate
remote> sudo -u www pip install -e .

The only thing that is left to be done is to link the content repository here

remote> cd /usr/local/webapps/pyragit
remote> sudo -u www ln -s /home/git/conten-repo.git content-repo

the uwsgi vassal

After installing the web application itself, it should be served using our uwsgi installation. Therfore we create a vassal configuration for the app and reload uwsgi.

remote> cd /usr/locat/etc/uwsgi/vassals
remote> sudo vim pyragit.ini
# run application as user and group
uid = www
gid = www

# socket connection for the application
socket = /tmp/%n.sock
# socket for monitoring the application
stats = /tmp/%n-stats.sock

# working directory, where the application resides
chdir = /usr/local/webapps/pyragit

# virtual environment to activate
virtualenv = /usr/local/webapps/pyragit/.venv

# mount the application on url root
# module = example:callable
# module = ordr2:main
ini-paste = /usr/local/webapps/pyragit/production.ini

# this is a standalone application

remote> sudo service uwsgi reload

adjusting nginx configuration

The last step is to tell nginx to serve content for a domain via a uwsgi socket. We only need to adjust the location parts in the config file.

remote> sudo vim /usr/local/etc/nginx/sites-available/
location / {
    root      /usr/local/www/default;
    try_files $uri @pyragit;

location @pyragit {
    include    uwsgi_params;
    uwsgi_pass unix:/tmp/pyragit.sock;

And of cause, we need to reload nginx:

remote> sudo service nginx reload

If everything works, you should see the right content when accessing the domain specified in the nginx config file.