diff --git a/ansible/.gitignore b/ansible/.gitignore new file mode 100644 index 00000000..ec2ba683 --- /dev/null +++ b/ansible/.gitignore @@ -0,0 +1 @@ +roles/nginx/files/ssl/* diff --git a/ansible/README.md b/ansible/README.md new file mode 100644 index 00000000..51caa13c --- /dev/null +++ b/ansible/README.md @@ -0,0 +1,38 @@ +# Ansible Playbook to install uptime kuma using docker + +This playbook comes with three roles + +1. docker (to install docker) +2. nginx (to install nginx using docker with ssl) +3. uptime kuma (to install uptime kuma using docker) + +To see more info see docker-compose, tasks and config files +I will try to make this readme better + +## To run it +1. install ansible see [here](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) +2. run `ansible-galaxy install -r ansible-requirements.yml` to get requirements +3. prepare inventory hosts +4. put your certificates in files section in nginx role with this structure below: +``` +ansible -> roles -> nginx -> files -> ssl -> .fullchain.pem +ansible -> roles -> nginx -> files -> ssl -> .privkey.pem +``` +5. to run playbook +```bash +ansible-playbook ./playbook.yml -i -e "kuma_domain=" -e "kuma_image_os=" -e "kuma_image_version=" +``` +you can use other ansible playbook options too + +> Note: Replace `` with your desired domain for uptime kuma + +> replace `` with a version from https://github.com/louislam/uptime-kuma/releases +> replace `` with one of options + +> `-e "kuma_image_os=" -e "kuma_image_version="` is not required and you can remove this part or change only one of them (kuma_image_os is debian & kuma_image_version is 1 by default) + +> If you are not using root user as your ansible_user use -bK option to become root + +> instead of `-e "kuma_image_os=" -e "kuma_image_version="` You can use `-e kuma_tag=` and replace `` with your desired tag (e.g. `latest`) + +> you can also create a yaml file with variables that you want to set & use it (also: ansible-vars) diff --git a/ansible/ansible-requirements.yml b/ansible/ansible-requirements.yml new file mode 100644 index 00000000..326654cc --- /dev/null +++ b/ansible/ansible-requirements.yml @@ -0,0 +1,6 @@ +roles: + - src: geerlingguy.docker + - src: geerlingguy.pip + +collections: + - name: community.docker diff --git a/ansible/playbook.yml b/ansible/playbook.yml new file mode 100644 index 00000000..dc21e249 --- /dev/null +++ b/ansible/playbook.yml @@ -0,0 +1,19 @@ +- name: install uptime kuma with nginx connected + hosts: all + + vars: + pip_install_packages: + - name: docker + docker_compose_version: "v2.0.1" + + tasks: + - name: Ensure {{inventory_hostname}} is set as hostname + hostname: + name: "{{inventory_hostname}}" + tags: ["hostname"] + + roles: + - {role: geerlingguy.docker, tags: ["docker"]} + - {role: geerlingguy.pip, tags: ["docker"]} + - {role: uptime-kuma, tags: ["kuma"]} + - {role: nginx, tags: ["nginx"]} diff --git a/ansible/roles/nginx/tasks/main.yml b/ansible/roles/nginx/tasks/main.yml new file mode 100644 index 00000000..ea0da9a3 --- /dev/null +++ b/ansible/roles/nginx/tasks/main.yml @@ -0,0 +1,22 @@ +- name: Ensure Volumes & Files directories exists + file: + dest: "{{item}}" + state: directory + loop: + - /compose + - /compose/volumes + - /compose/volumes/nginx + - /compose/volumes/nginx/log/{{ kuma_domain }} + +- name: Ensure nginx SSL certificates exist + copy: + src: ssl + dest: /compose/volumes/nginx + mode: 'preserve' + group: root + owner: root + +- name: Ensure config files are updated + template: + src: "nginx.conf" + dest: /compose/volumes/nginx/nginx.conf diff --git a/ansible/roles/nginx/templates/nginx.conf b/ansible/roles/nginx/templates/nginx.conf new file mode 100644 index 00000000..2e348623 --- /dev/null +++ b/ansible/roles/nginx/templates/nginx.conf @@ -0,0 +1,88 @@ +user nginx; +worker_processes auto; + +pid /var/run/nginx.pid; +error_log /var/log/nginx/error.log; + +events { + worker_connections 2048; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens off; + + default_type application/octet-stream; + + ### SSL Settings for all servers (https://ssl-config.mozilla.org/#server=nginx&server-version=1.17.2&config=intermediate) + # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate + ssl_certificate /etc/nginx/ssl/{{ kuma_domain }}.fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/{{ kuma_domain }}.privkey.pem; + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; # about 40000 sessions + ssl_session_tickets off; + + # intermediate configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + + # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/nginx/ssl/dhparam.pem (TODO: check if it's secure to use others DH parameters!) + # openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096 + ssl_dhparam /etc/nginx/ssl/dhparam.pem; + + # HSTS (ngx_http_headers_module is required) (63072000 seconds) + add_header Strict-Transport-Security "max-age=63072000" always; + + # OCSP stapling + ssl_stapling on; + ssl_stapling_verify on; + + log_format main '$remote_addr - $remote_user [$time_local] "$request_method $scheme://$host$request_uri $server_protocol" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" $request_time $upstream_response_time UPA:$upstream_addr BYS:$bytes_sent BYR:$request_length'; + access_log /var/log/nginx/access.log main; + + ### Set additional headers to be send to upstream + proxy_set_header Host $http_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; + + # Remove Headers that gonna be sent to client + proxy_hide_header X-Powered-By; + proxy_hide_header Server; + + # Redirect HTTP request to HTTPS + server { + listen 80 default_server; + server_name {{ kuma_domain }}; + return 302 https://$host$request_uri; + } + + server { + server_name {{ kuma_domain }}; + listen 443 ssl http2 default_server; + + access_log /var/log/nginx/{{ kuma_domain }}.access.log main; + error_log /var/log/nginx/{{ kuma_domain }}.error.log; + + location / { + # rewrite ^/(.*)/$ /$1 permanent; + ### redirect urls with trailing slash to non-trailing slash + # https://serverfault.dev/questions/597302/removing-the-trailing-slash-from-a-url-with-nginx + # location ~ (?.+)/$ { + # return 302 https://$host$no_slash; + # } + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://uptime-kuma:3001/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + } +} diff --git a/ansible/roles/uptime-kuma/defaults/main.yml b/ansible/roles/uptime-kuma/defaults/main.yml new file mode 100644 index 00000000..c2f5d1bc --- /dev/null +++ b/ansible/roles/uptime-kuma/defaults/main.yml @@ -0,0 +1,4 @@ +--- +kuma_image_version: '1' +kuma_image_os: 'debian' +kuma_tag: "{{kuma_image_version}}-{{kuma_image_os}}" diff --git a/ansible/roles/uptime-kuma/tasks/main.yml b/ansible/roles/uptime-kuma/tasks/main.yml new file mode 100644 index 00000000..11893e93 --- /dev/null +++ b/ansible/roles/uptime-kuma/tasks/main.yml @@ -0,0 +1,22 @@ +- name: Ensure Volumes & Files directories exists + file: + dest: "{{item}}" + state: directory + loop: + - /compose + - /compose/kuma + - /compose/volumes + - /compose/volumes/kuma + +- name: Ensure docker-compose file has been updated + template: + src: "{{item}}" + dest: /compose/kuma/ + loop: + - docker-compose.yml + +- name: Ensure uptime-kuma is up + community.docker.docker_compose: + state: present + project_src: /compose/kuma + pull: yes diff --git a/ansible/roles/uptime-kuma/templates/docker-compose.yml b/ansible/roles/uptime-kuma/templates/docker-compose.yml new file mode 100644 index 00000000..3357bdc6 --- /dev/null +++ b/ansible/roles/uptime-kuma/templates/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.3' +services: + uptime-kuma: + restart: always + networks: + - uptime-kuma + expose: + - 3001 + volumes: + - '/compose/volumes/uptime-kuma:/app/data' + container_name: uptime-kuma + image: 'louislam/uptime-kuma:{{kuma_tag}}' + + nginx: + ports: + - 443:443 + - 80:80 + networks: + - uptime-kuma + depends_on: + - uptime-kuma + restart: always + image: nginx:stable-alpine + volumes: + - '/compose/volumes/nginx/:/etc/nginx/' + - '/compose/volumes/nginx/log/{{ kuma_domain }}:/var/log/nginx/{{ kuma_domain }}/' + +networks: + uptime-kuma: