commit 9d332d5ce98e5a938e6ac22181f59bf36112af10 Author: Felix Date: Mon Feb 10 19:52:12 2020 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e845c18 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +inventory diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..960a7c4 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,5 @@ +[defaults] +inventory=inventory + +[ssh_connection] +pipelining = True diff --git a/files/docker-compose.yml b/files/docker-compose.yml new file mode 100644 index 0000000..740fbe2 --- /dev/null +++ b/files/docker-compose.yml @@ -0,0 +1,30 @@ +version: "3.3" + +services: + + gitea: + image: gitea/gitea:1.10 + restart: always + volumes: + - ./volumes/gitea:/data + ports: + - "127.0.0.1:3000:3000" + - "222:22" + environment: + - GITEA_HOSTNAME=${GITEA_HOSTNAME} + depends_on: + - redis + - postfix + + redis: + image: redis:5.0-alpine + restart: always + command: redis-server --appendonly yes + volumes: + - ./volumes/redis:/data + + postfix: + image: mwader/postfix-relay + environment: + - POSTFIX_myhostname=${GITEA_HOSTNAME} + restart: "always" diff --git a/gitea.yml b/gitea.yml new file mode 100644 index 0000000..6ce81c9 --- /dev/null +++ b/gitea.yml @@ -0,0 +1,70 @@ +--- +- hosts: all + become: yes + + # Install python if required + # https://www.josharcher.uk/code/ansible-python-connection-failure-ubuntu-server-1604/ + gather_facts: False + pre_tasks: + - name: install python for Ansible + raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal python-setuptools) + args: + executable: /bin/bash + register: output + changed_when: output.stdout != "" + - setup: # gather facts + + tasks: + - name: create app folder + file: path={{item.path}} owner={{item.owner}} group={{item.owner}} state=directory mode='0755' + with_items: + - { path: '/gitea/', owner: 'root' } + - { path: '/gitea/volumes/', owner: 'root' } + + - name: add all templates + template: src={{item.src}} dest={{item.dest}} mode={{item.mode}} + with_items: + - { src: 'templates/gitea.conf', dest: '/etc/nginx/sites-enabled/gitea.conf', mode: '0600' } + - { src: 'templates/env', dest: '/gitea/.env', mode: '0600' } + + - name: copy all files + copy: src={{item.src}} dest={{item.dest}} mode={{item.mode}} + with_items: + - { src: 'files/docker-compose.yml', dest: '/gitea/docker-compose.yml', mode: '0755' } + + - name: install dependencies + apt: + pkg: ['docker-compose', 'docker.io', 'certbot', 'nginx', 'python-certbot-nginx'] + + - name: enable and start docker service + systemd: + name: docker + enabled: yes + state: started + + - name: start docker-compose + docker_compose: + project_src: /gitea/ + state: present + stopped: yes + services: nginx + + - name: request letsencrypt certificates + shell: certbot certonly --nginx --agree-tos -d '{{ domain }}' -m '{{ letsencrypt_contact_email }}' -n + + - name: start docker-compose + docker_compose: + project_src: /gitea/ + state: present + pull: yes + + - name: reload nginx config and certs + shell: nginx -s reload + + - name: renew gitea certificates + cron: + special_time=daily + name=certbot-renew-gitea + user=root + job="certbot certonly -d {{ domain }} -n --webroot --deploy-hook 'nginx -s reload'" + diff --git a/inventory.example b/inventory.example new file mode 100755 index 0000000..60b9b84 --- /dev/null +++ b/inventory.example @@ -0,0 +1,5 @@ +[peertube] +user@host domain=your_domain letsencrypt_contact_email=user@example.com + +[all:vars] +ansible_connection=ssh diff --git a/templates/env b/templates/env new file mode 100644 index 0000000..b09eb23 --- /dev/null +++ b/templates/env @@ -0,0 +1 @@ +GITEA_HOSTNAME={{ domain }} diff --git a/templates/gitea.conf b/templates/gitea.conf new file mode 100644 index 0000000..51989f0 --- /dev/null +++ b/templates/gitea.conf @@ -0,0 +1,49 @@ +server { + listen 80; + server_name {{ domain }}; + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + server_name {{ domain }}; + + ssl_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem; + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; + ssl_prefer_server_ciphers on; + + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:50m; + ssl_session_tickets off; + + ssl_stapling on; + ssl_stapling_verify on; + + add_header X-Frame-Options SAMEORIGIN; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header Strict-Transport-Security "max-age=15768000"; + add_header Referrer-Policy "same-origin"; + fastcgi_hide_header X-Powered-By; + server_tokens off; + + client_max_body_size 100M; + + # No compression for json to avoid BREACH attack. + gzip on; + gzip_types text/plain text/xml text/css application/xml application/javascript image/svg+xml image/svg; + gzip_proxied any; + gzip_vary on; + + location / { + proxy_pass http://127.0.0.1:3000; + } +}