first attempt at LEMP stack

This commit is contained in:
Mayel 2021-07-14 12:38:58 +02:00
parent 08fc5fe2c6
commit 45c07acf0b
7 changed files with 117 additions and 132 deletions

View File

@ -6,14 +6,14 @@ steps:
image: decentral1se/stack-ssh-deploy:latest
settings:
host: swarm-test.autonomic.zone
stack: wordpress
stack: lemp
generate_secrets: true
purge: true
deploy_key:
from_secret: drone_ssh_swarm_test
environment:
DOMAIN: wordpress.swarm-test.autonomic.zone
STACK_NAME: wordpress
DOMAIN: lemp.swarm-test.autonomic.zone
STACK_NAME: lemp
LETS_ENCRYPT_ENV: production
SECRET_DB_PASSWORD_VERSION: v1
SECRET_DB_ROOT_PASSWORD_VERSION: v1

View File

@ -1,43 +1,26 @@
TYPE=wordpress
TYPE=lemp
DOMAIN=wordpress.example.com
DOMAIN=example.com
## Domain aliases
#EXTRA_DOMAINS=', `www.wordpress.example.com`'
#EXTRA_DOMAINS=', `www.example.com`'
LETS_ENCRYPT_ENV=production
## Additional extensions
#PHP_EXTENSIONS="calendar"
## Extensions you do NOT need, out of this list of installed extensions: https://github.com/adhocore/docker-phpfpm#php80
#PHP_EXTENSIONS_TO_DISABLE="calendar"
SECRET_DB_ROOT_PASSWORD_VERSION=v1
SECRET_DB_PASSWORD_VERSION=v1
# Multisite
#WORDPRESS_CONFIG_EXTRA="\
# define('WP_CACHE', false);\
# define('WP_ALLOW_MULTISITE', true );"
# Multisite phase 2 (see README)
#WORDPRESS_CONFIG_EXTRA="\
# define('WP_CACHE', false);\
# define('WP_ALLOW_MULTISITE', true );\
# define('MULTISITE', true);\
# define('SUBDOMAIN_INSTALL', true);\
# define('DOMAIN_CURRENT_SITE', '${DOMAIN}');\
# define('PATH_CURRENT_SITE', '/');\
# define('SITE_ID_CURRENT_SITE', 1);\
# define('BLOG_ID_CURRENT_SITE', 1);\
# define('FORCE_SSL_ADMIN', true );\
# define('COOKIE_DOMAIN', \$_SERVER['HTTP_HOST']);"
# Local SMTP relay
#COMPOSE_FILE="compose.yml:compose.mailrelay.yml"
#SMTP_HOST="postfix_relay_app"
#MAIL_FROM="wordpress@example.com"
#MAIL_FROM="site@example.com"
# Remote SMTP relay
#COMPOSE_FILE="compose.yml:compose.mailrelay.yml:compose.smtp.yml"
#SMTP_HOST="mail.example.com"
#MAIL_FROM="wordpress@example.com"
#MAIL_FROM="site@example.com"
#SMTP_PORT=587
#SMTP_AUTH=on
#SMTP_TLS=on

View File

