Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfabc38a46 | ||
|
818626b236
|
|||
|
|
d3927f6c5d | ||
|
1120daab40
|
|||
|
|
e4ea3a420d | ||
|
14d463a882
|
|||
|
|
1816d8a585 | ||
|
a22b78d585
|
|||
|
aafa72a464
|
|||
|
ae3af7ea83
|
|||
|
|
09e8534569 | ||
|
6928e8cf54
|
|||
|
dc1b18019a
|
|||
|
02426968fb
|
|||
|
edb227a763
|
|||
|
c03f0a0f4f
|
|||
|
|
7b0b2e8194 | ||
|
2cca3d5403
|
|||
|
9e68459916
|
|||
|
e23f9b1901
|
|||
|
|
c8fa7680ca | ||
|
007ae9a90a
|
|||
|
557fe0d5dc
|
|||
|
ab06bc177e
|
|||
|
|
0f2c17071c | ||
|
|
d716fefb88 | ||
| 764883f26d |
81
README.org
81
README.org
@@ -1,48 +1,63 @@
|
||||
#+TITLE: Gitea Server Installer Role
|
||||
#+TITLE: Gitea Server Role
|
||||
#+AUTHOR: DeadSwitch | The Silent Architect
|
||||
#+OPTIONS: toc:nil num:nil \n:t
|
||||
|
||||
[[https://opensource.org/licenses/MIT][https://img.shields.io/badge/license-MIT-blue.svg]] [[https://img.shields.io/badge/version-3.0.2-green.svg]]
|
||||
|
||||
* ds-gitea
|
||||
|
||||
This role installs and configures a [[https://docs.gitea.com/][Gitea]] server.
|
||||
This role can install and configures a [[https://docs.gitea.com/][Gitea]] server.
|
||||
|
||||
It uses SQLite as its default database service - with optional PostgreSQL support.
|
||||
It uses SQLite as its default database service - with optional PostgreSQL support (=ds-posgresql=).
|
||||
|
||||
Use the =ds-ufw= role to configure the firewall.
|
||||
The role can set up a reverse proxy with SSL using Nginx (=ds-nginx=).
|
||||
Self-signed certificates and Let's Encrypt with =certbot= are supported.
|
||||
|
||||
Use the =ds-posgresql= to configure the database.
|
||||
The =ds-ufw= role can configure the firewall.
|
||||
|
||||
* Role Workflow
|
||||
The =ds-act_runner= role can configure and register Actions runners.
|
||||
|
||||
* Role Behavior
|
||||
|
||||
1. Download and install the Gitea binary
|
||||
2. (Optionally) Set up the PostgreSQL user and database
|
||||
3. Set up the user and group for the service
|
||||
4. Create the required directory structure
|
||||
5. Wait for the secret creation and storage in SOPS - if secrets are not present
|
||||
6. Deploy the Gitea configuration
|
||||
7. Deploy the Gitea service file
|
||||
8. Enable and start the service
|
||||
3. (Optionally) Set up an =nginx= reverse proxy with SSL support
|
||||
4. Create a user and group for the service
|
||||
5. Create the required directory structure
|
||||
6. Wait to save the secrets in SOPS (only if secrets are not present)
|
||||
7. Deploy the Gitea =app.ini= configuration
|
||||
8. Deploy the Gitea systemd service
|
||||
9. Enable and start the services
|
||||
|
||||
* Defaults
|
||||
|
||||
#+begin_src yaml
|
||||
gitea_user: git
|
||||
gitea_group: git
|
||||
gitea_http_port: 3000
|
||||
gitea_ssh_port: 22
|
||||
gitea_require_signin_view: true
|
||||
gitea_disable_registration: true
|
||||
gitea_register_manual_confirm: false
|
||||
gitea_enable_captcha: false
|
||||
gitea_default_keep_email_private: true
|
||||
#+end_src
|
||||
|
||||
* Requirements
|
||||
|
||||
- Ansible >= 2.12
|
||||
- Debian-based OS (Bookworm, Trixie)
|
||||
- Debian 12+ or compatible
|
||||
- git
|
||||
- sudo
|
||||
- ca-certificates
|
||||
- (optional) PosgreSQL database
|
||||
- (optional) Nginx server
|
||||
- (optional) certbot for Let's Encrypt
|
||||
|
||||
* Variables
|
||||
|
||||
| Variable | Type | Comment |
|
||||
|-----------------------+--------+----------------------------------------------|
|
||||
|----------------------------------+---------+--------------------------------------------------|
|
||||
| gitea_user | string | Gitea user |
|
||||
| gitea_group | string | Gitea group |
|
||||
| gitea_binary_url | string | Download URL of Gitea |
|
||||
@@ -58,6 +73,19 @@ gitea_group: git
|
||||
| gitea_jwt_secret | string | JWT secret |
|
||||
| gitea_database_server | string | DB server - 'postgresql' or empty for sqlite |
|
||||
| gitea_db_password | string | PosgreSQL db password (if pgsql is used) |
|
||||
| gitea_reverse_proxy | string | Reverse proxy to use or not set for no proxy |
|
||||
| gitea_enable_https | boolean | Configure HTTPS in the proxy |
|
||||
| gitea_ssl_cert | string | SSL certificate |
|
||||
| gitea_ssl_key | string | SSL key |
|
||||
| gitea_enable_http_redirect | boolean | Redirect HTTP to HTTPS |
|
||||
| gitea_self_signed | boolean | Generate a self-signed cert and key |
|
||||
| gitea_lets_encrypt | boolean | Use certbot to configure the SSL |
|
||||
| gitea_certbot_email | string | Email to register the certificates |
|
||||
| gitea_require_signin_view | boolean | If false, public repos are visible without login |
|
||||
| gitea_disable_registration | boolean | Turn off the user registration feature |
|
||||
| gitea_register_manual_confirm | boolean | Registration requires admin verification |
|
||||
| gitea_enable_captcha | boolean | Enable captcha for registration |
|
||||
| gitea_default_keep_email_private | boolean | Default email policy: private |
|
||||
|
||||
* Handlers
|
||||
|
||||
@@ -66,9 +94,9 @@ gitea_group: git
|
||||
|
||||
* Secrets
|
||||
|
||||
Always store the production secrets in SOPS, or in Ansible Vault.
|
||||
Always save the production secrets in SOPS, or in Ansible Vault.
|
||||
|
||||
Generate the secrets manually when the playbook stops:
|
||||
You can generate the secrets manually when the playbook stops:
|
||||
|
||||
#+begin_src shell
|
||||
gitea generate secret INTERNAL_TOKEN
|
||||
@@ -81,6 +109,8 @@ Then re-run the playbook to finish the installation.
|
||||
|
||||
* Example Playbook
|
||||
|
||||
You can find more playbook examples in the =examples= directory.
|
||||
|
||||
#+begin_src yaml
|
||||
- name: Deploy a Gitea server
|
||||
hosts: gitea
|
||||
@@ -95,12 +125,25 @@ Then re-run the playbook to finish the installation.
|
||||
gitea_ssh_domain: gitea.tomsitcafe.com
|
||||
gitea_domain: gitea.tomsitcafe.com
|
||||
gitea_http_port: 3000
|
||||
gitea_root_url: http://gitea.tomsitcafe.com:3000
|
||||
gitea_root_url: https://gitea.tomsitcafe.com
|
||||
|
||||
# Optional
|
||||
# Optional Postgresql database backend
|
||||
gitea_database_server: postgresql
|
||||
|
||||
# In prod put these secrets in SOPS:
|
||||
# Optional Nginx reverse proxy configuration
|
||||
gitea_reverse_proxy: nginx
|
||||
gitea_enable_https: true # Use HTTPS
|
||||
gitea_self_signed: false # Don't generate self-signed certs
|
||||
gitea_lets_encrypt: true # Use certbot
|
||||
gitea_enable_http_redirect: true # Redirect HTTP to HTTPS
|
||||
|
||||
# Certbot configuration
|
||||
gitea_certbot_email: email@domain.tld
|
||||
gitea_ssl_cert: /etc/letsencrypt/live/{{ gitea_domain }}/fullchain.pem
|
||||
gitea_ssl_key: /etc/letsencrypt/live/{{ gitea_domain }}/privkey.pem
|
||||
gitea_ssl_trusted_certificate: /etc/letsencrypt/live/{{ gitea_domain }}/chain.pem
|
||||
|
||||
# In prod put the secrets in SOPS:
|
||||
gitea_lfs_jwt_secret: G9bZrRHMhRQ8w4R0KkH2VLnx2rzq81ROQ951IQjlMs4
|
||||
gitea_internal_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3NzA2Mzk1Njh9.ybbaeNLFiLbyvxfj4vkqhXSAXKRGpwvP8jIm9YLPgXw
|
||||
gitea_jwt_secret: uJni4x4e0AzpkLYc-t4keRJKOB6EaLzwVsdLeamkFyU
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
---
|
||||
gitea_user: git
|
||||
gitea_group: git
|
||||
gitea_http_port: 3000
|
||||
gitea_ssh_port: 22
|
||||
gitea_require_signin_view: true
|
||||
gitea_disable_registration: true
|
||||
gitea_register_manual_confirm: false
|
||||
gitea_enable_captcha: false
|
||||
gitea_default_keep_email_private: true
|
||||
|
||||
34
examples/certbot-playbook.yml
Normal file
34
examples/certbot-playbook.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
- name: Install Gitea
|
||||
hosts: gitea
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ds-postgresql
|
||||
- role: ds-nginx
|
||||
- role: ds-gitea
|
||||
vars:
|
||||
gitea_user: git
|
||||
gitea_group: git
|
||||
gitea_database_server: postgresql
|
||||
gitea_binary_url: https://dl.gitea.com/gitea/1.25.4/gitea-1.25.4-linux-amd64
|
||||
gitea_checksum_url: https://dl.gitea.com/gitea/1.25.4/gitea-1.25.4-linux-amd64.sha256
|
||||
gitea_app_name: Tom's IT Cafe Test Gitea Server
|
||||
gitea_domain: gitea.tomsitcafe.com
|
||||
gitea_ssh_domain: "{{ gitea_domain }}"
|
||||
gitea_http_port: 3000
|
||||
gitea_ssh_port: 22
|
||||
gitea_root_url: https://{{ gitea_domain }}
|
||||
gitea_reverse_proxy: nginx
|
||||
gitea_enable_https: true
|
||||
gitea_lets_encrypt: true
|
||||
gitea_enable_http_redirect: true
|
||||
gitea_certbot_email: tom@tomsitcafe.com
|
||||
gitea_ssl_cert: /etc/letsencrypt/live/{{ gitea_domain }}/fullchain.pem
|
||||
gitea_ssl_key: /etc/letsencrypt/live/{{ gitea_domain }}/privkey.pem
|
||||
gitea_ssl_trusted_certificate: /etc/letsencrypt/live/{{ gitea_domain }}/chain.pem
|
||||
# Secrets to SOPS
|
||||
gitea_lfs_jwt_secret: G9bZrRHMhRQ8w4R0KkH2VLnx2rzq81ROQ951IQjlMs4
|
||||
gitea_internal_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3NzA2Mzk1Njh9.ybbaeNLFiLbyvxfj4vkqhXSAXKRGpwvP8jIm9YLPgXw
|
||||
gitea_jwt_secret: uJni4x4e0AzpkLYc-t4keRJKOB6EaLzwVsdLeamkFyU
|
||||
gitea_db_password: Eegh7Aothooph7pa6eu7eitha_zaim0G
|
||||
21
examples/lightweight-playbook.yml
Normal file
21
examples/lightweight-playbook.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
- name: Install Gitea
|
||||
hosts: gitea
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ds-gitea
|
||||
vars:
|
||||
gitea_user: git
|
||||
gitea_group: git
|
||||
gitea_binary_url: https://dl.gitea.com/gitea/1.25.4/gitea-1.25.4-linux-amd64
|
||||
gitea_checksum_url: https://dl.gitea.com/gitea/1.25.4/gitea-1.25.4-linux-amd64.sha256
|
||||
gitea_app_name: Tom's IT Cafe Test Gitea Server
|
||||
gitea_domain: gitea.tomsitcafe.com
|
||||
gitea_ssh_domain: "{{ gitea_domain }}"
|
||||
gitea_http_port: 3000
|
||||
gitea_ssh_port: 22
|
||||
gitea_root_url: http://{{ gitea_domain }}:{{ gitea_http_port }}
|
||||
# Secrets to SOPS
|
||||
gitea_lfs_jwt_secret: G9bZrRHMhRQ8w4R0KkH2VLnx2rzq81ROQ951IQjlMs4
|
||||
gitea_internal_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3NzA2Mzk1Njh9.ybbaeNLFiLbyvxfj4vkqhXSAXKRGpwvP8jIm9YLPgXw
|
||||
gitea_jwt_secret: uJni4x4e0AzpkLYc-t4keRJKOB6EaLzwVsdLeamkFyU
|
||||
31
examples/self-signed-playbook.yml
Normal file
31
examples/self-signed-playbook.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
- name: Install Gitea
|
||||
hosts: gitea
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ds-postgresql
|
||||
- role: ds-nginx
|
||||
- role: ds-gitea
|
||||
vars:
|
||||
gitea_user: git
|
||||
gitea_group: git
|
||||
gitea_database_server: postgresql
|
||||
gitea_binary_url: https://dl.gitea.com/gitea/1.25.4/gitea-1.25.4-linux-amd64
|
||||
gitea_checksum_url: https://dl.gitea.com/gitea/1.25.4/gitea-1.25.4-linux-amd64.sha256
|
||||
gitea_app_name: Tom's IT Cafe Test Gitea Server
|
||||
gitea_domain: gitea.tomsitcafe.com
|
||||
gitea_ssh_domain: "{{ gitea_domain }}"
|
||||
gitea_http_port: 3000
|
||||
gitea_ssh_port: 22
|
||||
gitea_root_url: https://{{ gitea_domain }}
|
||||
gitea_reverse_proxy: nginx
|
||||
gitea_enable_https: true
|
||||
gitea_self_signed: true
|
||||
gitea_ssl_cert: /var/lib/gitea/certs/cert.pem
|
||||
gitea_ssl_key: /var/lib/gitea/certs/key.pem
|
||||
gitea_enable_http_redirect: true
|
||||
# Secrets to SOPS
|
||||
gitea_lfs_jwt_secret: G9bZrRHMhRQ8w4R0KkH2VLnx2rzq81ROQ951IQjlMs4
|
||||
gitea_internal_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3NzA2Mzk1Njh9.ybbaeNLFiLbyvxfj4vkqhXSAXKRGpwvP8jIm9YLPgXw
|
||||
gitea_jwt_secret: uJni4x4e0AzpkLYc-t4keRJKOB6EaLzwVsdLeamkFyU
|
||||
gitea_db_password: Eegh7Aothooph7pa6eu7eitha_zaim0G
|
||||
29
tasks/lets-encrypt.yml
Normal file
29
tasks/lets-encrypt.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- name: Install certbot
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- certbot
|
||||
state: present
|
||||
|
||||
- name: Ensure webroot directory exists
|
||||
ansible.builtin.file:
|
||||
path: /var/www/html/.well-known/acme-challenge
|
||||
state: directory
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: '0755'
|
||||
|
||||
- name: Obtain or renew TLS certificate (non-destructive)
|
||||
ansible.builtin.command:
|
||||
cmd: >
|
||||
certbot certonly
|
||||
--webroot
|
||||
-w /var/www/html
|
||||
-d {{ gitea_domain }}
|
||||
--agree-tos
|
||||
--email {{ gitea_certbot_email }}
|
||||
--non-interactive
|
||||
--keep-until-expiring
|
||||
register: certbot_result
|
||||
changed_when: "'Congratulations' in certbot_result.stdout"
|
||||
notify: Reload_nginx
|
||||
@@ -44,6 +44,28 @@
|
||||
- Reload_postgresql
|
||||
when: gitea_database_server | default('') == "postgresql"
|
||||
|
||||
- name: Set up the reverse proxy
|
||||
block:
|
||||
- name: Deploy the site configuration
|
||||
ansible.builtin.template:
|
||||
src: gitea.j2
|
||||
dest: /etc/nginx/sites-available/gitea
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Reload_nginx
|
||||
|
||||
- name: Enable the gitea site
|
||||
ansible.builtin.file:
|
||||
src: /etc/nginx/sites-available/gitea
|
||||
dest: /etc/nginx/sites-enabled/gitea
|
||||
state: link
|
||||
owner: root
|
||||
group: root
|
||||
force: true
|
||||
notify: Reload_nginx
|
||||
when: gitea_reverse_proxy | default('') == "nginx"
|
||||
|
||||
- name: Create the gitea group
|
||||
ansible.builtin.group:
|
||||
name: "{{ gitea_group }}"
|
||||
@@ -54,7 +76,8 @@
|
||||
name: "{{ gitea_user }}"
|
||||
group: "{{ gitea_group }}"
|
||||
home: /home/{{ gitea_user }}
|
||||
shell: /usr/sbin/nologin
|
||||
shell: /bin/bash
|
||||
password: '*'
|
||||
system: true
|
||||
create_home: true
|
||||
|
||||
@@ -71,6 +94,16 @@
|
||||
group: "{{ gitea_group }}"
|
||||
mode: '0750'
|
||||
|
||||
- name: Generate self-signed certificates
|
||||
ansible.builtin.include_tasks:
|
||||
file: self-signed-cert.yml
|
||||
when: gitea_self_signed | default(false)
|
||||
|
||||
- name: Configure the Let's Encrypt certificates
|
||||
ansible.builtin.include_tasks:
|
||||
file: lets-encrypt.yml
|
||||
when: gitea_lets_encrypt | default(false)
|
||||
|
||||
- name: Pause to generate and save the secrets in SOPS
|
||||
ansible.builtin.pause:
|
||||
prompt: |
|
||||
|
||||
18
tasks/self-signed-cert.yml
Normal file
18
tasks/self-signed-cert.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Create the certs directory
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/gitea/certs
|
||||
owner: "{{ gitea_user }}"
|
||||
group: "{{ gitea_group }}"
|
||||
mode: '0750'
|
||||
state: directory
|
||||
|
||||
- name: Generate the self-signed certs for Gitea
|
||||
ansible.builtin.command: >
|
||||
gitea cert
|
||||
--host {{ gitea_domain }},{{ gitea_ssh_domain }}
|
||||
--out /var/lib/gitea/certs/cert.pem
|
||||
--keyout /var/lib/gitea/certs/key.pem
|
||||
become_user: "{{ gitea_user }}"
|
||||
args:
|
||||
creates: /var/lib/gitea/certs/cert.pem
|
||||
@@ -50,14 +50,15 @@ ENABLED = false
|
||||
[service]
|
||||
REGISTER_EMAIL_CONFIRM = false
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
DISABLE_REGISTRATION = false
|
||||
DISABLE_REGISTRATION = {{ gitea_disable_registration }}
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
|
||||
ENABLE_CAPTCHA = false
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
DEFAULT_KEEP_EMAIL_PRIVATE = false
|
||||
ENABLE_CAPTCHA = {{ gitea_enable_captcha }}
|
||||
REQUIRE_SIGNIN_VIEW = {{ gitea_require_signin_view }}
|
||||
DEFAULT_KEEP_EMAIL_PRIVATE = {{ gitea_default_keep_email_private }}
|
||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||
DEFAULT_ENABLE_TIMETRACKING = true
|
||||
NO_REPLY_ADDRESS = noreply.localhost
|
||||
REGISTER_MANUAL_CONFIRM = {{ gitea_register_manual_confirm }}
|
||||
|
||||
[openid]
|
||||
ENABLE_OPENID_SIGNIN = false
|
||||
|
||||
72
templates/gitea.j2
Normal file
72
templates/gitea.j2
Normal file
@@ -0,0 +1,72 @@
|
||||
# {{ ansible_managed }}
|
||||
|
||||
{% if gitea_enable_https | default(false) %}
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name {{ gitea_domain }};
|
||||
|
||||
ssl_certificate {{ gitea_ssl_cert }};
|
||||
ssl_certificate_key {{ gitea_ssl_key }};
|
||||
{% if gitea_lets_encrypt | default(false) %}
|
||||
ssl_trusted_certificate {{ gitea_ssl_trusted_certificate }};
|
||||
{% endif %}
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
client_max_body_size 50M;
|
||||
|
||||
location / {
|
||||
client_max_body_size 512M;
|
||||
proxy_pass http://localhost:{{ gitea_http_port }};
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
{% if gitea_enable_http_redirect | default(true) %}
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{ gitea_domain }};
|
||||
|
||||
{% if gitea_lets_encrypt | default(false) %}
|
||||
# Allow Let's Encrypt to verify certificates
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /var/www/html;
|
||||
allow all;
|
||||
}
|
||||
|
||||
# Redirect everything else to HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
{% else %}
|
||||
return 301 https://$host$request_uri;
|
||||
{% endif %}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
# HTTP-only configuration
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{ gitea_domain }};
|
||||
|
||||
client_max_body_size 50M;
|
||||
|
||||
location / {
|
||||
client_max_body_size 512M;
|
||||
proxy_pass http://localhost:{{ gitea_http_port }};
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
@@ -3,6 +3,10 @@
|
||||
[Unit]
|
||||
Description=Gitea (Git with a cup of tea)
|
||||
After=network.target
|
||||
{% if gitea_database_server | default('') == "postgresql" %}
|
||||
Wants=postgresql.service
|
||||
After=postgresql.service
|
||||
{% endif %}
|
||||
|
||||
[Service]
|
||||
RestartSec=2s
|
||||
|
||||
Reference in New Issue
Block a user