blogc-git-receiver
- a simple login shell/git hook to deploy blogc websites
chsh -s $(command -v blogc-git-receiver
) user
blogc-git-receiver provides a PaaS-like way to deploy blogc(1) websites.
When used as a login shell, it will accept git payloads, creating bare repositories
as needed, and installing a hook, that will take care of rebuilding the website each
time someone push something to the master
branch.
The git repository must provide a blogcfile(5) (if blogc-make(1) is installed), or
a Makefile
(or a GNUMakefile
) that should accept the OUTPUT_DIR
variable, and
install built files into the directory pointed out by this variable.
blogc-git-receiver
is part of blogc
project, but isn't tied to blogc(1) or
blogc-make(1). Any repository with Makefile
that builds content and install it to
OUTPUT_DIR
should work with blogc-git-receiver
.
After creating an user (blogc
for the examples), change its shell to
blogc-git-receiver(1):
# chsh -s $(command -v blogc-git-receiver) blogc
Now add ssh keys to /home/blogc/.ssh/authorized_keys
. Every key in
authorized_keys
will be allowed to push to the git repositories, and even
create new ones. It is also possible to add blogc-git-receiver
as a command in
the authorized_keys
file for each key, but this setup is slightly more tricky,
as you may leak shell access to an user by mystake, if you forget to add the command
to a key that should not have shell access. Only use this method if you don't have
another option (e.g. in shared hosting environments that only provide one shell
account), or if you know exactly what you are doing.
Also, make sure to install all the dependencies required by the websites,
including a web server. blogc-git-receiver
can't handle web server virtual hosts.
To deploy a website (e.g. blogc example repository):
$ git clone https://github.com/blogc/blogc-example.git
$ cd blogc-example
$ git remote add blogc blogc@${SERVER_IP}:blogs/blogc-example.git
$ git push blogc master
This will deploy the example to the server, creating a symlink to the built content
in /home/blogc/repos/blogs/blogc-example.git/htdocs
. This symlink should be used
as the document root for the web server virtual host. If this symlink can't be
readed by your webserver for some reason, you can create it in some other directory
by adding the full symlink path to the ~/blogc-git-receiver.ini configuration file:
$ $EDITOR ~/blogc-git-receiver.ini
[repo:blogs/blogc-example.git]
symlink=/path/to/my/symlink
Do not duplicate the section if it already exists, just append the symlink path to it.
If for some reason you want to rebuild the last successful build of a given website,
you can run its pre-receive
hook manually in the server:
# su -s /bin/sh - blogc
$ cd ~/repos/blogs/blogc-example.git
$ ./hooks/pre-receive
This should re-run the last build as if it was pushed to git.
Supposing the usage of nginx as webserver, running as the nginx
user:
# dnf install -y nginx policycoreutils-python-utils
# useradd -m -s $(command -v blogc-git-receiver) blogc
# gpasswd -a nginx blogc
# chmod -R g+rx /home/blogc
# su -c "mkdir /home/blogc/{builds,repos}" -s /bin/sh blogc
# semanage fcontext -a -t httpd_sys_content_t "/home/blogc/(builds|repos)(/.*)?"
# restorecon -R -v /home/blogc
# systemctl restart nginx
After running these commands, the machine is ready to be used.
Users can rely on blogc-git-receiver
to mirror repositories to a remote Git
repository (e.g. a free Bitbucket private repository).
Please note that the blogc
user must be able to push to the remote repository, and
that any content manually pushed to the remote repository is overwritten by
blogc-git-receiver
.
Some reasonable ways to allow the blogc
user to push to the remote repository are:
The mirroring feature wont't block a git push
, it will just raise warnings. That
means that if an error happens when mirroring the repository, the deploy will still
succeed. Users should pay attention to the git hook logs, to avoid losing data
due to repositories not being mirrored.
This feature just requires adding a remote called mirror
to the bare repository
in the server, or creating a configuration file (~/blogc-git-receiver.ini), that is
a simple INI-style file where each repository is represented by a section and the
value of the mirror
variable is the URL that should be used to push.
Edit configuration file (recommended, do not duplicate the section if it already exists, just append the mirror to it):
# su -s /bin/sh - blogc
$ $EDITOR ~/blogc-git-receiver.ini
[repo:myblog.git]
mirror=$YOUR_GIT_MIRROR_URL
Or to add the mirror
remote:
# su -s /bin/sh - blogc
$ cd repos
$ git init --bare myblog.git # if not created yet
$ cd myblog.git
$ git remote add --mirror=push mirror $YOUR_GIT_MIRROR_URL
Both examples assume that your repository is named myblog.git
.
The authentication must be done with a password-less SSH key created by the blogc
user.
As the git push --mirror
call is automated, users must disable SSH strict host
checking in SSH's ~/.ssh/config
file:
Host bitbucket.org
StrictHostKeyChecking no
The example uses bitbucket.org
as remote host, that should be changed if needed.
To change this file, users must login with /bin/sh
or any other "real" shell,
as root
:
# su -s /bin/sh - blogc
If for some reason you want to push the repository of a given website to remote
mirror, you can run its post-receive
hook manually in the server:
# su -s /bin/sh - blogc
$ cd ~/repos/blogs/blogc-example.git
$ ./hooks/post-receive
WARNING: If you push manually and your server's repository is empty, you'll clean your mirror repository.
The following variables can be set in the SSH Server (usually in ~/.ssh/environment
)
to change blogc-git-receiver
behaviour:
BLOGC_GIT_RECEIVER_BASE_DIR
blogc-git-receiver
. Defaults
to user's home directory. Useful for shared hosting environments that only provide
one shell user.BLOGC_GIT_RECEIVER_BUILDS_DIR
$BLOGC_GIT_RECEIVER_BASE_DIR/builds
. This directory must be readable by
your webserver. This variable is useful to keep your git repositories unreadable,
while letting your webserver access the built files. In this case, users need to
also define custom symlinks for every repository in
$BLOGC_GIT_RECEIVER_BASE_DIR/blogc-git-receiver.ini
, because the default
htdocs
symlink inside the git repositories won't be acessible by the webserver.The following variable is exported by blogc-git-receiver
when building websites
with make(1):
BLOGC_GIT_RECEIVER=1
-D
).Please report any issues to: https://github.com/blogc/blogc
Rafael G. Martins <rafael@rafaelmartins.eng.br>
blogc(1), git(1), git-shell(1), chsh(1), su(1), make(1)