From 62af249e775451a0f5a4bbddc4239b69bd0b54df Mon Sep 17 00:00:00 2001 From: Adrien Luxey Date: Fri, 1 May 2020 15:40:16 +0200 Subject: [PATCH] new wordpress creation pipeline! --- ansible/README.md | 72 ++++++---- ansible/group_vars/all/vars.yml | 58 +++++--- ansible/group_vars/all/vault.yml | 62 +++++---- ansible/roles/build/tasks/drupal.yml | 2 +- ansible/roles/build/tasks/wordpress.yml | 94 +++++++++++-- .../templates/wordpress/docker-compose.yml.j2 | 25 +++- .../wordpress/{nginx.j2 => nginx.host.j2} | 2 +- .../templates/wordpress/nginx/Dockerfile.j2 | 5 + .../templates/wordpress/nginx/nginx.conf.j2 | 128 ++++++++++++++++++ .../wordpress/{ => site}/Dockerfile.j2 | 7 +- 10 files changed, 359 insertions(+), 96 deletions(-) rename ansible/roles/build/templates/wordpress/{nginx.j2 => nginx.host.j2} (96%) create mode 100644 ansible/roles/build/templates/wordpress/nginx/Dockerfile.j2 create mode 100644 ansible/roles/build/templates/wordpress/nginx/nginx.conf.j2 rename ansible/roles/build/templates/wordpress/{ => site}/Dockerfile.j2 (73%) diff --git a/ansible/README.md b/ansible/README.md index 38f6266..5de7c40 100644 --- a/ansible/README.md +++ b/ansible/README.md @@ -1,6 +1,23 @@ +# Deployer: deploy your shit and make it run + +So lame to have to configure nginx, MySQL, and your filesystem to install a stupid Wordpress instance. + +**Deployer** does my config for me like the slave it is. + +All the configuration is defined in `group_vars/all/vars.yml`, go check. + +Create a side `group_vars/all/vault.yml` for your secrets, and encrypt it with Ansible Vault: + + ansible-vault encrypt group_vars/all/vault.yml + # other sub-commands: edit, decrypt... + +I usually run the following command: + + ansible-playbook --ask-vault-pass sites.yml -i inventory -v + ## Required packages on remote -Python (installed with `pip` for user `adrien`): +Python modules: * docker * docker-compose @@ -8,38 +25,33 @@ Python (installed with `pip` for user `adrien`): TODO: Ansible task to install that before the rest -## Configure mailing +# Features -When I send mails from the container with `php`, with current `msmtp` config, it fails if the recipient isn't `@luxeylab.net`. +* Creating Wordpress instances (yoohoo, da best) -Host `mail.log`: - - # mail('adrien@yopmai.com'...) in container - Apr 2 09:07:56 Serenity postfix/smtpd[22617]: connect from unknown[172.27.1.2] - Apr 2 09:07:56 Serenity postfix/smtpd[22617]: NOQUEUE: reject: RCPT from unknown[172.27.1.2]: 454 4.7.1 : Relay access denied; from= to= proto=ESMTP helo= - Apr 2 09:07:56 Serenity postfix/smtpd[22617]: lost connection after DATA from unknown[172.27.1.2] - Apr 2 09:07:56 Serenity postfix/smtpd[22617]: disconnect from unknown[172.27.1.2] ehlo=1 mail=1 rcpt=0/1 data=0/1 commands=2/4 + * That send mail!!11!1! - # mail('adrien@yopmai.com'...) on host - Apr 2 09:10:33 Serenity postfix/cleanup[27364]: 5DB1D3CCDA: message-id=<20200402071033.5DB1D3CCDA@luxeylab.net> - Apr 2 09:10:33 Serenity postfix/qmgr[2066]: 5DB1D3CCDA: from=, size=286, nrcpt=1 (queue active) - Apr 2 09:10:33 Serenity postfix/smtp[27366]: 5DB1D3CCDA: to=, relay=smtp.yopmail.com[87.98.164.155]:25, delay=0.68, delays=0.35/0/0.23/0.09, dsn=2.0.0, status=sent (250 mail saved) - Apr 2 09:10:33 Serenity postfix/qmgr[2066]: 5DB1D3CCDA: removed +### Does not support - # mail('adrien@luxeylab.net'...) in container - Apr 2 08:08:12 Serenity postfix/smtpd[2647]: connect from unknown[172.27.1.2] - Apr 2 08:08:12 Serenity postfix/smtpd[2647]: 6BA723CCD8: client=unknown[172.27.1.2] - Apr 2 08:08:12 Serenity postfix/cleanup[5829]: 6BA723CCD8: message-id=<> - Apr 2 08:08:12 Serenity postfix/smtpd[2647]: disconnect from unknown[172.27.1.2] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5 - Apr 2 08:08:12 Serenity postfix/qmgr[2066]: 6BA723CCD8: from=, size=290, nrcpt=1 (queue active) - Apr 2 08:08:13 Serenity postfix/smtp[5831]: 6BA723CCD8: to=, orig_to=, relay=gmail-smtp-in.l.google.com[74.125.133.26]:25, delay=0.79, delays=0.23/0.03/0.11/0.42, dsn=2.0.0, status=sent (250 2.0.0 OK 1585807693 130si4035771wma.123 - gsmtp) - Apr 2 08:08:13 Serenity postfix/qmgr[2066]: 6BA723CCD8: removed +* Setting up the host -Good docs on the topic: +* SSL certificate creation (bro, do it yourself!). That is: -* [Explains postfix on Host+ssmtp in Docker in detail, poorly written](https://medium.com/@thilinaviraj950/configure-and-use-host-base-postfix-to-send-emails-from-a-container-18cd279fc460) -* [Another one](https://www.michelebologna.net/2019/send-an-email-from-a-docker-container/) - -I needed to add Docker's network (`172.0.0.0/8`) to `mynetworks` in `/etc/postfix/main.cf`. Also `inet_interfaces` would have had to be changed if Arthur didn't put it to `all`. - -**Now solved.** \ No newline at end of file + ```bash + # Make an nginx file for certbot + cat << EOF > /etc/nginx/sites-enabled/yoursite.com + server { + listen 80; + server_name www.yoursite.com yoursite.com; + include snippets/letsencrypt.conf; + } + EOF + nginx -t # Is everything alright? + # If so, restart nginx + service nginx restart + # Create the certificate + certbot certonly --webroot -w /var/www/letsencrypt -d yoursite.com -d www.yoursite.com + # Remove the stupid file + rm /etc/nginx/sites-enabled/yoursite.com + service nginx restart + ``` \ No newline at end of file diff --git a/ansible/group_vars/all/vars.yml b/ansible/group_vars/all/vars.yml index fada63a..66f9a74 100644 --- a/ansible/group_vars/all/vars.yml +++ b/ansible/group_vars/all/vars.yml @@ -3,7 +3,29 @@ www_path: /vault/www sites_path: /vault/sites +wordpress: + version: 5.4 + checksum: sha1:d5f1e6d7cadd72c11d086a2e1ede0a72f23d993e + sites: + - slug: test # Shorthand name to use as directory/file name + # The site URL (without www) + url: test.luxeylab.net + # Ask nginx to redirect url to www + # Else, we redirect www to url + redirect_to_www: no + # What kind of site is that? + type: wordpress + # Subnet addresses + subnet_cidr_address: 172.27.6.0/24 + subnet_gateway_ip: 172.27.6.1 + subnet_nginx_ip: 172.27.6.2 + subnet_site_ip: 172.27.6.3 + + mysql_database: wp_test + mysql_username: wp_test + mysql_password: "{{ vault_wp_test_mysql_password }}" + # - slug: rdb # Shorthand name to use as directory/file name # # The site URL (without www) # url: rennesdesbois.fr @@ -72,25 +94,25 @@ sites: # mysql_username: lexperimental # mysql_password: "{{ vault_lexperimental_mysql_password }}" - - slug: mts # Shorthand name to use as directory/file name - # The site URL (without www) - url: editionsmangetasoupe.fr - # Ask nginx to redirect url to www - # Else, we redirect www to url - redirect_to_www: no - # What kind of site is that? - type: drupal - # Subnet addresses - subnet_cidr_address: 172.27.5.0/24 - subnet_gateway_ip: 172.27.5.1 - subnet_site_ip: 172.27.5.2 + # - slug: mts # Shorthand name to use as directory/file name + # # The site URL (without www) + # url: editionsmangetasoupe.fr + # # Ask nginx to redirect url to www + # # Else, we redirect www to url + # redirect_to_www: no + # # What kind of site is that? + # type: drupal + # # Subnet addresses + # subnet_cidr_address: 172.27.5.0/24 + # subnet_gateway_ip: 172.27.5.1 + # subnet_site_ip: 172.27.5.2 - # This will allow setting up MySQL - # Configuration on Drupal's side must be done by hand: - # Edit your /sites/default/settings.php - mysql_database: mts8 - mysql_username: mts - mysql_password: "{{ vault_mts_mysql_password }}" + # # This will allow setting up MySQL + # # Configuration on Drupal's side must be done by hand: + # # Edit your /sites/default/settings.php + # mysql_database: mts8 + # mysql_username: mts + # mysql_password: "{{ vault_mts_mysql_password }}" mysql_root_password: "{{ vault_mysql_root_password }}" adrien_serenity_password: "{{ vault_adrien_serenity_password }}" \ No newline at end of file diff --git a/ansible/group_vars/all/vault.yml b/ansible/group_vars/all/vault.yml index c0d32dd..1a0749d 100644 --- a/ansible/group_vars/all/vault.yml +++ b/ansible/group_vars/all/vault.yml @@ -1,30 +1,34 @@ $ANSIBLE_VAULT;1.1;AES256 -30333835653963663535316564323735303838343861333835313232626632336635623361316534 -3931353931336638626634643133343865363539633266660a646339376138346330336232373139 -65393937643136623530663130626664666466623930376462613237616230343165346163383563 -3639336166373234360a306532306231333363333533373937613763626565353630626237373037 -66613537356339376131653239323330346530323137346430656635613331653261306234636432 -61663539656166613338333336323962623434656532323037356336346439386130313936613864 -39393466306635656532336162326266366361356530393264316437326335346439616136646665 -36356633643434326364346564613562356637663463653935616665373966386335373530323333 -30393138383365646438616265353165613233313039333538393634313330343565633161623266 -35656330383065373966383132323235663866613139613830333435393438333761313438663763 -66366166303462613666393936303966616338393166373539336464366361656530323335333934 -66366462323665326465353731666264383431623637373330343039666538313063396263373066 -38323366393738353763626436373830396462386566346535646663326233636462303164316561 -37646230663131643936376135343462363839336431353564303564373233376132346139326535 -33326165633239333864666233643466376164653835626262616264666434306530346462323464 -37643962656336356436616138626531396665616235353263326265326236383739363130386262 -65356238303437303232396639396563353836333937303836313637376139386239653465333962 -62346236353934396236366535323262643161336366326432363539386664323766633561363232 -30623364323035343830663362326466326433643165356435343965343162303965323063383732 -33373639343038663931646262373164356563366531656432626232343762396661386338386165 -35363666383164383031663532616563373735663565343130643638313739656266653336323339 -61383834653032643335653866653338643035376366373238343435653632383338346566643132 -39663234373637343565623431343366386635666635623838396163396137363465613438353737 -39353561656239636533613161316634633035626338663433626131613461346439353061373765 -65313632346339303164656561303538343937366264376665666364663762656435636166623861 -61346562366235343437636337306163326365666463343038633861333265623135356439313264 -32343036373433313331356566363636643237623835343033616338386336363465356233386431 -38313536323661623165623662616162396363396436613838663864613165653635663638353839 -30343333363633373338626535373034623738336463383266346464646434623731 +34386539366237643636326332343434623662373561336536363338373535393662323663656535 +6431333031393336353139616535363739343763356163620a356164313063616231373634393963 +30366366616539306438326563623832626666363562383334303961643862373736356337356635 +6461363664316566660a346539376262326438353933663333393137623438643166623335383236 +38643631363032636138333739353337633839303562383664366163303537633463663331313362 +30306132383465633434376236626562353935383463306333386538653436323832313063646162 +35653934306631383633636132666534373537316137623961653566303463376433373561323166 +38353034393830323165653130663063646135656137633434313066616663636635346431333138 +65633663626266613039323264653738316564643563303764646330643837383639646131643639 +36646664386138623565353864373235326362353537306133633663316238613862616464323732 +66383733306166633466333833643162353261356565326232356132303062623936663731663136 +36613261646130383632636165393061316235326435383064313233316639383830323165653265 +31383063303463303561383434623832323536336438623265316264623661653333323133356231 +64663734343333663130303565383466666436383964646564313932323637393136646165643634 +66636261663561613139393333326663646464303339323933663061383736343536623164356566 +36323534323666303532383333343363373666386565643566396636386265393232636233396133 +35393338613166653931666536663336633364383735303361636366656666636433356262656262 +34633534306239663563326566623161633363633466613764343836613331326265636439623530 +37326138393738316536393464643131653537663434323664343237393165613039646232343835 +34323036386232363437633966303861643962393337326332613334343431383231646465336334 +65396465373163643163313466376334646436386463373232613663393663373139356234326165 +64353633313832633335633830323337636130636431666263383061626231343138646665346136 +36323232373338373734333436656435646163393961633366613735616537656638633034373965 +38663662373736626561666239333733393630653439383265616433663934366435323136373963 +66303836363764393363383833323066616234316666303934626638363734346663616661616664 +36366635656534343738343234356363323032636435336433333135666232623231333739336262 +30636561613938396631623365613535656666313334663665363037636534353030626262313134 +62663931626661313231613235366364613635383638633265386330373731663738336435346537 +30393137373636363237643365626437623734376162626437306364313564616530663934343137 +33313065346465633933616134386434323031313239303736653564623833376563336361366164 +37666635643334663665633966653738616131643237343063326430326263363461303966333032 +64616336303361626336343930363666623565356431336461346132326636333636663730343934 +3666 diff --git a/ansible/roles/build/tasks/drupal.yml b/ansible/roles/build/tasks/drupal.yml index e39739b..bb50fef 100644 --- a/ansible/roles/build/tasks/drupal.yml +++ b/ansible/roles/build/tasks/drupal.yml @@ -3,7 +3,7 @@ path: "{{ sites_path }}/{{ item.slug }}" state: directory mode: '750' - tags: [docker, nginx] + tags: [docker, nginx, mysql] - name: Render sexy Dockerfile template: diff --git a/ansible/roles/build/tasks/wordpress.yml b/ansible/roles/build/tasks/wordpress.yml index 1226513..1b281c5 100644 --- a/ansible/roles/build/tasks/wordpress.yml +++ b/ansible/roles/build/tasks/wordpress.yml @@ -1,3 +1,59 @@ + + +- name: Is it a new install? + stat: + path: "{{ www_path }}/{{ item.slug }}_wp-content/index.php" + register: wpcontent + +- name: Populate wp-content folder + block: + - name: "Clear folder {{ www_path }}/{{ item.slug }}_wp-content" + file: + path: "{{ www_path }}/{{ item.slug }}_wp-content" + state: absent + - name: "Download Wordpress v{{ wordpress.version }} archive" + get_url: + url: "https://wordpress.org/wordpress-{{ wordpress.version }}.tar.gz" + dest: "/tmp/wordpress.tgz" + checksum: "{{ wordpress.checksum }}" + - name: "Extract Wordpress v{{ wordpress.version }} archive" + unarchive: + src: "/tmp/wordpress.tgz" + dest: /tmp + remote_src: yes + - name: "Copy wp-content folder to destination" + copy: + src: /tmp/wordpress/wp-content/ + dest: "{{ www_path }}/{{ item.slug }}_wp-content" + remote_src: yes + # group: www-data + # mode: '0660' + # directory_mode: '0770' + - name: Set proper access rights to wp-content tree + file: + path: "{{ www_path }}/{{ item.slug }}_wp-content" + state: directory + recurse: yes + group: www-data + mode: "u=rwX,g=rwX,o=" + + - name: "Remove downloaded content" + file: + path: "{{ toremove }}" + state: absent + loop: + - /tmp/wordpress.tgz + - /tmp/wordpress + loop_control: + loop_var: toremove + + when: wpcontent.stat.exists is not defined or wpcontent.stat.exists == False + tags: [docker, nginx] + +#################### +# Render templates # +#################### + - name: "Create folder {{ sites_path }}/{{ item.slug }}" file: path: "{{ sites_path }}/{{ item.slug }}" @@ -5,25 +61,39 @@ mode: '750' tags: [docker, nginx] -- name: Render sexy Dockerfile - template: - src: wordpress/Dockerfile.j2 - dest: "{{ sites_path }}/{{ item.slug }}/Dockerfile" - tags: docker +- name: "Create {{ sites_path }}/{{ item.slug }} sub-directories" + file: + path: "{{ sites_path }}/{{ item.slug }}/{{ filetree_item.path }}" + state: directory + mode: "{{ filetree_item.mode }}" + with_filetree: "../templates/wordpress/" + loop_control: + loop_var: filetree_item + when: filetree_item.state == 'directory' + tags: [docker, nginx] -- name: Render marvelous docker-compose.yml +- name: Render template files template: - src: wordpress/docker-compose.yml.j2 - dest: "{{ sites_path }}/{{ item.slug }}/docker-compose.yml" - tags: docker + src: "{{ filetree_item.src }}" + dest: "{{ sites_path }}/{{ item.slug }}/{{ filetree_item.path | regex_replace('.j2','') }}" + mode: "{{ filetree_item.mode }}" + with_filetree: "../templates/wordpress/" + loop_control: + loop_var: filetree_item + when: filetree_item.state == 'file' + tags: [docker, nginx] -- name: Render swell nginx site config - template: - src: wordpress/nginx.j2 +- name: Copy host config to /etc/nginx/sites-available + copy: + remote_src: yes + src: "{{ sites_path }}/{{ item.slug }}/nginx.host" dest: "/etc/nginx/sites-available/{{ item.url }}" become: yes tags: nginx + + + # - name: Create Let's Encrypt certificate # This seems hard, see: # https://docs.ansible.com/ansible/latest/modules/acme_certificate_module.html#acme-certificate-module diff --git a/ansible/roles/build/templates/wordpress/docker-compose.yml.j2 b/ansible/roles/build/templates/wordpress/docker-compose.yml.j2 index 8511983..6e9544b 100644 --- a/ansible/roles/build/templates/wordpress/docker-compose.yml.j2 +++ b/ansible/roles/build/templates/wordpress/docker-compose.yml.j2 @@ -1,11 +1,13 @@ version: '3' # Generated by ansible for site {{ item.url }} -# At {{ item.subnet_site_ip }} on {{ item.subnet_cidr_address }} +# On network {{ item.subnet_cidr_address }}: +# - web server (nginx) at {{ item.subnet_nginx_ip }} +# - php-fpm (wordpress) at {{ item.subnet_site_ip }} services: - wp: - build: . + site: + build: site restart: always environment: WORDPRESS_DB_HOST: "{{ item.subnet_gateway_ip }}" @@ -13,14 +15,31 @@ services: WORDPRESS_DB_PASSWORD: "{{ item.mysql_password }}" WORDPRESS_DB_NAME: "{{ item.mysql_database }}" volumes: + - "html_data:/var/www/html" - "{{ www_path }}/{{ item.slug }}_wp-content:/var/www/html/wp-content" networks: net: ipv4_address: "{{ item.subnet_site_ip }}" + nginx: + build: nginx + restart: always + depends_on: + - site + volumes: + - "html_data:/var/www/html" + - "{{ www_path }}/{{ item.slug }}_wp-content:/var/www/html/wp-content" + networks: + net: + ipv4_address: "{{ item.subnet_nginx_ip }}" + + networks: net: ipam: driver: default config: - subnet: "{{ item.subnet_cidr_address }}" + +volumes: + html_data: diff --git a/ansible/roles/build/templates/wordpress/nginx.j2 b/ansible/roles/build/templates/wordpress/nginx.host.j2 similarity index 96% rename from ansible/roles/build/templates/wordpress/nginx.j2 rename to ansible/roles/build/templates/wordpress/nginx.host.j2 index 6fa86f7..52ab372 100644 --- a/ansible/roles/build/templates/wordpress/nginx.j2 +++ b/ansible/roles/build/templates/wordpress/nginx.host.j2 @@ -49,7 +49,7 @@ server { location / { include snippets/header-params_location.conf; - proxy_pass http://{{ item.subnet_site_ip }}:80; + proxy_pass http://{{ item.subnet_nginx_ip }}:80; } } diff --git a/ansible/roles/build/templates/wordpress/nginx/Dockerfile.j2 b/ansible/roles/build/templates/wordpress/nginx/Dockerfile.j2 new file mode 100644 index 0000000..1201821 --- /dev/null +++ b/ansible/roles/build/templates/wordpress/nginx/Dockerfile.j2 @@ -0,0 +1,5 @@ +FROM nginx:latest +COPY nginx.conf /etc/nginx/nginx.conf + +# Should be UID & GID=33 +# USER www-data:www-data \ No newline at end of file diff --git a/ansible/roles/build/templates/wordpress/nginx/nginx.conf.j2 b/ansible/roles/build/templates/wordpress/nginx/nginx.conf.j2 new file mode 100644 index 0000000..f83e748 --- /dev/null +++ b/ansible/roles/build/templates/wordpress/nginx/nginx.conf.j2 @@ -0,0 +1,128 @@ +user www-data www-data; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + + +http { + charset utf-8; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 15s; + types_hash_max_size 2048; + server_tokens off; + client_max_body_size 10M; + client_body_timeout 60; + # server_names_hash_bucket_size 64; + server_name_in_redirect off; + + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + + include /etc/nginx/conf.d/*.conf; + + + server { + listen 80 default; + listen [::]:80 default; + server_name {{ item.url }} www.{{ item.url }}; + + root /var/www/html; + index index.php; + + # Restrictions + location = /favicon.ico { + log_not_found off; + access_log off; + } + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + location ~ /\. { + deny all; + } + location = /_.gif { + expires max; + empty_gif; + } + location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { + expires max; + log_not_found off; + } + location ~* /(?:uploads|files)/.*\.php$ { + deny all; + } + # XMLRPC is a great way to bruteforce passwords + location = /xmlrpc.php { + deny all; + } + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + # regex to split $uri to $fastcgi_script_name and $fastcgi_path + fastcgi_split_path_info ^(.+\.php)(/.+)$; + + # Check that the PHP script exists before passing it + # Breaks site... + # try_files $fastcgi_script_name =404; + + # Block httpoxy attacks. See https://httpoxy.org/ : + fastcgi_param HTTP_PROXY ""; + + # Bypass the fact that try_files resets $fastcgi_path_info + # see: http://trac.nginx.org/nginx/ticket/321 + set $path_info $fastcgi_path_info; + fastcgi_param PATH_INFO $path_info; + + # Do not diplay errors: + # fastcgi_intercept_errors on; + + fastcgi_index index.php; + + include fastcgi_params; + + fastcgi_pass site:9000; + + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + } +} \ No newline at end of file diff --git a/ansible/roles/build/templates/wordpress/Dockerfile.j2 b/ansible/roles/build/templates/wordpress/site/Dockerfile.j2 similarity index 73% rename from ansible/roles/build/templates/wordpress/Dockerfile.j2 rename to ansible/roles/build/templates/wordpress/site/Dockerfile.j2 index 4ecbbf3..2220d0a 100644 --- a/ansible/roles/build/templates/wordpress/Dockerfile.j2 +++ b/ansible/roles/build/templates/wordpress/site/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM wordpress:apache +FROM wordpress:{{ wordpress.version }}-fpm RUN apt-get update; \ apt-get install -y --no-install-recommends msmtp; \ @@ -16,4 +16,7 @@ RUN echo "\ account default\n\ host {{ item.subnet_gateway_ip }}\n\ port 25\n\ -from php@{{ item.url }}\n" > /etc/msmtprc \ No newline at end of file +from php@{{ item.url }}\n" > /etc/msmtprc + +# Should be UID & GID=33 +# USER www-data:www-data \ No newline at end of file