]> gitweb.hamatoma.de Git - ansknife.git/commitdiff
wordpress_latest.yaml works main
authorHamatoma <author@hamatoma.de>
Thu, 25 Sep 2025 17:48:54 +0000 (19:48 +0200)
committerHamatoma <author@hamatoma.de>
Thu, 25 Sep 2025 17:48:54 +0000 (19:48 +0200)
docu/de/61_wordpress.md [new file with mode: 0644]
playbooks.templates/wordpress_create.yaml [new file with mode: 0644]
playbooks.templates/wordpress_latest.yaml [new file with mode: 0644]
templates.fix/nginx/wordpress.j2 [new file with mode: 0644]

diff --git a/docu/de/61_wordpress.md b/docu/de/61_wordpress.md
new file mode 100644 (file)
index 0000000..e8baddc
--- /dev/null
@@ -0,0 +1,17 @@
+# Wordpress-Installation
+
+## Installation
+```
+ansible-playbook playbooks/wordpress_create -e domain=www.example.de -e wp_version=6.8.2
+ansible-playbook playbooks/webapp_create -e webapp_name=www.example.de \
+  -e db_name=wpexample -e db_user=example -e db_password=TopSecret
+ansible-playbook playbooks/ssl_mult_cert.yaml domains=example.de,www.example.de
+# ODER (wenn kein zusätzliches www.*)
+ansible-playbook playbooks/ssl_create_certificate.yaml domain=example.de
+```
+- Kontrolle von /etc/nginx/sites-available/www.example.de
+- Wenn Domäne erreichbar:
+```
+ansible-playbook playbooks/lets_multi_cert.yaml domains=example.de,www.example.de
+# ODER (wenn kein zusätzliches www.*)
+ansible-playbook playbooks/lets_create.yaml domain=example.de
diff --git a/playbooks.templates/wordpress_create.yaml b/playbooks.templates/wordpress_create.yaml
new file mode 100644 (file)
index 0000000..ca5b92b
--- /dev/null
@@ -0,0 +1,62 @@
+---
+# Creates a wordpress website for a domain
+# needed facts (variables) from commandline: (e.g. -e domain=example.com
+# domain: the site domain name
+# wp_version: the version of the wordpress to install
+# wp_shortname: the short name of the wordpress site. Used for log file names.
+# optional:
+# wp_php_version: the php version to use. Default: 8.3
+- hosts: all
+  vars_files:
+    - ../vars/common.yaml
+    - ../vars/ssl-certificate.yaml
+  tasks:
+    - name: Check pre-requisites
+      fail: 
+        msg: "The variable 'domain', 'wp_version' and 'wp_shortname' must be defined: use -e domain=mydomain.com"
+      when: domain is not defined or domain == "" or wp_version is not defined or wp_version == "" or wp_shortname is not defined or wp_shortname == ""
+    - name: Is the zip file available?
+      ansible.builtin.stat:
+        path: "{{ remote_www_directory }}/packages/wordpress-{{ wp_version }}.zip"
+      register: wp_zip_file
+    - name: Fail if the zip file is not available
+      ansible.builtin.fail:
+        msg: "The wordpress zip file {{ remote_www_directory }}/packages/wordpress-{{ wp_version }}.zip is not available. Please download it first."
+      when: not wp_zip_file.stat
+    - name: Check whether the target directory already exists
+      ansible.builtin.stat:
+        path: "{{ remote_www_directory }}/{{ domain }}"
+      register: target_directory
+    - name: "Unarchive wordpress. Note: there is a wordpress subdirectory in the zip file"
+      ansible.builtin.unarchive:
+        src: "{{ remote_www_directory }}/packages/wordpress-{{ wp_version }}.zip"
+        dest: "{{ remote_www_directory }}"
+        remote_src: true
+        owner: www-data
+        group: www-data
+        mode: '0775'
+      when: not target_directory.stat.exists
+    - name: Rename the directory to the domain name
+      ansible.builtin.command:
+        cmd: mv {{ remote_www_directory }}/wordpress {{ remote_www_directory }}/{{ domain }}
+      when: not target_directory.stat.exists
+    - name: Create nginx site configuration
+      ansible.builtin.template:
+        src: ../templates.fix/nginx/wordpress.j2
+        dest: /etc/nginx/sites-available/{{ domain }}
+        owner: root
+        group: root
+        mode: '0644'
+      vars:
+        domain: "{{ domain }}"
+        shortname: "{{ wp_shortname }}"
+        php_version: "{{ wp_php_version | default('8.3') }}"
+
+    - name: Create symlink to sites-enabled
+      ansible.builtin.file:
+        src: "../sites-available/{{ domain }}"
+        dest: "/etc/nginx/sites-enabled/{{ domain }}"
+        state: link
+        force: true
+        follow: false
+     
diff --git a/playbooks.templates/wordpress_latest.yaml b/playbooks.templates/wordpress_latest.yaml
new file mode 100644 (file)
index 0000000..f5f7053
--- /dev/null
@@ -0,0 +1,38 @@
+---
+- name: Download WordPress page and extract version
+  hosts: all
+  gather_facts: false
+
+  tasks:
+    - name: Define the package directory
+      ansible.builtin.set_fact:
+        package_dir: "/srv/www/packages"
+        url_zip: "https://de.wordpress.org/latest-de_DE.zip"
+        url_page: "https://de.wordpress.org/download"
+    - name: Download the wordpress.org download page
+      ansible.builtin.uri:
+        url: "{{ url_page }}"
+        return_content: true
+      register: wordpress_page_content
+      delegate_to: localhost
+
+    - name: Extract the version number
+      ansible.builtin.set_fact:
+        wp_version: "{{ wordpress_page_content.content | regex_search('WordPress (\\d+\\.\\d+\\.\\d+) herunterladen') | regex_replace('[^.0-9]', '') }}"
+    - name: Display the extracted version
+      ansible.builtin.debug:
+        msg: "The latest WordPress version is {{ wp_version }}"
+    - name: Test wether the zip file is available
+      ansible.builtin.stat:
+        path: "{{ package_dir }}/wordpress-{{ wp_version }}.zip"
+      register: wp_zip_stat
+    - name: log the result of the stat
+      ansible.builtin.debug:
+        msg: "The file already exists: {{ package_dir }}/wordpress-{{ wp_version }}.zip"
+      when : wp_zip_stat.stat.exists
+    - name: Download the WordPress zip file if not already present
+      ansible.builtin.get_url:
+        url: "{{ url_zip }}"
+        dest: "{{ package_dir }}/wordpress-{{ wp_version }}.zip"
+      when: not wp_zip_stat.stat.exists
+
diff --git a/templates.fix/nginx/wordpress.j2 b/templates.fix/nginx/wordpress.j2
new file mode 100644 (file)
index 0000000..d8b69ac
--- /dev/null
@@ -0,0 +1,115 @@
+server {
+  listen 80;
+  server_name {{ domain }} www.{{ domain }};
+  include snippets/letsencrypt.conf;
+  location / {
+    return 301 https://{{ domain }}$request_uri;  # enforce https
+ }
+}
+server {
+  listen 443 ssl;
+  http2 on;
+  ssl_certificate     /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
+  ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;
+#  ssl_certificate /etc/ssl/certs/{{ domain }}.pem;
+#  ssl_certificate_key /etc/ssl/private/{{ domain }}.key;
+
+  server_name {{ domain }};
+  location / {
+    return 301 https://www.{{ domain }}$request_uri;
+  }
+}
+server {
+  listen 443 ssl;
+  http2 on;
+  ssl_certificate     /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
+  ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;
+#  ssl_certificate /etc/ssl/certs/{{ domain }}.pem;
+#  ssl_certificate_key /etc/ssl/private/{{ domain }}.key;
+
+  server_name www.{{ domain }};
+  root /srv/www/{{ domain }}/;
+
+
+  access_log  /var/log/nginx/a_{{ shortname }}.log;
+  error_log   /var/log/nginx/e_{{ shortname }}.log;
+
+  index index.php;
+  client_max_body_size 1G;
+  autoindex on;
+
+  # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
+  # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
+  
+  location ^~ /.well-known {
+    allow all;
+     if ($request_method = 'OPTIONS') {
+        add_header 'Access-Control-Allow-Origin' '*';
+        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
+        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
+        add_header 'Access-Control-Max-Age' 1728000;
+        add_header 'Content-Type' 'text/plain; charset=utf-8';
+        add_header 'Content-Length' 0;
+        return 204;
+     }
+     if ($request_method = 'POST') {
+        add_header 'Access-Control-Allow-Origin' '*' always;
+        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
+        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
+        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
+     }
+     if ($request_method = 'GET') {
+        add_header 'Access-Control-Allow-Origin' '*' always;
+        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
+        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
+        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
+     }
+
+  }
+  #location ~ /\. {
+  #  deny all;
+  #}
+
+  # Deny access to any files with a .php extension in the uploads directory
+  # Works in sub-directory installs and also in multisite network
+  # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
+  location ~* /(?:uploads|files)/.*\.php$ {
+    deny all;
+  }
+
+    location = /favicon.ico {
+        log_not_found off;
+        access_log off;
+    }
+
+    location = /robots.txt {
+        allow all;
+        log_not_found off;
+        access_log off;
+    }
+
+    location / {
+        # This is cool because no php is touched for static content.
+        # include the "?$args" part so non-default permalinks doesn't break when using query string
+        try_files $uri $uri/ /index.php?$args;
+    }
+
+    location ~ \.php$ {
+        #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
+        include fastcgi.conf;
+        fastcgi_intercept_errors on;
+        fastcgi_pass unix:/var/run/php/php{{ php_version }}-fpm.sock;
+        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+        fastcgi_param  HTTPS $fastcgi_https;
+        fastcgi_param HTTP_AUTHORIZATION $http_authorization;
+
+        fastcgi_buffers 16 16k;
+        fastcgi_buffer_size 32k;
+    }
+
+    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
+        expires max;
+        log_not_found off;
+    }
+}