LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

How to Fire Up Wordpress in Three Commands

Typically when you setup WordPress, you’ve got to do the following:

  • Install MySQL
  • Run mysql_secure_installation (not strictly necessary but you should!)
  • Create the MySQL database
  • Create the MySQL user
  • Grant the MySQL user database privileges
  • Install a web server such as Apache or NginX
  • Install PHP
  • Configure the web server to support PHP
  • Create the web root directory and set permissions
  • Create log files if necessary, and setup logfile rotation
  • Configure your web server for the site you want to run
  • Download WordPress and untar
  • Set permissions on the files and directories

…and then you’re ready to run the WordPress install script.

True, if you’re on shared hosting, you may have a 1-click installer such as Softaculous or Fantastico available. But if you’re running things on your VPS, you’ll have to do these things manually.

If only there was a way to…oh, I don’t know…bundle up all these tasks and setup and components and put them in some sort of…what would we call it…container…

Enter Docker

Try this on Debian 10 (obviously, replace wordpress.lowend.party with whatever your site hostname is):

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
docker container run --detach --publish=80:80 --hostname=wordpress.lowend.party wordpress

Or if you want be cheeky, you could even do it in a single cut-and-paste, though I think using && doesn’t qualify it as one command:

curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && docker container run --detach --publish=80:80 --hostname=wordpress.lowend.party wordpress

Now go that address in your browser and WordPress will be running!

Behind the Scenes

curl -fsSL https://get.docker.com -o get-docker.sh

This command pulls down the get-docker.sh setup script.

sh get-docker.sh

This script runs them. Note that we save a step by running in a new shell as opposed to having to chmod first. The script sets up the repo, updates apt, downloads the docker packages and installs them, etc.

Here’s the output. As you can see, the script tells you what it’s doing:

root@wordpress:~# curl -fsSL https://get.docker.com -o get-docker.sh
root@wordpress:~# sh get-docker.sh 
# Executing docker install script, commit: 26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c
+ sh -c apt-get update -qq >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl gnupg >/dev/null
+ sh -c curl -fsSL "https://download.docker.com/linux/debian/gpg" | apt-key add -qq - >/dev/null
Warning: apt-key output should not be parsed (stdout is not a terminal)
+ sh -c echo "deb [arch=amd64] https://download.docker.com/linux/debian buster stable" > /etc/apt/sources.list.d/docker.list
+ sh -c apt-get update -qq >/dev/null
+ [ -n ]
+ sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null
+ sh -c docker version
Client: Docker Engine - Community
Version: 19.03.12
API version: 1.40
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:45:50 2020
OS/Arch: linux/amd64
Experimental: false

Server: Docker Engine - Community
Version: 19.03.12
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:44:21 2020
OS/Arch: linux/amd64
Experimental: false
Version: 1.2.13
GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
Version: 0.18.0
GitCommit: fec3683
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:

sudo usermod -aG docker your-user

Remember that you will have to log out and back in for this to take effect!

WARNING: Adding a user to the "docker" group will grant the ability to run
containers which can be used to obtain root privileges on the
docker host.
Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
for more information.

Finally, we run the container. Let’s break down the docker command:

  • docker container run: The docker CLI has over 30 commands. You can type “docker help” or “docker container help” to read more about them. Or read the docker man pages (“man docker” or “man docker-run”).
  • –detach: tells Docker to run this container in the background.
  • –publish=80:80: this tells Docker to take this container’s port 80 and map the VPS’s port 80 to it.
  • –hostname=wordpress.lowend.party: Apache needs to set a ServerName so it’s appropriate to set the hostname inside the container.
  • wordpress: the name of the container

When run, Docker will pull down the “wordpress” container (and all its dependencies) and run them. You’ll see a lot of messages like this as it works:

eb2d00c10344: Extracting 72.42MB/76.65MB

Here’s the complete output:

root@wordpress:~# docker container run --detach --publish=80:80 --hostname=wordpress.lowend.party wordpress
Unable to find image 'wordpress:latest' locally
latest: Pulling from library/wordpress
8559a31e96f4: Pull complete
e0276193a084: Pull complete
eb2d00c10344: Pull complete
f54006e0dc29: Pull complete
e0d3d1244592: Pull complete
3a60f364b0c5: Pull complete
3e309988c00b: Pull complete
f65316e96b10: Pull complete
b22875b95a2a: Pull complete
0c78caf16ec3: Pull complete
4fc30aae7ee5: Pull complete
37b016cacdc6: Pull complete
fd56bf3cc539: Pull complete
b0ba72715b92: Pull complete
03888322beaa: Pull complete
7e7ce3c89644: Pull complete
f6556df913cf: Pull complete
11b2e0de50b5: Pull complete
1c79bd2495a6: Pull complete
0f2fb876982e: Pull complete
Digest: sha256:6f609ebf8518069516df36f0ab504735f8e563c1e303c37eba4902e732fcc6c6
Status: Downloaded newer image for wordpress:latest

You can see the container running with “docker ps”:

root@wordpress:~# docker ps
168421e25271 wordpress "docker-entrypoint.s…" 15 seconds ago Up 13 seconds>80/tcp objective_neumann

In fact, check out ps -ef:

root 11698 11682 0 10:04 ? 00:00:00 apache2 -DFOREGROUND
www-data 11742 11698 0 10:04 ? 00:00:00 apache2 -DFOREGROUND
www-data 11743 11698 0 10:04 ? 00:00:00 apache2 -DFOREGROUND
www-data 11744 11698 0 10:04 ? 00:00:00 apache2 -DFOREGROUND
www-data 11745 11698 0 10:04 ? 00:00:00 apache2 -DFOREGROUND
www-data 11746 11698 0 10:04 ? 00:00:00 apache2 -DFOREGROUND

What jiggery-pokery is this?!? Why is apache running in the main process table? Remember that a container is not a VM. You can see the difference by looking at the cgroup. First, here is the cgroup for sshd, a standard system process started when the VM booted and running on PID 9040:

root@wordpress:~# ps -o cgroup 9040

Now here’s the cgroup for PID 11698, one of the apache2 processes shown above:

root@wordpress:~# ps -o cgroup 11698

Wrapping Up

There’s a lot more you could do with this setup to make it more production-worthy, such as setting up Let’s Encrypt for SSL (yes, there’s a cerbot image on DockerHub) or mapping a directory for uploads, images, etc. into the container. But the point of this tutorial was to show you how radically simple Docker can make software setups.



  1. Mancior:


    What are DB credentials? Username, password, db name?

    May 19, 2021 @ 6:08 am | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

Your email address will not be published. Required fields are marked *