#16 php7.3-fpm, doc updates

Move to php7.3-fpm for WordPress, update the documentation, add script to clean up environment
This commit is contained in:
Michael J. Stealey
2019-01-28 11:18:37 -05:00
parent 4d168dbb72
commit 3dc642271d
10 changed files with 572 additions and 204 deletions
+15
View File
@@ -0,0 +1,15 @@
# wordpress - wordpress:php7.3-fpm
WORDPRESS_DB_NAME=wordpress
WORDPRESS_TABLE_PREFIX=wp_
WORDPRESS_DB_HOST=mysql
WORDPRESS_DB_USER=root
WORDPRESS_DB_PASSWORD=password
# mariadb - mariadb:latest
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=root
MYSQL_PASSWORD=password
MYSQL_DATABASE=wordpress
# nginx - nginx:latest
NGINX_DEFAULT_CONF=./nginx/default.conf
+198
View File
@@ -0,0 +1,198 @@
# Console output
Example console output from the described commands in the README file.
## <a name="tldr"></a>TL;DR output
Running the commands from the top level of the repository should yeild.
```console
$ mkdir -p certs/ certs-data/ logs/nginx/ mysql/ wordpress/
$ docker-compose up -d
Creating network "wordpress-nginx-docker_default" with the default driver
Creating mysql ... done
Creating wordpress ... done
Creating nginx ... done
```
After a few moments you should see your site running at [http://127.0.0.1](http://127.0.0.1) ready to be configured.
<img width="80%" alt="tl;dr running site" src="https://user-images.githubusercontent.com/5332509/51803325-cc65ce80-2221-11e9-8789-6dd4e802464c.png">
A deeper look into the container logs would show the full setup and chain of events between the containers.
- **Note** that the wordpress container will show a `Connection Error` until the database has finished running it's internal setup and makes port 3306 available for connections
```console
$ docker-compose logs
Attaching to nginx, wordpress, mysql
wordpress | WordPress not found in /var/www/html - copying now...
wordpress | Complete! WordPress has been successfully copied to /var/www/html
wordpress |
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress |
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress |
wordpress |
wordpress | Warning: mysqli::__construct(): (HY000/2002): Connection refused in Standard input code on line 22
wordpress | MySQL Connection Error: (2002) Connection refused
wordpress | [27-Jan-2019 15:46:42] NOTICE: fpm is running, pid 1
wordpress | [27-Jan-2019 15:46:42] NOTICE: ready to handle connections
wordpress | 172.19.0.4 - 27/Jan/2019:15:52:24 +0000 "GET /index.php" 302
wordpress | 172.19.0.4 - 27/Jan/2019:15:52:24 +0000 "GET /wp-admin/install.php" 200
wordpress | 172.19.0.4 - 27/Jan/2019:15:52:26 +0000 "GET /index.php" 200
mysql | Initializing database
mysql |
mysql |
mysql | PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !
mysql | To do so, start the server, then issue the following commands:
mysql |
mysql | '/usr/bin/mysqladmin' -u root password 'new-password'
mysql | '/usr/bin/mysqladmin' -u root -h password 'new-password'
mysql |
mysql | Alternatively you can run:
mysql | '/usr/bin/mysql_secure_installation'
mysql |
mysql | which will also give you the option of removing the test
mysql | databases and anonymous user created by default. This is
mysql | strongly recommended for production servers.
mysql |
mysql | See the MariaDB Knowledgebase at http://mariadb.com/kb or the
mysql | MySQL manual for more instructions.
mysql |
mysql | Please report any problems at http://mariadb.org/jira
mysql |
mysql | The latest information about MariaDB is available at http://mariadb.org/.
mysql | You can find additional information about the MySQL part at:
mysql | http://dev.mysql.com
mysql | Consider joining MariaDB's strong and vibrant community:
mysql | https://mariadb.org/get-involved/
mysql |
mysql | Database initialized
mysql | MySQL init process in progress...
mysql | 2019-01-27 15:46:20 0 [Note] mysqld (mysqld 10.3.12-MariaDB-1:10.3.12+maria~bionic) starting as process 105 ...
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Using Linux native AIO
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Uses event mutexes
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Number of pools: 1
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Using SSE2 crc32 instructions
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: Completed initialization of buffer pool
mysql | 2019-01-27 15:46:20 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
mysql | 2019-01-27 15:46:21 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
mysql | 2019-01-27 15:46:21 0 [Note] InnoDB: Creating shared tablespace for temporary tables
mysql | 2019-01-27 15:46:21 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
mysql | MySQL init process in progress...
mysql | 2019-01-27 15:46:22 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
mysql | 2019-01-27 15:46:22 0 [Note] InnoDB: Waiting for purge to start
mysql | 2019-01-27 15:46:22 0 [Note] InnoDB: 10.3.12 started; log sequence number 1630824; transaction id 21
mysql | 2019-01-27 15:46:22 0 [Note] Plugin 'FEEDBACK' is disabled.
mysql | 2019-01-27 15:46:22 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
mysql | 2019-01-27 15:46:22 0 [Note] InnoDB: Buffer pool(s) load completed at 190127 15:46:22
mysql | 2019-01-27 15:46:22 0 [Warning] 'user' entry 'root@fc9f819a3e8c' ignored in --skip-name-resolve mode.
mysql | 2019-01-27 15:46:22 0 [Warning] 'user' entry '@fc9f819a3e8c' ignored in --skip-name-resolve mode.
mysql | 2019-01-27 15:46:22 0 [Warning] 'proxies_priv' entry '@% root@fc9f819a3e8c' ignored in --skip-name-resolve mode.
mysql | 2019-01-27 15:46:22 0 [Note] Reading of all Master_info entries succeded
mysql | 2019-01-27 15:46:22 0 [Note] Added new Master_info '' to hash table
mysql | 2019-01-27 15:46:22 0 [Note] mysqld: ready for connections.
mysql | Version: '10.3.12-MariaDB-1:10.3.12+maria~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 0 mariadb.org binary distribution
mysql | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
mysql | 2019-01-27 15:46:38 10 [Warning] 'proxies_priv' entry '@% root@fc9f819a3e8c' ignored in --skip-name-resolve mode.
mysql |
mysql | 2019-01-27 15:46:38 0 [Note] mysqld (initiated by: unknown): Normal shutdown
mysql | 2019-01-27 15:46:38 0 [Note] Event Scheduler: Purging the queue. 0 events
mysql | 2019-01-27 15:46:38 0 [Note] InnoDB: FTS optimize thread exiting.
mysql | 2019-01-27 15:46:38 0 [Note] InnoDB: Starting shutdown...
mysql | 2019-01-27 15:46:38 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
mysql | 2019-01-27 15:46:38 0 [Note] InnoDB: Buffer pool(s) dump completed at 190127 15:46:38
mysql | 2019-01-27 15:46:38 0 [Note] InnoDB: Shutdown completed; log sequence number 1630833; transaction id 24
mysql | 2019-01-27 15:46:38 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
mysql | 2019-01-27 15:46:38 0 [Note] mysqld: Shutdown complete
mysql |
mysql |
mysql | MySQL init process done. Ready for start up.
mysql |
mysql | 2019-01-27 15:46:39 0 [Note] mysqld (mysqld 10.3.12-MariaDB-1:10.3.12+maria~bionic) starting as process 1 ...
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Using Linux native AIO
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Uses event mutexes
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Number of pools: 1
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Using SSE2 crc32 instructions
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Completed initialization of buffer pool
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Creating shared tablespace for temporary tables
mysql | 2019-01-27 15:46:39 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
mysql | 2019-01-27 15:46:40 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
mysql | 2019-01-27 15:46:40 0 [Note] InnoDB: Waiting for purge to start
mysql | 2019-01-27 15:46:40 0 [Note] InnoDB: 10.3.12 started; log sequence number 1630833; transaction id 21
mysql | 2019-01-27 15:46:40 0 [Note] Plugin 'FEEDBACK' is disabled.
mysql | 2019-01-27 15:46:40 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
mysql | 2019-01-27 15:46:40 0 [Note] Server socket created on IP: '::'.
mysql | 2019-01-27 15:46:40 0 [Note] InnoDB: Buffer pool(s) load completed at 190127 15:46:40
mysql | 2019-01-27 15:46:40 0 [Warning] 'proxies_priv' entry '@% root@fc9f819a3e8c' ignored in --skip-name-resolve mode.
mysql | 2019-01-27 15:46:40 0 [Note] Reading of all Master_info entries succeded
mysql | 2019-01-27 15:46:40 0 [Note] Added new Master_info '' to hash table
mysql | 2019-01-27 15:46:40 0 [Note] mysqld: ready for connections.
mysql | Version: '10.3.12-MariaDB-1:10.3.12+maria~bionic' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
```
## <a name="stop-and-remove"></a>`stop-and-remove.sh` output
A script to stop and remove the running WordPress site has been provided.
Example usage:
```console
$ ./stop-and-remove.sh
Do you really want to stop and remove EVERYTHING (y/n)? y
INFO: Stopping containers
Stopping nginx ... done
Stopping wordpress ... done
Stopping mysql ... done
INFO: Removing containers
Going to remove nginx, wordpress, mysql
Removing nginx ... done
Removing wordpress ... done
Removing mysql ... done
INFO: Setting file permissions to that of the user
INFO: Pruning unused docker volumes
Total reclaimed space: 0B
INFO: Pruning unused docker networks
Deleted Networks:
wordpress-nginx-docker_default
INFO: Removing directories and contents (certs/ certs-data/ logs/nginx/ mysql/ wordpress/)
INFO: Done
```
+244 -150
View File
@@ -1,24 +1,48 @@
# Wordpress: with Nginx web server in Docker
# WordPress: with Nginx web server in Docker
This project is a docker compose installation of a single site Wordpress instance using Nginx as the web server and MariaDB as the database.
This project is a docker compose installation of a single site WordPress instance using Nginx as the web server and MariaDB as the database.
- Let's Encrypt SSL enabled option using [https://hub.docker.com/r/certbot/certbot/](https://hub.docker.com/r/certbot/certbot/)
- Work inspired by: [Dockerizing Wordpress with Nginx and PHP-FPM on Ubuntu 16.04](https://www.howtoforge.com/tutorial/dockerizing-wordpress-with-nginx-and-php-fpm/)
- Work inspired by: [Dockerizing WordPress with Nginx and PHP-FPM on Ubuntu 16.04](https://www.howtoforge.com/tutorial/dockerizing-wordpress-with-nginx-and-php-fpm/)
**What is Wordpress?**
**What is WordPress?**
- WordPress is open source software you can use to create a beautiful website, blog, or app.
- More information at [https://wordpress.org](https://wordpress.org)
## Installation
## Table of Contents
Review the [Optional configuration](#opt_config) section to determine which apply to your deployment.
- [TL;DR](#tldr) - I don't want details and just want to run WordPress locally using http
- [Setup and configuration](#setup) - environment and configuration setup options
- [HTTP or HTTPS?](#http-or-https) - http or https (via Let's Encrypt) to serve your content
- [SSL certificates](#ssl-certs) - secure socket layer encryption options
- [Let's Encrypt initialization](#lets-encrypt) - use Let's Encrypt for SSL certificates
- [Let's Encrypt renewal](#renew) - how to renew your Let's Encrypt certificates
- [.env](#dotenv) - variable declaration for docker-compose to use
- [Deploy](#deploy) - deploying your WordPress site
- [Running site](#site) - what to expect after you deploy
- [Stop and remove](#stop-and-remove) - clear all files associated with running the site
- [Configuration options](#opt-config) - additional options for deploying your site
- [Debugging tips](#debug) - basic tips for debugging your site when something goes wrong
A [Renew certificate](#renew) section has also been created as a guide of what to expect for post deployment certificate renewal if using Let's Encrypt.
## <a name="tldr"></a>TL;DR
**NOTE**: assumes you are starting from the top level of the cloned repository (`PWD == ./wordpress-nginx-docker`)
```
mkdir -p certs/ certs-data/ logs/nginx/ mysql/ wordpress/
docker-compose up -d
```
After a few moments you should see your site running at [http://127.0.0.1](http://127.0.0.1) ready to be configured.
Further details available [here](CONSOLE.md/#tldr).
## <a name="setup"></a>Setup and configuration
### Create directories on host
Directories are created on the host to persist data for the containers to volume mount from the host.
Directories are created on the host and volume mounted to the docker containers. This allows the user to persist data beyond the scope of the container itself. If volumes are not persisted to the host the user runs the risk of losing their data when the container is updated or removed.
- **mysql**: The database files for MariaDB
- **wordpress**: The WordPress media files
@@ -29,32 +53,90 @@ Directories are created on the host to persist data for the containers to volume
From the top level of the cloned repository, create the directories that will be used for managing the data on the host.
```
$ cd wordpress-nginx-docker/
# mkdir -p certs/ certs-data/ logs/nginx/ mysql/ wordpress/
mkdir -p certs/ certs-data/ logs/nginx/ mysql/ wordpress/
```
**NOTE**: for permissions reasons it is important for the user to create these directories prior to issuing the docker-compose command. If the directories do not already exist when the containers are started, the directories will be created at start time and will be owned by the root user of the container process. This can lead to access denied permission issues.
### <a name="http-or-https"></a>HTTP or HTTPS?
There are three files in the `nginx` directory, and which one you use depends on whether you want to serve your site using HTTP or HTTPS.
Files in the `nginx` directory:
- `default.conf` - Example configuration for running locally on port 80 using http.
- `default_http.conf.template` - Example configuration for running at a user defined `FQDN_OR_IP` on port 80 using http.
- `default_https.conf.template` - Example configuration for running at a user defined `FQDN_OR_IP` on port 443 using https.
**NOTE**: `FQDN_OR_IP` is short for Fully Qualified Domain Name or IP Address, and should be DNS resolvable if using a hostname.
Both of these are protocols for transferring the information of a particular website between the Web Server and Web Browser. But whats difference between these two? Well, extra "s" is present in https and that makes it secure!
A very short and concise difference between http and https is that https is much more secure compared to http. https = http + cryptographic protocols.
Main differences between HTTP and HTTPS
- In HTTP, URL begins with [http://]() whereas an HTTPS URL starts with [https://]()
- HTTP uses port number `80` for communication and HTTPS uses `443`
- HTTP is considered to be unsecured and HTTPS is secure
- HTTP Works at Application Layer and HTTPS works at Transport Layer
- In HTTP, Encryption is absent whereas Encryption is present in HTTPS
- HTTP does not require any certificates and HTTPS needs SSL Certificates (signed, unsigned or self generated)
### HTTP
If you plan to run your WordPress site over http on port 80, then do the following.
1. Change the name of `nginx/wordpress.conf.example` to `nginx/wordpress.conf`
2. Update the `DOMAIN_NAME` in `nginx/wordpress.conf` to be that of your domain
3. Run `$ docker-compose up -d`
4. Navigate to [http://DOMAIN_NAME]() in a browser where `DOMAIN_NAME` is the name of your site
1. Replace the contents of `nginx/default.conf` with the `nginx/default_http.conf.template` file
2. Update the `FQDN_OR_IP` in `nginx/default.conf` to be that of your domain
3. Run `$ docker-compose up -d` and allow a few moments for the containers to set themselves up
4. Navigate to [http://FQDN_OR_IP]() in a browser where `FQDN_OR_IP` is the hostname or IP Address of your site
### HTTPS with SSL Certificates
### HTTPS
If you plan to run your WordPress site over https on port 443, then do the following.
**Choose a method for SSL certificates**
1. Replace the contents of `nginx/default.conf` with the `nginx/default_https.conf.template` file.
2. Update the `FQDN_OR_IP` in `nginx/default.conf` to be that of your domain (occurs in many places)
3. Review the options for SSL certificates below to complete your configuration
- **Let's Encrypt**
## <a name="ssl-certs"></a>SSL Certificates
If you plan on using SSL certificates from [Let's Encrypt](https://letsencrypt.org) it is important that your public domain is already DNS registered and publically reachable.
Run: `./letsencrypt/letsencrypt-init.sh DOMAIN_NAME`, where `DOMAIN_NAME` is the publicly registered domain name of your host to generate your initial certificate. (Information about updating your Let's Encrypt certificate can be found further down in this document)
**What are SSL Certificates?**
SSL Certificates are small data files that digitally bind a cryptographic key to an organizations details. When installed on a web server, it activates the padlock and the https protocol and allows secure connections from a web server to a browser. Typically, SSL is used to secure credit card transactions, data transfer and logins, and more recently is becoming the norm when securing browsing of social media sites.
SSL Certificates bind together:
- A domain name, server name or hostname.
- An organizational identity (i.e. company name) and location.
Three options for obtaining/installing SSL Certificates are outlined below.
1. Let's Encrypt - free SSL Certificate service
2. Bring your own - you already have a valid certificate
3. Self signed - you can generate your own self signed certificates to use for testing
### <a name="lets-encrypt"></a>Let's Encrypt
Lets Encrypt is a free, automated, and open certificate authority (CA), run for the publics benefit. It is a service provided by the Internet Security Research Group (ISRG).
We give people the digital certificates they need in order to enable HTTPS (SSL/TLS) for websites, for free, in the most user-friendly way we can. We do this because we want to create a more secure and privacy-respecting Web.
- If you plan on using SSL certificates from [Let's Encrypt](https://letsencrypt.org) it is important that your public domain is already DNS registered and publicly reachable.
Two scripts have been provided to help automate the Let's Encrypt interactions needed to obtain and maintain your certificates.
- `letsencrypt-init.sh` - run once when first setting up your site to obtain certificates
- `letsencrypt-renew.sh` - run as needed to renew your previously issued certificate
**NOTE**: these scripts should be run from within the `letsencrypt/` directory. It is important to run the initialization script BEFORE deploying your site.
**USAGE**: `./letsencrypt-init.sh FQDN_OR_IP`, where `FQDN_OR_IP` is the publicly registered domain name of your host to generate your initial certificate. (Information about updating your Let's Encrypt certificate can be found further down in this document)
```console
$ cd letsencrypt/
$ ./letsencrypt-init.sh example.com
mysql uses an image, skipping
wordpress uses an image, skipping
@@ -128,10 +210,14 @@ INFO: update the nginx/wordpress_ssl.conf file
- 47: ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
- 48: ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
```
- **Self signed**
If you plan on using self signed SSL certificates, run: `./letsencrypt/self-signed-init.sh DOMAIN_NAME`, where `DOMAIN_NAME` is the `CN` you want to assign to the host (commonly `localhost`).
### Bring your own
If you plan to use pre-existing certificates you will need to update the `nginx/default.conf` file with the appropriate settings to the kind of certificates you have.
### Self signed
**USAGE**: `./self-signed-init.sh FQDN_OR_IP`, where `FQDN_OR_IP` is the `CN` you want to assign to the host (commonly `localhost`).
```console
$ cd letsencrypt/
@@ -147,20 +233,9 @@ INFO: update the nginx/wordpress_ssl.conf file
- 19: server_name localhost www.localhost;
- 46: ssl_certificate /etc/letsencrypt/live/localhost/cert.pem;
- 47: ssl_certificate_key /etc/letsencrypt/live/localhost/privkey.pem;
- 48: #ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; <-- COMMENT OUT OR REMOVE
- 48: #ssl_trusted_certificate /etc/letsencrypt/live/FQDN_OR_IP/chain.pem; <-- COMMENT OUT OR REMOVE
```
- **Bring your own**
If you plan to use pre-existing certificates you will need to update the `nginx/wordpress_ssl.conf` file with the appropriate settings to the kind of certificates you have.
**Finally**
1. Change the name of `nginx/wordpress_ssl.conf.example` to `nginx/wordpress_ssl.conf`
2. Update the `DOMAIN_NAME` in `nginx/wordpress_ssl.conf` to be that of your domain
3. Run `$ docker-compose up -d`
4. Navigate to [https://DOMAIN_NAME]() in a browser where `DOMAIN_NAME` is the name of your site
### <a name="renew"></a>Renew your Let's Encrypt certificate
What is the lifetime for Lets Encrypt certificates? For how long are they valid?
@@ -249,118 +324,69 @@ Killing nginx ... done
And that's it!
## <a name="opt_config"></a>Optional Configuration
### <a name="dotenv"></a>.env
### Environment Varialbles
A `.env` file has been included to more easily set docker-compose variables without having to modify the docker-compose.yml file itself.
WordPress environment variables. See the [official image](https://hub.docker.com/_/wordpress/) for additional information.
Default values have been provided as a means of getting up and running quickly for testing purposes. It is up to the user to modify these to best suit their deployment preferences.
- `WORDPRESS_DB_NAME`: Name of database used for WordPress in MariaDB
- `WORDPRESS_TABLE_PREFIX`: Prefix appended to all WordPress related tables in the `WORDPRESS_DB_NAME` database
- `WORDPRESS_DB_HOST `: Hostname of the database server / container
- `WORDPRESS_DB_PASSWORD `: Database password for the `WORDPRESS_DB_USER`. By default 'root' is the `WORDPRESS_DB_USER`.
Example `.env` file:
```yaml
environment:
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_TABLE_PREFIX=wp_
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_PASSWORD=password
```env
# wordpress - wordpress:php7.3-fpm
WORDPRESS_DB_NAME=wordpress
WORDPRESS_TABLE_PREFIX=wp_
WORDPRESS_DB_HOST=mysql
WORDPRESS_DB_USER=root
WORDPRESS_DB_PASSWORD=password
# mariadb - mariadb:latest
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=root
MYSQL_PASSWORD=password
MYSQL_DATABASE=wordpress
# nginx - nginx:latest
NGINX_DEFAULT_CONF=./nginx/default.conf
```
MySQL environment variables.
## <a name="deploy"></a>Deploy
- If you've altered the `WORDPRESS_DB_PASSWORD` you should also set the `MYSQL_ROOT_PASSWORD ` to be the same as they will both be associated with the user 'root'.
Once configuration has been completed deployment is just a matter of invoking the docker-compose command. Depending on the output you want to see you can choose to daemonize the launching of the containers with `-d`
```yaml
environment:
- MYSQL_ROOT_PASSWORD=password
```
### Non-root database user
If you don't want 'root' as the `WORDPRESS_DB_USER`, then some extra configuration variables are required in the `mysql` container.
Example:
```yaml
version: '3.6'
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx:/etc/nginx/conf.d
- ./logs/nginx:/var/log/nginx
- ./wordpress:/var/www/html
- ./certs:/etc/letsencrypt
- ./certs-data:/data/letsencrypt
links:
- wordpress
restart: always
mysql:
image: mariadb
container_name: mysql
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_USER=wp_user # same as WORDPRESS_DB_USER
- MYSQL_PASSWORD=wp_password # same as WORDPRESS_DB_PASSWORD
- MYSQL_DATABASE=wordpress # same as WORDPRESS_DB_NAME
restart: always
wordpress:
image: wordpress:php7.2-fpm
container_name: wordpress
volumes:
- ./wordpress:/var/www/html
environment:
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_TABLE_PREFIX=wp_
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_PASSWORD=wp_password # new DB password
- WORDPRESS_DB_USER=wp_user # new DB user
links:
- mysql
restart: always
```
## Example deployment (using localhost)
From the top level of the cloned repository, create host directories to preserve the container contents and create a basic Nginx configuration file.
### Launch everything daemonized
```
cd wordpress-nginx-docker/
### optional: directories would be created by docker if not done manually
mkdir -p certs/ certs-data/ logs/nginx/ mysql/ wordpress/
cp nginx/wordpress.conf.example nginx/wordpress.conf
docker-compose up -d
```
Update `nginx/wordpress.conf` by changing the `server_name` value from `DOMAIN_NAME` to `127.0.0.1`.
### Launch everything, but see the STDOUT of the containers in the console
```console
$ diff nginx/wordpress.conf.example nginx/wordpress.conf
3c3
< server_name DOMAIN_NAME;
---
> server_name 127.0.0.1;
```
docker-compose up
```
Launch and daemonize the containers with `docker-compose up -d`
Issuing a `ctrl-z` will safely disconnect from the console without terminating the running containers. Otherwise `ctrl-c` will disconnect and kill the containers.
```console
$ docker-compose up -d
Creating mysql ... done
Creating wordpress ... done
Creating nginx ... done
### Staged approach
The user may notice `Connection Error` output from the WordPress container as the database readies itself for connections. This can be eliminated by staging the deployment of the containers until each one has properly set up.
```
docker-compose up -d database
```
### Initial Wordpress setup
wait until the database completes it's setup. This can be observed by looking at the log output using `docker-compose logs database` and waiting for the **mysqld: ready for connections** message.
```
docker-compose up -d wordpress nginx
```
## <a name="site"></a>Running site
### Initial WordPress setup
Navigate your browser to [http://127.0.0.1](http://127.0.0.1) and follow the installation prompts
@@ -384,7 +410,91 @@ Navigate your browser to [http://127.0.0.1](http://127.0.0.1) and follow the ins
<img width="80%" alt="View site" src="https://user-images.githubusercontent.com/5332509/44045891-f4c5f90c-9ef7-11e8-88e4-fc8cfb61ea7d.png">
Once your site is running you can begin to create and publish any content you'd like in your Wordpress instance.
Once your site is running you can begin to create and publish any content you'd like in your WordPress instance.
## <a name="stop-and-remove"></a>Stop and remove contaiers
Because `docker-compose.yml` was used to define the container relationships it can also be used to stop and remove the containers from the host they are running on.
Stop and remove containers:
```console
$ cd wordpress-nginx-docker
$ docker-compose stop
Stopping nginx ... done
Stopping wordpress ... done
Stopping mysql ... done
$ docker-compose rm -f
Going to remove nginx, wordpress, mysql
Removing nginx ... done
Removing wordpress ... done
Removing mysql ... done
```
Removing all related directories:
```console
$ rm -rf certs/ certs-data/ logs/ mysql/ wordpress/
```
A script named `stop-and-remove.sh` has been provided to run these commands for you. See an example [here](CONSOLE.md/#stop-and-remove).
## <a name="opt_config"></a>Optional Configuration
### Environment Variables
WordPress environment variables. See the [official image](https://hub.docker.com/_/wordpress/) for additional information.
- `WORDPRESS_DB_NAME`: Name of database used for WordPress in MariaDB
- `WORDPRESS_TABLE_PREFIX`: Prefix appended to all WordPress related tables in the `WORDPRESS_DB_NAME` database
- `WORDPRESS_DB_HOST `: Hostname of the database server / container
- `WORDPRESS_DB_PASSWORD `: Database password for the `WORDPRESS_DB_USER`. By default 'root' is the `WORDPRESS_DB_USER`.
```yaml
environment:
- WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress}
- WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_}
- WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mysql}
- WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-root}
- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-password}
```
MySQL environment variables.
- If you've altered the `WORDPRESS_DB_PASSWORD` you should also set the `MYSQL_ROOT_PASSWORD ` to be the same as they will both be associated with the user 'root'.
```yaml
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password}
- MYSQL_USER=${MYSQL_USER:-root}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-wordpress}
```
### Non-root database user
If you don't want 'root' as the `WORDPRESS_DB_USER`, then the configuration variables in `.env` can be updated in the following way.
Example:
```yaml
# wordpress - wordpress:php7.3-fpm
WORDPRESS_DB_NAME=wordpress
WORDPRESS_TABLE_PREFIX=wp_
WORDPRESS_DB_HOST=mysql
WORDPRESS_DB_USER=wp_user # new DB user
WORDPRESS_DB_PASSWORD=wp_password. # new DB password
# mariadb - mariadb:latest
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=wp_user # same as WORDPRESS_DB_USER
MYSQL_PASSWORD=wp_password # same as WORDPRESS_DB_PASSWORD
MYSQL_DATABASE=wordpress # same as WORDPRESS_DB_NAME
# nginx - nginx:latest
NGINX_DEFAULT_CONF=./nginx/default.conf
```
### Port Mapping
@@ -407,27 +517,11 @@ For the `wordpress` stanza, add
- '9000:9000'
```
## Clean up / Removal
Because docker-compose was used to define the container relationships it can also be used to stop and remove the containers from the host they are running on.
## Debugging tips
Stop and remove containers:
TODO:
```console
$ cd wordpress-nginx-docker
$ docker-compose stop
Stopping nginx ... done
Stopping wordpress ... done
Stopping mysql ... done
$ docker-compose rm -f
Going to remove nginx, wordpress, mysql
Removing nginx ... done
Removing wordpress ... done
Removing mysql ... done
```
container logs
Removing all related directories:
```console
$ rm -rf certs/ certs-data/ logs/ mysql/ wordpress/
```
permissions
+30 -25
View File
@@ -1,5 +1,33 @@
version: '3.6'
services:
wordpress:
image: wordpress:php7.3-fpm
container_name: wordpress
volumes:
- ./wordpress:/var/www/html
environment:
- WORDPRESS_DB_NAME=${WORDPRESS_DB_NAME:-wordpress}
- WORDPRESS_TABLE_PREFIX=${WORDPRESS_TABLE_PREFIX:-wp_}
- WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-mysql}
- WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-root}
- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-password}
depends_on:
- mysql
restart: always
mysql:
image: mariadb:latest
container_name: mysql
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password}
- MYSQL_USER=${MYSQL_USER:-root}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-wordpress}
restart: always
nginx:
image: nginx:latest
container_name: nginx
@@ -7,34 +35,11 @@ services:
- '80:80'
- '443:443'
volumes:
- ./nginx:/etc/nginx/conf.d
- ${NGINX_DEFAULT_CONF:-./nginx/default.conf}:/etc/nginx/conf.d/default.conf
- ./logs/nginx:/var/log/nginx
- ./wordpress:/var/www/html
- ./certs:/etc/letsencrypt
- ./certs-data:/data/letsencrypt
links:
depends_on:
- wordpress
restart: always
mysql:
image: mariadb
container_name: mysql
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
restart: always
wordpress:
image: wordpress:php7.2-fpm
container_name: wordpress
volumes:
- ./wordpress:/var/www/html
environment:
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_TABLE_PREFIX=wp_
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_PASSWORD=password
links:
- mysql
restart: always
+10 -10
View File
@@ -10,7 +10,7 @@ _default_conf () {
echo "server {" > $OUTFILE
echo " listen 80;" >> $OUTFILE
echo " listen [::]:80;" >> $OUTFILE
echo " server_name ${DOMAIN_NAME};" >> $OUTFILE
echo " server_name ${FQDN_OR_IP};" >> $OUTFILE
echo "" >> $OUTFILE
echo " location / {" >> $OUTFILE
echo " rewrite ^ https://\$host\$request_uri? permanent;" >> $OUTFILE
@@ -23,12 +23,12 @@ _default_conf () {
echo "}" >> $OUTFILE
}
# DOMAIN_NAME should not include prefix of www.
# FQDN_OR_IP should not include prefix of www.
if [ "$#" -ne 1 ]; then
echo "Usage: $0 DOMAIN_NAME" >&2
echo "Usage: $0 FQDN_OR_IP" >&2
exit 1;
else
DOMAIN_NAME=$1
FQDN_OR_IP=$1
fi
if [ ! -d "${CERTS}" ]; then
@@ -58,7 +58,7 @@ docker run -it --rm \
certbot/certbot \
certonly \
--webroot --webroot-path=/data/letsencrypt \
-d ${DOMAIN_NAME} -d www.${DOMAIN_NAME}
-d ${FQDN_OR_IP} -d www.${FQDN_OR_IP}
cd ${REPO_DIR}
docker-compose stop
@@ -67,10 +67,10 @@ cd ${LE_DIR}
rm -f ${REPO_DIR}/nginx/default.conf
echo "INFO: update the nginx/wordpress_ssl.conf file"
echo "- 4: server_name ${DOMAIN_NAME};"
echo "- 19: server_name ${DOMAIN_NAME} www.${DOMAIN_NAME};"
echo "- 46: ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem;"
echo "- 47: ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem;"
echo "- 48: ssl_trusted_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/chain.pem;"
echo "- 4: server_name ${FQDN_OR_IP};"
echo "- 19: server_name ${FQDN_OR_IP} www.${FQDN_OR_IP};"
echo "- 46: ssl_certificate /etc/letsencrypt/live/${FQDN_OR_IP}/fullchain.pem;"
echo "- 47: ssl_certificate_key /etc/letsencrypt/live/${FQDN_OR_IP}/privkey.pem;"
echo "- 48: ssl_trusted_certificate /etc/letsencrypt/live/${FQDN_OR_IP}/chain.pem;"
exit 0;
+13 -13
View File
@@ -5,31 +5,31 @@ REPO_DIR=$(dirname ${LE_DIR})
CERTS=${REPO_DIR}/certs
CERTS_DATA=${REPO_DIR}/certs-data
# DOMAIN_NAME should not include prefix of www.
# FQDN_OR_IP should not include prefix of www.
if [ "$#" -ne 1 ]; then
echo "Usage: $0 DOMAIN_NAME" >&2
echo "Usage: $0 FQDN_OR_IP" >&2
exit 1;
else
DOMAIN_NAME=$1
FQDN_OR_IP=$1
fi
if [ ! -d "${CERTS}/live/${DOMAIN_NAME}" ]; then
if [ ! -d "${CERTS}/live/${FQDN_OR_IP}" ]; then
echo "INFO: making certs directory"
mkdir -p ${CERTS}/live/${DOMAIN_NAME}
mkdir -p ${CERTS}/live/${FQDN_OR_IP}
fi
# generate and add keys
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
-days 365 -nodes -subj '/CN='${DOMAIN_NAME}''
-days 365 -nodes -subj '/CN='${FQDN_OR_IP}''
mv cert.pem ${CERTS}/live/${DOMAIN_NAME}/fullchain.pem
mv key.pem ${CERTS}/live/${DOMAIN_NAME}/privkey.pem
mv cert.pem ${CERTS}/live/${FQDN_OR_IP}/fullchain.pem
mv key.pem ${CERTS}/live/${FQDN_OR_IP}/privkey.pem
echo "INFO: update the nginx/wordpress_ssl.conf file"
echo "- 4: server_name ${DOMAIN_NAME};"
echo "- 19: server_name ${DOMAIN_NAME} www.${DOMAIN_NAME};"
echo "- 46: ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem;"
echo "- 47: ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem;"
echo "- 48: #ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem; <-- COMMENT OUT OR REMOVE"
echo "- 4: server_name ${FQDN_OR_IP};"
echo "- 19: server_name ${FQDN_OR_IP} www.${FQDN_OR_IP};"
echo "- 46: ssl_certificate /etc/letsencrypt/live/${FQDN_OR_IP}/fullchain.pem;"
echo "- 47: ssl_certificate_key /etc/letsencrypt/live/${FQDN_OR_IP}/privkey.pem;"
echo "- 48: #ssl_trusted_certificate /etc/letsencrypt/live/FQDN_OR_IP/chain.pem; <-- COMMENT OUT OR REMOVE"
exit 0;
@@ -1,6 +1,6 @@
server {
listen 80;
server_name DOMAIN_NAME;
server_name 127.0.0.1;
root /var/www/html;
index index.php;
+24
View File
@@ -0,0 +1,24 @@
server {
listen 80;
server_name FQDN_OR_IP;
root /var/www/html;
index index.php;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
@@ -1,7 +1,7 @@
server {
listen 80;
listen [::]:80;
server_name DOMAIN_NAME;
server_name FQDN_OR_IP;
location / {
rewrite ^ https://$host$request_uri? permanent;
@@ -16,7 +16,7 @@ server {
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name DOMAIN_NAME www.DOMAIN_NAME;
server_name FQDN_OR_IP www.FQDN_OR_IP;
add_header Strict-Transport-Security "max-age=31536000" always;
@@ -38,9 +38,9 @@ server {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME/chain.pem;
ssl_certificate /etc/letsencrypt/live/FQDN_OR_IP/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/FQDN_OR_IP/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/FQDN_OR_IP/chain.pem;
location / {
try_files $uri $uri/ /index.php?$args;
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Stop running containers and remove related directories
read -p "Do you really want to stop and remove EVERYTHING (y/n)? " answer
case ${answer:0:1} in
y|Y )
echo "INFO: Stopping containers"
docker-compose stop
echo "INFO: Removing containers"
docker-compose rm -f
echo "INFO: Setting file permissions to that of the user"
docker run --rm \
-v $(pwd):/clean \
-e UID=$(id -u) \
-e GID=$(id -g) \
nginx:latest /bin/bash -c 'chown -R $UID:$GID /clean'
echo "INFO: Pruning unused docker volumes"
docker volume prune -f
echo "INFO: Pruning unused docker networks"
docker network prune -f
echo "INFO: Removing directories and contents (certs/ certs-data/ logs/nginx/ mysql/ wordpress/)"
rm -rf certs/ certs-data/ logs/nginx/ mysql/ wordpress/
echo "INFO: Done"
exit 0;
;;
* )
echo "INFO: Exiting without stopping containers or removing files"
exit 0;
;;
esac
exit 0;