Add gitea role

Added base gitea docker setup role.

Adds automatic unattended setup with default admin account and optional
email notification setup.
This commit is contained in:
Marty Oehme 2021-12-08 09:16:32 +01:00
parent 12a3fa1e6f
commit 3a5b5680cf
Signed by: Marty
GPG key ID: B7538B8F50A1C800
10 changed files with 360 additions and 0 deletions

41
roles/gitea/README.md Normal file
View file

@ -0,0 +1,41 @@
# gitea
A relatively light-weight git server hosting.
## Defaults
```
gitea_upstream_file_dir: "{{ docker_stack_files_dir }}/{{ stack_name }}"
```
The on-target directory where the proxy configuration file should be stashed.
```
gitea_use_https: true
```
Whether the service should be reachable through http (port 80) or through https (port 443) and provision an https certificate. Usually you will want this to stay `true`.
```
gitea_version: latest
```
The docker image version to be used in stack creation.
```
subdomain_alias: git
```
If the deployed container should be served over a uri that is not the stack name.
By default, it will be set to `git.yourdomain.com` -
if this option is not set it will be served on `gitea.yourdomain.com` instead.
For now gitea will still need to be initially set up after installation.
This could be automated with the help of these commands:
```sh
docker run --name gitea -p 8080:3000 -e GITEA__security__INSTALL_LOCK=true -d gitea/gitea:1.14.2
$ docker exec gitea migrate
$ docker exec gitea gitea admin user create --admin --username root --password admin1234 --email admin@example.com
```

View file

@ -0,0 +1,24 @@
---
# never got around to removing the master tag from the images
gitea_version: latest
gitea_upstream_file_dir: "{{ docker_stack_files_dir }}/{{ stack_name }}"
gitea_use_https: true
# the subdomain link gitea will be reachable under
subdomain_alias: git
gitea_db_database: gitea
gitea_db_username: gitea
gitea_db_password: gitea
gitea_app_admin_username: Mygiteausername # can not be set to admin in Gitea
gitea_app_admin_password: Mygiteapassword
gitea_app_admin_email: myadmin@mydomain.mytld
# gitea_smtp_host: domain.com:port
# gitea_smtp_username: my@username.com
# gitea_smtp_password: <password>
# gitea_smtp_force_tls: false # forces tls if it is on a non-traditional tls port. Overwrites starttls so should generally be off

2
roles/gitea/files/gitea Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"

View file

@ -0,0 +1,62 @@
- name: Add admin user
community.docker.docker_container_exec:
container: "{{ gitea_app_container_name['stdout'] }}"
command: >
gitea admin user create --admin --username {{ gitea_app_admin_username }} --password {{ gitea_app_admin_password }} --email {{ gitea_app_admin_email }}
become: yes
listen: "no admin user"
## Register reverse proxy
- name: Ensure upstream directory exists
ansible.builtin.file:
path: "{{ gitea_upstream_file_dir }}"
state: directory
mode: '0755'
become: yes
listen: "update gitea upstream"
- name: Update upstream template
ansible.builtin.template:
src: upstream.json.j2
dest: "{{ gitea_upstream_file_dir }}/upstream.json"
mode: '0600'
become: yes
listen: "update gitea upstream"
# figure out if upstream id exists
- name: check {{ stack_name }} upstream
community.docker.docker_container_exec:
container: "{{ caddy_container_id }}"
command: >
curl localhost:2019/id/{{ stack_name }}_upstream/
changed_when: False
register: result
become: yes
listen: "update gitea upstream"
# upstream already exists, patch it
- name: remove old {{ stack_name }} upstream
community.docker.docker_container_exec:
container: "{{ caddy_container_id }}"
command: >
curl -X DELETE localhost:2019/id/{{ stack_name }}_upstream/
become: yes
when: (result.stdout | from_json)['error'] is not defined
listen: "update gitea upstream"
# upstream has to be created
- name: add {{ stack_name }} upstream
community.docker.docker_container_exec:
container: "{{ caddy_container_id }}"
command: >
curl -X POST -H "Content-Type: application/json" -d @{{ gitea_upstream_file_dir }}/upstream.json localhost:2019/config/apps/http/servers/{{ (gitea_use_https == True) | ternary(caddy_https_server_name, caddy_http_server_name) }}/routes/0/
become: yes
listen: "update gitea upstream"
- name: Ensure upstream directory is gone again
ansible.builtin.file:
path: "{{ gitea_upstream_file_dir }}"
state: absent
become: yes
listen: "update gitea upstream"

16
roles/gitea/meta/main.yml Normal file
View file

@ -0,0 +1,16 @@
---
galaxy_info:
author: Marty Oehme
description: Light-weight git hosting
license: GPL-3.0-only
min_ansible_version: 2.9
galaxy_tags: []
platforms:
- name: GenericLinux
versions: all
dependencies:
- docker
- docker-swarm
- caddy

View file

