diff --git a/files/docker-compose.yml b/files/docker-compose.yml index 543f35d..bceb2aa 100644 --- a/files/docker-compose.yml +++ b/files/docker-compose.yml @@ -44,6 +44,14 @@ services: - postgres - redis + grafana: + image: grafana/grafana:7.0.4 + restart: always + ports: + - 127.0.0.1:3002:3000 + volumes: + - ./volumes/grafana:/var/lib/grafana + postgres: image: postgres:12-alpine restart: always @@ -52,7 +60,6 @@ services: - POSTGRES_PASSWORD=${WEBLATE_POSTGRES_PASSWORD} volumes: - ./volumes/postgres:/var/lib/postgresql/data - restart: always redis: image: redis:5.0-alpine diff --git a/gitea.yml b/gitea.yml index 2fa41a5..80eda5c 100644 --- a/gitea.yml +++ b/gitea.yml @@ -16,20 +16,22 @@ tasks: - name: create app folder - file: path={{item.path}} state=directory + file: path={{item.path}} state=directory owner={{item.owner}} group={{item.owner}} with_items: - - { path: '/gitea/' } - - { path: '/gitea/volumes/' } - - { path: '/gitea/volumes/gitea/' } - - { path: '/gitea/volumes/redis/' } - - { path: '/gitea/volumes/weblate/' } - - { path: '/gitea/volumes/postgres/' } + - { path: '/gitea/', owner: 'root' } + - { path: '/gitea/volumes/', owner: 'root' } + - { path: '/gitea/volumes/gitea/', owner: 'root' } + - { path: '/gitea/volumes/redis/', owner: 'root' } + - { path: '/gitea/volumes/weblate/', owner: '1000' } + - { path: '/gitea/volumes/grafana/', owner: '472' } + - { path: '/gitea/volumes/postgres/', owner: '70' } - 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/weblate.conf', dest: '/etc/nginx/sites-enabled/weblate.conf', mode: '0600' } + - { src: 'templates/grafana.conf', dest: '/etc/nginx/sites-enabled/grafana.conf', mode: '0600' } - { src: 'templates/env', dest: '/gitea/.env', mode: '0600' } vars: weblate_admin_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/weblate_admin_password chars=ascii_letters,digits') }}" @@ -61,6 +63,7 @@ shell: | certbot certonly --nginx --agree-tos -d '{{ domain }}' -m '{{ letsencrypt_contact_email }}' -n certbot certonly --nginx --agree-tos -d 'weblate.{{ domain }}' -m '{{ letsencrypt_contact_email }}' -n + certbot certonly --nginx --agree-tos -d 'grafana.{{ domain }}' -m '{{ letsencrypt_contact_email }}' -n - name: start docker-compose docker_compose: diff --git a/templates/grafana.conf b/templates/grafana.conf new file mode 100644 index 0000000..7f0de45 --- /dev/null +++ b/templates/grafana.conf @@ -0,0 +1,49 @@ +server { + listen 80; + server_name grafana.{{ domain }}; + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + server_name grafana.{{ domain }}; + + ssl_certificate /etc/letsencrypt/live/grafana.{{ domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/grafana.{{ 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:3002; + } +}