aboutsummaryrefslogtreecommitdiffstats
path: root/man/blogc-git-receiver.1.ronn
blob: 5759bacd2db12be70c7f0b0eaa7e4416ae1d925a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
blogc-git-receiver(1) -- a simple login shell/git hook to deploy blogc websites
===============================================================================

## SYNOPSIS

chsh -s $(command -v `blogc-git-receiver`) <user>

## DESCRIPTION

**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`.

## SETUP

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.

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.

### Rebuild last successful build

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.

### Setup with SELinux enabled (Fedora)

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.

## REPOSITORY MIRRORING

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:

- Create a password-less SSH key. The key *must* be password-less, because the push
  is automatic, and remote git hooks can't be interactive.
- Create an oauth token in the hosting service (if it supports oauth authentication
  in git, e.g. GitHub) and add it to the git URL.

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.

To create the configuration file (recommended):

    # su -s /bin/sh - blogc
    $ cat > ~/blogc-git-receiver.ini <<EOF
    [repo:myblog.git]
    mirror=$YOUR_GIT_MIRROR_URL
    EOF

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`.

### Caveats of repository mirroring with SSH

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

### Push to mirror manually

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.

## ENVIRONMENT

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`:
    Path to the base directory that should be used by `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`:
    Path to the directory that should be used to store the blogc builds. Defaults
    to `$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`1. 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`:
    This variable can be used to enable building of content that should only be
    built when running in production environment, for example. This variable will
    not be exported when using blogc-make(1), whose builds are always considered to
    be "production" (blogc-make(1) is never called with `-D`).

## BUGS

Please report any issues to: <https://github.com/blogc/blogc>

## AUTHOR

Rafael G. Martins &lt;<rafael@rafaelmartins.eng.br>&gt;

## SEE ALSO

blogc(1), git(1), git-shell(1), chsh(1), su(1), make(1)