Created
November 2, 2020 14:09
-
-
Save evildmp/8a94c39d58fc248757dc0cd909daa258 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.. meta:: | |
:description: | |
This guide explains step-by-step how to deploy a WordPress project with Docker, in accordance with | |
Twelve-factor principles. | |
:keywords: Docker, PHP, WordPress, MySQL, S3 | |
.. _php-wordpress-create-deploy: | |
How to migrate (or create) and deploy a WordPress project | |
=========================================================================================== | |
This guide will take you through the steps to deploy a portable, vendor-neutral WordPress project, either by building it | |
from scratch or migrating an existing application, using Docker. The project architecture is in line | |
with `Twelve-factor <https://www.12factor.net/config>`_ design principles. | |
This guide assumes that you are familiar with the basics of the Divio platform and have Docker and the :ref:`Divio CLI | |
<local-cli>` installed. | |
Edit (or create) the project files | |
----------------------------------- | |
Start in an existing WordPress project (i.e. containing ``wp-content``, ``wp-admin`` etc ), or if necessary, create a | |
new directory. | |
The ``Dockerfile`` | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
Create a file named ``Dockerfile``, adding: | |
.. code-block:: Dockerfile | |
FROM wordpress:5.5.1 | |
COPY . /var/www/html | |
You may need to change the version of WordPress to suit your project. | |
Local container orchestration with ``docker-compose.yml`` | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
Create a ``docker-compose.yml`` file, :ref:`for local development purposes <docker-compose-local>`. This will replicate | |
the ``web`` image used in cloud deployments, allowing you to run the application in an environment as close to that of | |
the cloud servers as possible. Amongst other things, it will allow the project to use a MySQL database | |
running in a local container, and provides convenient access to files inside the containerised application. | |
.. code-block:: yaml | |
version: "2.4" | |
services: | |
web: | |
# the application's web service (container) will use an image based on our Dockerfile | |
build: "." | |
# map the internal port 80 to port 8000 on the host | |
ports: | |
- "8000:80" | |
links: | |
- "database_default" | |
env_file: .env-local | |
volumes: | |
- "./:/var/www/html:rw" | |
database_default: | |
# Select one of the following db configurations for the database | |
image: mysql:5.7 | |
environment: | |
MYSQL_DATABASE: "db" | |
MYSQL_ALLOW_EMPTY_PASSWORD: "yes" | |
SERVICE_MANAGER: "fsm-mysql" | |
volumes: | |
- ".:/app:rw" | |
healthcheck: | |
test: "/usr/bin/mysql --user=root -h 127.0.0.1 --execute \"SHOW DATABASES;\"" | |
interval: 2s | |
timeout: 20s | |
retries: 10 | |
Local configuration using ``.env-local`` | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
As you will see above, the ``web`` service refers to an ``env_file`` containing the environment variables that will be | |
used in the local development environment. Create a ``.env-local`` file: | |
.. code-block:: text | |
DATABASE_URL=mysql://root@database_default:3306/db | |
Check the local site | |
~~~~~~~~~~~~~~~~~~~~ | |
First, build the Docker application: | |
.. code-block:: bash | |
docker-compose build | |
Then launch it: | |
.. code-block:: bash | |
docker-compose up | |
Install WordPress (new projects only) | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
``docker-compose up`` will execute ``/usr/local/bin/docker-entrypoint.sh`` inside the container. If this is a new | |
project, it will install WordPress by copying WordPress files from ``/usr/src/wordpress/`` to ``/var/www/html`` if they | |
are not already present. | |
``/var/www/html`` is mapped to the project directory by ``docker-compose.yml``, and the files will appear there. | |
A new project requires a ``wp-config.php`` - copy ``wp-config-sample.php`` to ``wp-config.php``. | |
Configure ``wp-config.php`` | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
A WordPress project's ``wp-config.php`` contains hard-coded database credentials by default. This needs to be modified | |
to obtain its configuration from the ``DATABASE_URL`` environment variable. Edit the "MySQL settings" section of the | |
file, changing the relevant section to: | |
.. code-block:: bash | |
/** get the DATABASE_URL from the environment */ | |
$db = parse_url(getenv("DATABASE_URL")); | |
define('DB_NAME', trim($db["path"],"/")); | |
/** MySQL database username */ | |
define('DB_USER', $db["user"]); | |
/** MySQL database password */ | |
define('DB_PASSWORD', $db["pass"]); | |
/** MySQL hostname */ | |
define('DB_HOST', $db["host"]); | |
Check the local site | |
~~~~~~~~~~~~~~~~~~~~ | |
You can now open WordPress at http://127.0.0.1:8000/. | |
Install the ``wp-s3-smart-upload`` plugin to handle S3 storage | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
Open http://127.0.0.1:8000/wp-admin/plugin-install.php, and search for the *WordPress Amazon S3 – Wasabi Smart File | |
Uploads Plugin*; install and activate it. | |
This will download the plugin and copy it to ``wp-content/plugins`` in the application. | |
.. admonition:: not currently configured | |
This is yet to be configured from env vars so won't actually work. | |
Deployment and further development | |
----------------------------------------- | |
Create a new project on Divio | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
In the `Divio Control Panel <https://control.divio.com>`_ add a new project, selecting the *Build your own* option. | |
Add database and media services | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
The new project does not include any :ref:`additional services <services>`; they must be added manually using the Divio | |
Control Panel if required. Use the *Services* menu to add a Postgres or MySQL database to match your choice earlier, | |
and an S3 object storage instance for media. | |
Connect the local project to the cloud project | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
Your Divio project has a *slug*, based on the name you gave it when you created it. Run ``divio project list -g`` to | |
get your project's slug; you can also read the slug from the Control Panel. | |
Run: | |
.. code-block:: bash | |
divio project configure | |
and provide the slug. (This creates a new file in the project at ``.divio/config.json``.) | |
If you have done this correctly, ``divio project dashboard`` will open the project in the Control Panel. | |
Configure the Git repository | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
Initialise the project as a Git repository if it's not Git-enabled already: | |
.. code-block:: bash | |
git init . | |
A ``.gitignore`` file is needed to exclude unwanted files from the repository. Add: | |
.. code-block:: text | |
# Divio | |
.divio | |
/data.tar.gz | |
/data | |
# OS-specific patterns - add your own here | |
.DS_Store | |
.DS_Store? | |
._* | |
.Spotlight-V100 | |
.Trashes | |
Add the project's Git repository as a remote, using the *slug* value in the remote address: | |
.. code-block:: bash | |
git remote add origin [email protected]:<slug>.git | |
(Use e.g. ``divio`` instead if you already have a remote named ``origin``.) | |
Commit your work | |
~~~~~~~~~~~~~~~~ | |
.. code-block:: bash | |
git add . # add all the newly-created files | |
git commit -m "Created new project" # commit | |
git push --set-upstream --force origin [or divio] master # push, overwriting any unneeded commits made by the Control Panel at creation time | |
You'll now see "1 undeployed commit" listed for the project in the Control Panel. | |
Deploy the Test server | |
~~~~~~~~~~~~~~~~~~~~~~ | |
Deploy with: | |
.. code-block:: bash | |
divio project deploy | |
(or use the **Deploy** button in the Control Panel). | |
Once deployed, your project will be accessible via the Test server URL shown in the Control Panel. | |
Perform initial operations on the cloud database | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
.. admonition:: not currently working | |
Your cloud project does not yet have any content in the database, so you can't log in or do any other work there. | |
You can push the local database with the superuser you created to the Test environment: | |
.. code-block:: bash | |
divio project push db | |
or, :ref:`SSH to a cloud container <divio-project-ssh>` in the Test environment with ``divio project ssh`` and execute | |
Django migrations and create a superuser there in the usual way. | |
You can run migrations automatically on deployment by adding a :ref:`release command <release-commands>` in the Control | |
Panel. | |
Notes on working with the project | |
--------------------------------- | |
.. admonition:: the Twelve-factor model | |
By default, WordPress is configured in ways that can make adopting the Twelve-factor model difficult. For example, | |
installation of new code is typically handled by WordPress itself, by copying it to a web server directory. | |
Configuration | |
~~~~~~~~~~~~~ | |
The configuration described here tries to adopt Twelve-factor model as closely as possible, placing all configuration | |
in environment variables, so that the project can readily be moved to another host or platform, or set up locally for | |
development. The configuration for: | |
* security # to be done | |
* database | |
* media # to be done | |
* static files # to be done | |
is handled by a few simple code snippets in ``wp-config.php``. In each case, the settings will fall back to | |
safe and secure defaults. | |
Configuration for any other components should be handled in the same way: | |
* edit ``wp-config.php`` so that the configuration can be obtained from environment variables | |
* if required, add environment variables to the cloud environments with the appropriate values | |
* add environment variables to ``.env-local`` for the development environment | |
Installing and deploying new code | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment