├── .editorconfig ├── .gitignore ├── LICENSE.txt ├── Makefile ├── README.markdown └── config ├── composer.json ├── composer.lock └── wp-config.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = space 6 | indent_size = 2 7 | 8 | [Makefile] 9 | insert_final_newline = true 10 | indent_style = tab 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !Makefile 3 | !README.markdown 4 | !LICENSE.txt 5 | !.editorconfig 6 | !.gitignore 7 | !config/composer.json 8 | !config/composer.lock 9 | !config/wp-config.php 10 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016 Jose Diaz-Gonzalez 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifndef APP_NAME 2 | APP_NAME = blog 3 | endif 4 | 5 | ifndef WORDPRESS_VERSION 6 | WORDPRESS_VERSION = 4.9.6 7 | endif 8 | 9 | ifndef BUILDPACK_VERSION 10 | BUILDPACK_VERSION = v180 11 | endif 12 | 13 | ifndef DOKKU_USER 14 | DOKKU_USER = dokku 15 | endif 16 | 17 | ifdef UNATTENDED_CREATION 18 | DOKKU_CMD = ssh $(DOKKU_USER)@$(SERVER_NAME) 19 | else 20 | DOKKU_CMD = dokku 21 | endif 22 | 23 | CURL_INSTALLED := $(shell command -v curl 2> /dev/null) 24 | WGET_INSTALLED := $(shell command -v wget 2> /dev/null) 25 | 26 | .PHONY: all 27 | all: help ## outputs the help message 28 | 29 | .PHONY: help 30 | help: ## this help. 31 | @grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-36s\033[0m %s\n", $$1, $$2}' 32 | 33 | .PHONY: build 34 | build: ## builds a wordpress blog installation and outputs deploy instructions 35 | ifndef APP_NAME 36 | $(error "Missing APP_NAME environment variable, this should be the name of your blog app") 37 | endif 38 | ifndef SERVER_NAME 39 | $(error "Missing SERVER_NAME environment variable, this should be something like 'dokku.me'") 40 | endif 41 | ifndef CURL_INSTALLED 42 | ifndef WGET_INSTALLED 43 | $(error "Neither curl nor wget are installed, and at least one is necessary for retrieving salts") 44 | endif 45 | endif 46 | # creating the wordpress repo 47 | @test -d $(APP_NAME) || (git -c advice.detachedHead=false clone --branch=$(WORDPRESS_VERSION) --single-branch https://github.com/WordPress/WordPress.git $(APP_NAME) && cd $(APP_NAME) && git checkout -qb master) 48 | # adding wp-config.php from gist 49 | @test -f $(APP_NAME)/wp-config.php || (cp config/wp-config.php $(APP_NAME)/wp-config.php && cd $(APP_NAME) && git add wp-config.php && git commit -qm "Adding environment-variable based wp-config.php") 50 | # adding .env file to configure buildpack 51 | @test -f $(APP_NAME)/.buildpacks || (echo "https://github.com/heroku/heroku-buildpack-php.git#$(BUILDPACK_VERSION)" > $(APP_NAME)/.buildpacks && cd $(APP_NAME) && git add .buildpacks && git commit -qm "Forcing php buildpack usage") 52 | # ensuring our composer.json loads with php 5.6 and loads the mysql extension 53 | @test -f $(APP_NAME)/composer.json || (cp config/composer.json $(APP_NAME)/composer.json && cp config/composer.lock $(APP_NAME)/composer.lock && cd $(APP_NAME) && git add composer.json composer.lock && git commit -qm "Use PHP 5.6 and the mysql extension") 54 | # setting the correct dokku remote for your app and server combination 55 | @cd $(APP_NAME) && (git remote rm dokku 2> /dev/null || true) && git remote add dokku "dokku@$(SERVER_NAME):$(APP_NAME)" 56 | # retrieving potential salts and writing them to /tmp/wp-salts 57 | ifdef CURL_INSTALLED 58 | @curl -so /tmp/wp-salts https://api.wordpress.org/secret-key/1.1/salt/ 59 | else 60 | ifdef WGET_INSTALLED 61 | @wget -qO /tmp/wp-salts https://api.wordpress.org/secret-key/1.1/salt/ 62 | endif 63 | endif 64 | @sed -i.bak -e 's/ //g' -e "s/);//g" -e "s/define('/$(DOKKU_CMD) config:set $(APP_NAME) /g" -e "s/SALT',/SALT=/g" -e "s/KEY',[ ]*/KEY=/g" /tmp/wp-salts && rm /tmp/wp-salts.bak 65 | 66 | ifndef UNATTENDED_CREATION 67 | # run the following commands on the server to setup the app: 68 | @echo "" 69 | @echo "dokku apps:create $(APP_NAME)" 70 | @echo "" 71 | # setup plugins persistent storage 72 | @echo "" 73 | @echo "mkdir -p /var/lib/dokku/data/storage/$(APP_NAME)-plugins" 74 | @echo "chown 32767:32767 /var/lib/dokku/data/storage/$(APP_NAME)-plugins" 75 | @echo "dokku storage:mount $(APP_NAME) /var/lib/dokku/data/storage/$(APP_NAME)-plugins:/app/wp-content/plugins" 76 | @echo "" 77 | # setup upload persistent storage 78 | @echo "" 79 | @echo "mkdir -p /var/lib/dokku/data/storage/$(APP_NAME)-uploads" 80 | @echo "chown 32767:32767 /var/lib/dokku/data/storage/$(APP_NAME)-uploads" 81 | @echo "dokku storage:mount $(APP_NAME) /var/lib/dokku/data/storage/$(APP_NAME)-uploads:/app/wp-content/uploads" 82 | @echo "" 83 | # setup languages persistent storage 84 | @echo "" 85 | @echo "mkdir -p /var/lib/dokku/data/storage/$(APP_NAME)-languages" 86 | @echo "chown 32767:32767 /var/lib/dokku/data/storage/$(APP_NAME)-languages" 87 | @echo "dokku storage:mount $(APP_NAME) /var/lib/dokku/data/storage/$(APP_NAME)-languages:/app/wp-content/languages" 88 | @echo "" 89 | # setup your mysql database and link it to your app 90 | # if you're using MariaDB, replace mysql with mariadb 91 | @echo "" 92 | @echo "export MYSQL_IMAGE_VERSION=\"5.6\"" 93 | @echo "dokku mysql:create $(APP_NAME)-database" 94 | @echo "dokku mysql:link $(APP_NAME)-database $(APP_NAME)" 95 | @echo "" 96 | # you will also need to set the proper environment variables for keys and salts 97 | # the following were generated using the wordpress salt api: https://api.wordpress.org/secret-key/1.1/salt/ 98 | # and use the following commands to set them up: 99 | @echo "" 100 | @cat /tmp/wp-salts 101 | @echo "" 102 | # now, on your local machine, change directory to your new wordpress app, and push it up 103 | @echo "" 104 | @echo "cd $(APP_NAME)" 105 | @echo "git push dokku master" 106 | else 107 | @chmod +x /tmp/wp-salts 108 | $(DOKKU_CMD) apps:create $(APP_NAME) 109 | $(DOKKU_CMD) storage:mount $(APP_NAME) /var/lib/dokku/data/storage/$(APP_NAME)-plugins:/app/wp-content/plugins 110 | $(DOKKU_CMD) storage:mount $(APP_NAME) /var/lib/dokku/data/storage/$(APP_NAME)-uploads:/app/wp-content/uploads 111 | $(DOKKU_CMD) storage:mount $(APP_NAME) /var/lib/dokku/data/storage/$(APP_NAME)-languages:/app/wp-content/languages 112 | $(DOKKU_CMD) mysql:create $(APP_NAME)-database 113 | $(DOKKU_CMD) mysql:link $(APP_NAME)-database $(APP_NAME) 114 | @/tmp/wp-salts 115 | @echo "" 116 | # run the following commands on the server to ensure data is stored properly on disk 117 | @echo "" 118 | @echo "mkdir -p /var/lib/dokku/data/storage/$(APP_NAME)-plugins" 119 | @echo "chown 32767:32767 /var/lib/dokku/data/storage/$(APP_NAME)-plugins" 120 | @echo "mkdir -p /var/lib/dokku/data/storage/$(APP_NAME)-uploads" 121 | @echo "chown 32767:32767 /var/lib/dokku/data/storage/$(APP_NAME)-uploads" 122 | @echo "mkdir -p /var/lib/dokku/data/storage/$(APP_NAME)-languages" 123 | @echo "chown 32767:32767 /var/lib/dokku/data/storage/$(APP_NAME)-languages" 124 | @echo "" 125 | # now, on your local machine, change directory to your new wordpress app, and push it up 126 | @echo "" 127 | @echo "cd $(APP_NAME)" 128 | @echo "git push dokku master" 129 | endif 130 | 131 | .PHONY: destroy 132 | destroy: ## destroys an existing wordpress blog installation and outputs undeploy instructions 133 | ifndef APP_NAME 134 | $(error "Missing APP_NAME environment variable, this should be the name of your blog app") 135 | endif 136 | ifndef SERVER_NAME 137 | $(error "Missing SERVER_NAME environment variable, this should be something like 'dokku.me'") 138 | endif 139 | ifndef UNATTENDED_CREATION 140 | # destroy the mysql database 141 | # if you're using MariaDB, replace mysql with mariadb 142 | @echo "" 143 | @echo "dokku mysql:unlink $(APP_NAME)-database $(APP_NAME)" 144 | @echo "dokku mysql:destroy $(APP_NAME)-database" 145 | @echo "" 146 | # destroy the app 147 | @echo "" 148 | @echo "dokku -- --force apps:destroy $(APP_NAME)" 149 | @echo "" 150 | # run the following commands on the server to remove storage directories on disk 151 | @echo "" 152 | @echo "rm -rf /var/lib/dokku/data/storage/$(APP_NAME)-plugins" 153 | @echo "rm -rf /var/lib/dokku/data/storage/$(APP_NAME)-uploads" 154 | @echo "rm -rf /var/lib/dokku/data/storage/$(APP_NAME)-languages" 155 | @echo "" 156 | # now, on your local machine, cd into your app's parent directory and remove the app 157 | @echo "" 158 | @echo "rm -rf $(APP_NAME)" 159 | else 160 | # destroy the mysql database 161 | # if you're using MariaDB, replace mysql with mariadb 162 | $(DOKKU_CMD) mysql:unlink $(APP_NAME)-database $(APP_NAME) 163 | $(DOKKU_CMD) mysql:destroy $(APP_NAME)-database 164 | # destroy the app 165 | $(DOKKU_CMD) -- --force apps:destroy $(APP_NAME) 166 | # run the following commands on the server to remove storage directories on disk 167 | @echo "" 168 | @echo "rm -rf /var/lib/dokku/data/storage/$(APP_NAME)-plugins" 169 | @echo "rm -rf /var/lib/dokku/data/storage/$(APP_NAME)-uploads" 170 | @echo "rm -rf /var/lib/dokku/data/storage/$(APP_NAME)-languages" 171 | @echo "" 172 | # now, on your local machine, cd into your app's parent directory and remove the app 173 | @echo "" 174 | @echo "rm -rf $(APP_NAME)" 175 | endif 176 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # WordPress on Dokku 2 | 3 | A repository to help you setup WordPress on a Dokku server. 4 | 5 | ## Requirements 6 | 7 | - A Dokku server. Tested on 0.7.2+ 8 | - The [dokku-mysql](https://github.com/dokku/dokku-mysql) or [dokku-mariadb](https://github.com/dokku/dokku-mariadb) plugin 9 | - `make` installed locally 10 | - `curl` or `wget` installed locally 11 | 12 | ## Usage 13 | 14 | This repository generates an app directory based on environment variables, as well as instructions for configuring your app on the Dokku server. 15 | 16 | > Plugins and Uploads will be stored on the host using persistent storage. Unless you do similar with themes, this setup will expect them to be distributed with the wordpress installation. 17 | 18 | To use, run the following (and then read the instructions!): 19 | 20 | ```shell 21 | # both APP_NAME and SERVER_NAME are required 22 | # export the server name (or ip) 23 | export SERVER_NAME=dokku.me 24 | 25 | # export the app name 26 | export APP_NAME=blog 27 | 28 | # generate the repository and follow the output directions 29 | make build 30 | ``` 31 | 32 | You can also specify a custom WordPress version: 33 | 34 | ```shell 35 | export WORDPRESS_VERSION=3.7.16 36 | 37 | make build APP_NAME=blog SERVER_NAME=dokku.me 38 | ``` 39 | 40 | Want a mostly unattended installation? You can also execute it with the `UNATTENDED_CREATION` environment variable. You will only need to create the requisite persistent storage directories and push the repository. All configuration will be manually performed using the `dokku` user against the configured `SERVER_NAME`. 41 | 42 | ```shell 43 | export UNATTENDED_CREATION=1 44 | 45 | make build APP_NAME=blog SERVER_NAME=dokku.me 46 | ``` 47 | 48 | You can also destroy an existing wordpress installation: 49 | 50 | ```shell 51 | make destroy APP_NAME=blog SERVER_NAME=dokku.me UNATTENDED_CREATION=1 52 | ``` 53 | 54 | ## After Installation (Optional) 55 | 56 | ### Modify Upload File Size Limit 57 | 58 | Put `.user.ini` file at the root of your folder with the following content: 59 | 60 | ``` 61 | upload_max_filesize = 256M 62 | post_max_size = 256M 63 | ``` 64 | 65 | Then use the following command to push to dokku 66 | 67 | ```shell 68 | git add . 69 | git commit -m "Modify Upload File Size Limit" 70 | git push dokku master 71 | ``` 72 | 73 | ### Upgrading Wordpress 74 | 75 | To upgrade to a later version of Wordpress, pull the later version of wordpress 76 | into your generated local repo and push it. For example, to upgrade the 77 | dokku-wordpress generated 78 | app `mywp` to version `4.9.8` of Wordpress: 79 | 80 | ``` 81 | cd mywp 82 | git remote set-branches --add origin 4.9.8 83 | git fetch origin 4.9.8:latest 84 | git merge -X theirs latest 85 | ``` 86 | 87 | If you get any conflicts run `git merge-tool` and answer "d" (to delete) for each 88 | file in conflict, if any. Then git commit to complete the merge. 89 | 90 | `git push dokku master` 91 | 92 | Warning: A 'traditional' upgrade performed using Wordpress's own UI based upgrade process will not 93 | survive a server app restart (due to the ephemeral nature of the underlying docker 94 | based filesystem) and thus should not be attempted if you want to persist the upgrade. 95 | 96 | ### Plugins 97 | 98 | Plugins stored in `wp-content/plugins` and uploads stored in `wp-content/uploads` are 99 | given special persistence via the `dokku storage:mount` commands in this installation process. 100 | 101 | Plugins should thus be installed via Wordpress's own UI based installation method and 102 | will persist across remote reboots and won't get affected by subsequent git pushes 103 | when upgrading. 104 | Manual installation by copying plugins into the local git repo and pushing them up 105 | will not work. 106 | 107 | ### Themes 108 | 109 | The `wp-content/themes` directory is not given any special persistence on the remote server. 110 | So whilst there is persistence whilst the Wordpress app is running and themes 111 | will successfully install - any such new themes or theme customisations will not survive a 112 | remote app restart/server reboot. Thus any custom themes should be copied 113 | into `wp-content/themes` in the local git repo and pushed up. 114 | 115 | Tip: It can be tricky to view the state of the filesystem that your wordpress app 116 | actually resides in, because of the layered nature of the underlying docker filesystem. 117 | To view the actual filesystem of your wordpress app 'mywp' on server 'dokku.me': ssh into 118 | your server e.g. `ssh root@dokku.me` then `dokku run mywp bash` then `ls /app/wp-content/`. 119 | Alternatively install a Wordpress 120 | [file manager plugin](https://wordpress.org/plugins/wp-file-manager/) to view and 121 | download new/customised theme files on the remote server and into your local repo. 122 | 123 | When upgrading using the above Wordpress upgrade instructions - any custom themes 124 | in the local repository will be deleted in order to synchronise perfectly with the 125 | fresh new version of Wordpress. 126 | To preserve extra/customised themes back them up before upgrading the local repo 127 | and restore them into the local `wp-content/themes` directory after the upgrade. 128 | Alternatively do not delete the files you want to keep during the `git merge-tool` step of the 129 | local upgrade process - though be careful as you probably want to replace 130 | default themes to be compatible with the new upgraded version of Wordpress. 131 | -------------------------------------------------------------------------------- /config/composer.json: -------------------------------------------------------------------------------- 1 | {"require": {"php": ">=5.6", "ext-gd": "*"}} 2 | -------------------------------------------------------------------------------- /config/composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "2c47ba96599cc3aa60317886030d0ce5", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "stable", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": { 16 | "php": ">=5.6", 17 | "ext-gd": "*" 18 | }, 19 | "platform-dev": [] 20 | } 21 | -------------------------------------------------------------------------------- /config/wp-config.php: -------------------------------------------------------------------------------- 1 |