@ -1,14 +1,13 @@
# Wordpress
# PHP / LEMP
[![Build Status](https://drone.autonomic.zone/api/badges/coop-cloud/wordpress/status.svg)](https://drone.autonomic.zone/coop-cloud/wordpress)
Coöp Cloud + [Wordpress](https://wordpress.org) = 🥳
Coöp Cloud + [PHP](https://php.org) + MariaDB + Nginx = 🥳
<!-- metadata -->
- **Category**: Apps
- **Status**: ❶💚
- **Image**: [`wordpress`](https://hub.docker.com/_/wordpress), ❶💚, upstream
- **Image**: [`adhocore/phpfpm`](https://github.com/adhocore/docker-phpfpm), ❶💚, upstream
- **Healthcheck**: Yes
- **Backups**: Yes
- **Email**: ❶💚
@ -21,39 +20,15 @@ Coöp Cloud + [Wordpress](https://wordpress.org) = 🥳
1. Set up Docker Swarm and [`abra`][abra]
2. Deploy [`coop-cloud/traefik`][cc-traefik]
3. `abra app new wordpress --secrets` (optionally with `--pass` if you'd like
3. `abra app new lemp --secrets` (optionally with `--pass` if you'd like
to save secrets in `pass`)
4. `abra app YOURAPPDOMAIN config` - be sure to change `$DOMAIN` to something that resolves to
your Docker swarm box
5. `abra app YOURAPPDOMAIN deploy`
6. Open the configured domain in your browser to finish set-up
7. `abra app YOURAPPDOMAIN run app chown www-data:www-data /var/www/html/wp-content` to fix
file permissions (see #3)
6. Copy your site files using something like: `abra app YOURAPPDOMAIN cp index.html app:/var/www/html/`
6. Use [restore functionality](https://docs.coopcloud.tech/backup-restore/) to import a SQL file into the db
6. Open the configured domain in your browser to check all is good
## Running WP-CLI
`abra app YOURAPPDOMAIN wp 'core check-update --major'`
(the WP-CLI arguments need to be quoted, because of how `abra` handles
command-line arguments)
## Network (Multi-site)
_(Only tested using subdomains)_
1. Set up as above
2. `abra app YOURAPPDOMAIN config`, and uncomment the first `# Multisite` section
3. `abra app YOURAPPDOMAIN deploy`
4. Log into the Wordpress admin dashboard, go to Tools » Network Setup
5. Don't worry about the suggested file changes
6. `abra app YOURAPPDOMAIN config` again - comment out the first `# Multisite`
section in `.envrc`, uncomment the `# Multisite phase 2` section, and add
your multisite subdomain(s) to `EXTRA_DOMAINS` (beware the weird syntax..)
7. `abra app YOURAPPDOMAIN deploy`
## Installing a custom theme
`abra app YOURAPPDOMAIN cp ~/path/to/local/theme wordpress:/var/www/html/wp-content/themes/`
## Email

43
abra.sh
View File

@ -2,49 +2,14 @@ export PHP_UPLOADS_CONF_VERSION=v3
export ENTRYPOINT_CONF_VERSION=v2
export ENTRYPOINT_MAILRELAY_CONF_VERSION=v1
export MSMTP_CONF_VERSION=v3
sub_wp() {
CONTAINER=$(docker container ls -f "Name=${STACK_NAME}_app" --format '{{ .ID }}')
if [ -z "$CONTAINER" ]; then
error "Can't find a container for ${STACK_NAME}_app"
exit
fi
debug "Using Container ID ${CONTAINER}"
# FIXME 3wc: we're fighting the Wordpress image, which recommends a named
# volume for /var/www/html -- this used to work fine using --volumes-from
# because the actual MySQL password was inserted into the generated
# wp-config.php -- but as of Wordpress 5.7.0, wp-config loads data straight
# from the environment, which requires Docker secrets to work, which only work
# in swarm services (not one-off `docker run` commands). Defining a `cli`
# service in compose.yml almost works, but there's no volumes_from: in Compose
# V3, and without it then the `cli` service can't access Wordpress core.
# See https://git.autonomic.zone/coop-cloud/wordpress/issues/21
warning "Slowly looking up MySQL password..."
silence
abra__service_="app"
DB_PASSWORD="$(sub_app_run cat "/run/secrets/db_password")"
unsilence
# shellcheck disable=SC2154,SC2086
docker run -it \
--volumes-from "$CONTAINER" \
--network "container:$CONTAINER" \
-u xfs:xfs \
-e WORDPRESS_DB_HOST=db \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD="${DB_PASSWORD}" \
-e WORDPRESS_DB_NAME=wordpress \
-e WORDPRESS_CONFIG_EXTRA="${WORDPRESS_CONFIG_EXTRA}" \
wordpress:cli wp ${abra__args_[*]}
}
export NGINX_DEFAULT_CONF_VERSION=v1
abra_backup_app() {
_abra_backup_dir "app:/var/www/html/wp-content"
_abra_backup_dir "app:/var/www/html/"
}
abra_backup_db() {
_abra_backup_mysql "db" "wordpress"
_abra_backup_mysql "db" "site"
}
abra_backup() {
@ -72,7 +37,7 @@ abra_restore_db() {
DB_ROOT_PASSWORD=$(sub_app_run cat /run/secrets/db_root_password)
zcat "$@" | sub_app_run mysql -u root -p"$DB_ROOT_PASSWORD" wordpress
zcat "$@" | sub_app_run mysql -u root -p"$DB_ROOT_PASSWORD" site
success "Restored 'db'"
}

View File

@ -1,19 +1,18 @@
version: "3.8"
services:
app:
image: "wordpress:5.7.2"
backend:
image: adhocore/phpfpm:8.0
volumes:
- "wordpress_content:/var/www/html/wp-content/"
- "site_content:/var/www/html/"
networks:
- backend
- proxy
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD_FILE=/run/secrets/db_password
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_CONFIG_EXTRA=${WORDPRESS_CONFIG_EXTRA}
- PHP_EXTENSIONS
- DB_HOST=db
- DB_USER=site
- DB_PASSWORD_FILE=/run/secrets/db_password
- DB_NAME=site
- PHP_EXTENSIONS_TO_DISABLE
secrets:
- db_password
configs:
@ -25,28 +24,41 @@ services:
entrypoint: /docker-entrypoint.sh
depends_on:
- db
deploy:
update_config:
failure_action: rollback
order: start-first
labels:
- coop-cloud.${STACK_NAME}.backend.version=8.0-92fac7ac
frontend:
image: nginx:1.19.2
networks:
- proxy
deploy:
restart_policy:
condition: on-failure
labels:
- "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
# Redirect from EXTRA_DOMAINS to DOMAIN
- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true"
- "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}"
- coop-cloud.${STACK_NAME}.frontend.version=1.19.2-c628b67d
volumes:
- site_content:/var/www/html/
configs:
- source: nginx_default_conf
target: /etc/nginx/conf.d/default.conf
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
deploy:
update_config:
failure_action: rollback
order: start-first
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.${STACK_NAME}.tls=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
# 3wc: this rule works for routing, but not for generating certificates
# see https://git.autonomic.zone/coop-cloud/planning/issues/14
#- "traefik.http.routers.${STACK_NAME}.rule=HostRegexp(`{subdomain:.+}.${DOMAIN}`, `${DOMAIN}`)"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- coop-cloud.${STACK_NAME}.app.version=5.7.2-92fac7ac
db:
image: "mariadb:10.6"
volumes:
@ -55,8 +67,8 @@ services:
- backend
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_DATABASE=site
- MYSQL_USER=site
- MYSQL_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
@ -69,7 +81,7 @@ networks:
external: true
volumes:
mariadb:
wordpress_content:
site_content:
secrets:
db_root_password:
external: true
@ -82,6 +94,9 @@ configs:
name: ${STACK_NAME}_entrypoint_conf_${ENTRYPOINT_CONF_VERSION}
file: entrypoint.sh.tmpl
template_driver: golang
nginx_default_conf:
name: ${STACK_NAME}_nginx_default_conf_${NGINX_DEFAULT_CONF_VERSION}
file: default.conf
php_uploads_conf:
name: ${STACK_NAME}_php_uploads_conf_${PHP_UPLOADS_CONF_VERSION}
file: uploads.ini

51
default.conf Normal file
View File

@ -0,0 +1,51 @@
# edited copy of upstream default config
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /var/www/html;
index index.html index.htm;
try_files $uri $uri/ $uri.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root /var/www/html;
# }
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
try_files $uri = 404;
#root html;
fastcgi_pass backend:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}

View File

@ -1,13 +1,9 @@
#!/bin/bash
{{ if (env "PHP_EXTENSIONS") }}
docker-php-ext-install {{ env "PHP_EXTENSIONS" }}
{{ if (env "PHP_EXTENSIONS_TO_DISABLE") }}
docker-php-ext-disable {{ env "PHP_EXTENSIONS_TO_DISABLE" }}
{{ end }}
if [ -n "$@" ]; then
"$@"
fi
# Upstream ENTRYPOINT
# https://github.com/docker-library/wordpress/blob/master/php7.4/apache/Dockerfile#L120
/usr/local/bin/docker-entrypoint.sh apache2-foreground