7.2 KiB
A personal Git enhanced with CI/CD
Gitea for a self hosted git
In the continuity of the static site generator, I wanted also to store my blog in a git repo. This has several purposes :
- I could eventually edit my blog from any machine : I just would need to clone the repository and edit my files
- With a CI/CD pipeline, all changes to this repository would trigger the pipeline to rebuild the static blog automatically and deploy it on my server
There are not many self host git that include a nice web UI. Of course I stick to striclty open source, and chose gitea over gitlab. Its web UI is nice, similar to github, it is relatively lightweight, compared to gitlab, its installation is quite easy and has all the basic functionnalities I need :
- A simple git backend
- A intuitive web UI
- A container registry
To also improve my docker
skills, I went for a all in docker solution. Gitea has an official image on the docker hub, as well as a nice documentation
To persist my data, PostgreSQL is my go to : I feel it is simply the best Database so far.
Drone for continuous integration/deployment pipelines
Whereas choosing a self hosted git was relatively easy, picking a CI/CD tool was a thougher choice : there are many of them out there. I know less about CI/CD, and narrowed my short list to two of them:
- Drone
- Buildbot
In order to move on my project, I tried not to overthink it and went for Drone, even though I feel Buildbot would be maybe a more complete solution. One aspect of Drone that pleased me was the possibility to run all with docker images, and its documented integration with Gitea. Let me clarify that :
- Indeed, drone interfaces easily with gitea as per its documentation (and not so much with gitlab, which conforted my initial choice)
- The other point is that it can run its pipeline all within docker container, as seen here, that is each step of the pipeline is the execution of a container. As I wanted to improve my docker skills as well, this was a nice touch. However this means that I would have to package my static blog generator as a docker image to run it in my pipeline.
The web UI is also very nice and intuitive, and its uses the Gitea SSO for signing in.
The actual setup
The architecture
First of all, since all these services would run of the same machine (a small VPS, as the workload of this personnal blog shall remain low), I wanted to have an nginx proxy before all of them. Of course, even Nginx shall be run as a docker container.
Hence here are all the containers that must be up and running at the end :
- Nginx
- Gitea
- Postgres
- Drone
- Drone runner (indeed, this container ACTUALLY runs the pipeline, the Drone one only acts as a scheduler)
For clarity let us create three folders in the server, all of them containing the docker-compose.yml
that ups the services :
- gitea : it holds the gitea container as well as the postgres (as it is only used by gitea here)
- nginx : as the proxy it is separated from the others
- drone : of course, the last piece of the puzzle, containing drone server and runner
All of them needs to be on the same docker network to comunicate with each other.
Creating the network
As said above, all these running containers need to be on the same docker netword so that they can communicate. Frist this is then to create this network, with this simple command (mine is simply called gitea, as all revolve around it)
docker network create gitea
All default parameters for this network is quite fine here.
Hence, all the docker-compose.yml
shall start with :
networks:
gitea:
external: true
that indicates the use of the previously created network as an externally created network.
The proxy
To make this project a serious one, we need to have https enabled. For this, there is a very convenient initiative : letsencrypt, and the very nice certbot that acts like its CLI.
Since we are going all docker, we shall use the official nginx and certbot.
The point of doing this in a separate folder, is to organize the mounted volumes : indeed between nginx logs, configurations and certbot, we need to know for sure where to find all those files.
Only the /var/www/html
will be map as is to the container, that is /var/www/html:/var/www/html
. I find it easier to follow the default path for nginx even on the host machine, as if nginx was not running on docker.
In the nginx
folder, let us make two subfolders : certbot
and nginx
, self explanatory.
Configuring the nginx web server
We considerd being in the folder $HOME/nginx, in which there are two subfolders : nginx and certbot
I will not go for a nginx tutorial as the official documentation is quite exhaustive.
However here is the part of the docker-compose.yml
that concerns nginx :
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf:/etc/nginx/conf.d
- ./certbot/www:/var/www/certbot/
- ./certbot/conf:/etc/nginx/ssl/:ro
- ./nginx/logs:/var/log/nginx/
- /var/www/html:/var/www/html/
networks:
- gitea
It obviously expose ports 80 (for redirection) and 443. It always restart, as we do not want off time. Concerning the volumes : the configuration is in the ./nginx/conf, this way we can update it anytime. It will also need access to the the certbot confg. As said above, we also want to access the logs, as I prepare a web analytics sofware, that insetad of using cookies and intrusive ways, only uses the nginx logs. Of course, it is in the gitea network. As containers can belong to several networks, if in the future I want to add another web server, I will add this container to the second network.
Notice also the /var/www/certbot
path within the container : it is useful for the acme challenge. We will talk about it later.
Adding certbot to the loop
We will also use docker-compose.yml
to configure certbot, even though it will not be a running container, whereas a short lived one.
certbot:
image: certbot/certbot:latest
networks:
- gitea
volumes:
- ./certbot/www:/var/www/certbot/:rw
- ./certbot/conf:/etc/letsencrypt/:rw
It also belongs to the gitea networks, to communicate to nginx. Even though this is probably not the best idea : a dedicated network should have been more relevant. Two volumes are also mounted. The certbot/conf contains the actual certificates that will generate promptly.
The initial nginx config
For certbot to generate the certificate, we need nginx to have this minimal config :
server {
listen 80;
listen [::]:80;
server_name example.org www.example.org;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://example.org$request_uri;
}
}