blog/drafts/gitea_and_drone.md
simonpetit 0ac5937344
All checks were successful
continuous-integration/drone/push Build is passing
WIP
2024-12-09 14:51:08 +00:00

158 lines
7.5 KiB
Markdown

# 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](https://hub.docker.com/r/gitea/gitea), as well as a nice [documentation](https://docs.gitea.com/installation/install-with-docker)
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](https://docs.drone.io/server/provider/gitea/) (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](https://docs.drone.io/quickstart/docker/), 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](https://letsencrypt.org/fr/), and the very nice [certbot](https://certbot.eff.org/) that acts like its CLI.
Since we are going all docker, we shall use the official [nginx](https://hub.docker.com/_/nginx) and [certbot](https://hub.docker.com/r/certbot/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](http://nginx.org/en/docs/beginners_guide.html) 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;
}
}
Indeed, for the ACME challenge, certbot must have a positive respone to /.well-known/acme-challenge/, which points to /var/www/cerbot.
Now we can run certbot to generate the certificate. Let us start with a dry run first :
Insert dry run command
### Configuring Gitea
### Starting with Drone CI