@ -0,0 +1,95 @@
---
- name: Ensure git user exists with ssh key
ansible.builtin.user:
name: "{{ gitea_git_username }}"
generate_ssh_key: yes
ssh_key_type: rsa
ssh_key_bits: 4096
ssh_key_comment: "Gitea Host Key"
become: yes
register: git_user
- name: Ensure git passthrough command directory exists
ansible.builtin.file:
path: "/app/gitea/"
state: directory
mode: '0770'
owner: "{{ git_user['uid'] }}"
group: "{{ git_user['group'] }}"
become: yes
- name: Save git passthrough command in right location
ansible.builtin.copy:
src: gitea
dest: "/app/gitea/gitea"
owner: "{{ git_user['uid'] }}"
group: "{{ git_user['group'] }}"
mode: '0750'
become: yes
- name: Fetch keyfile
fetch:
src: "{{ git_user['home'] }}/.ssh/id_rsa.pub"
dest: "buffer/{{ansible_hostname}}-id_rsa.pub"
flat: yes
become: yes
- name: Ensure git user has its own key authorized for access
ansible.posix.authorized_key:
user: "{{ git_user['name'] }}"
state: present
key: "{{ lookup('file', 'buffer/{{ ansible_hostname }}-id_rsa.pub') }}"
become: yes
- name: Clean up buffer dir
ansible.builtin.file:
path: buffer
state: absent
delegate_to: localhost
## install gitea container
- name: Check upstream status
community.docker.docker_container_exec:
container: "{{ caddy_container_id }}"
command: >
curl localhost:2019/id/{{ stack_name }}_upstream/
register: result
changed_when: (result.stdout | from_json) != (lookup('template', 'upstream.json.j2') | from_yaml)
become: yes
notify: "update gitea upstream"
- name: Deploy gitea to swarm
community.general.docker_stack:
name: "{{ stack_name }}"
state: present
prune: yes
compose:
- "{{ stack_compose }}"
become: yes
tags:
- docker-swarm
notify: "update gitea upstream"
- name: Get app container info
ansible.builtin.command:
cmd: docker ps -q -f name={{ stack_name }}_app
become: yes
until: gitea_app_container_name['rc'] == 0 and gitea_app_container_name['stdout'] | length >= 1
retries: 5
delay: 10
changed_when: False
register: gitea_app_container_name
- name: Look for existing admin user
community.docker.docker_container_exec:
container: "{{ gitea_app_container_name['stdout'] }}"
command: >
gitea admin user list --admin
become: yes
until: "'connection refused' not in gitea_admin_list and 'Failed to run app' not in gitea_admin_list"
retries: 5
delay: 10
changed_when: gitea_admin_list['stdout_lines'] | length <= 1
failed_when: gitea_admin_list['rc'] == 1 and gitea_admin_list['attempts'] >= 5
register: gitea_admin_list
notify: "no admin user"

View file

@ -0,0 +1,68 @@
version: '3.4'
services:
app:
image: "{{ stack_image }}:{{ gitea_version }}"
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "localhost:3000"]
interval: 1m
timeout: 10s
retries: 3
start_period: 1m
volumes:
- data:/data
- /home/git/.ssh:/data/git/.ssh
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
- USER_UID={{ git_user['uid'] }}
- USER_GID={{ git_user['group'] }}
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME={{ gitea_db_database }}
- GITEA__database__USER={{ gitea_db_username }}
- GITEA__database__PASSWD={{ gitea_db_password }}
- "GITEA__server__ROOT_URL={{ (gitea_use_https == True) | ternary('https', 'http') }}://{{ (subdomain_alias is not undefined and not none) | ternary(subdomain_alias, stack_name) }}.{{server_domain}}"
- "GITEA__server__SSH_DOMAIN={{ server_domain }}"
- GITEA__server__LANDINGPAGE=explore
- GITEA__service__DISABLE_REGISTRATION=true
{% if gitea_app_admin_username is not undefined and not None and gitea_app_admin_password is not undefined and not None %}
- GITEA__security__INSTALL_LOCK=true
{% endif %}
{% if gitea_smtp_host is not undefined and not None and gitea_smtp_username is not undefined and not None and gitea_smtp_password is not undefined and not None %}
- GITEA__mailer__ENABLED=true
- GITEA__service__ENABLE_NOTIFY_MAIL=true
- GITEA__mailer__FROM=gitea@{{ server_domain }}
- GITEA__mailer__TYPE=smtp
- GITEA__mailer__HOST={{ gitea_smtp_host }}
- GITEA__mailer__IS_TLS_ENABLED={{ (gitea_smtp_force_tls is not undefined and not None) | ternary(gitea_smtp_force_tls,'false') }}
- GITEA__mailer__USER={{ gitea_smtp_username }}
- GITEA__mailer__PASSWD={{ gitea_smtp_password }}
{% endif %}
networks:
- "{{ docker_swarm_public_network_name }}"
- backend
ports:
- "127.0.0.1:2222:22"
db:
image: postgres:13
volumes:
- db:/var/lib/postgresql/data
networks:
- backend
environment:
- POSTGRES_USER={{ gitea_db_username }}
- POSTGRES_PASSWORD={{ gitea_db_password }}
- POSTGRES_DB={{ gitea_db_database }}
volumes:
data:
db:
networks:
"{{ docker_swarm_public_network_name }}":
external: true
backend:

View file

@ -0,0 +1,38 @@
{
"@id": "{{ stack_name }}_upstream",
{% if server_domain is not undefined and not none %}
"match": [
{
"host": [
{% if subdomain_alias is not undefined and not none %}
"{{ subdomain_alias }}.{{ server_domain }}"
{% else %}
"{{ stack_name }}.{{ server_domain }}"
{% endif %}
]
}
],
{% else %}
"match": [
{
"path": [
{% if subdomain_alias is not undefined and not none %}
"/{{ subdomain_alias }}*"
{% else %}
"/{{ stack_name }}*"
{% endif %}
]
}
],
{% endif %}
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "{{ stack_name }}_app:3000"
}
]
}
]
}

View file

@ -0,0 +1,9 @@
---
stack_name: gitea
stack_image: "gitea/gitea"
stack_compose: "{{ lookup('template', 'docker-stack.yml.j2') | from_yaml }}"
gitea_git_username: git

View file

@ -73,3 +73,8 @@
import_role:
role: blog
tags: blog
- name: Install gitea
import_role:
role: gitea
tags: gitea