[GUIDE] Setup WP on a VPS without cpanel

Gogol

Administrator
Staff member
Moderator
Executive VIP
Jr. VIP
Joined
Sep 10, 2010
Messages
11,805
Reaction score
26,657
I have been thinking of doing a tutorial on this for a long time, but I couldn't get enough time to do so. Now that I have some free time today, I decided to write a tutorial. I hope it helps someone out there.

Prerequisites:
  1. A decent spec'd VPS with Ubuntu latest stable version installed, and with root access - Anything with over 2 gigs of RAM should be enough to get started.
  2. Basic Linux knowledge. Although we will go through each and every step in detail, I still recommend taking the time to learn the basics like how to login to a VPS (extra points if you can login using private keys), view all files, move around inside folders, delete files/folders, edit files, rename and copy files, watch resource usage and so on.

I am assuming that you do not have anything else installed on the VPS, and it is a fresh one. Let's assume the ip of the server to be 10.10.1.100 and the username to be root.


Step 1

Login to the VPS.


I am using mac (the process should be exactly the same for linux), but ssh command should be available for windows as well. You do that by opening up the terminal/command prompt, and then by issuing the following command:

Code:

You will be greeted with a password challenge. Entering password can be confusing since the terminal will not show the password as you are typing it. Don't worry about it, type the password and hit enter. You should be logged in.

Variations/Gotchas

1. Some hosts do not allow password based logins by default, like AWS EC2. If you have such a host, and you have a private key file, modify the command for login to the following:
Code:
ssh -i /path/to/your/key/file [email protected]
The -i flag here means identity.

2. Some hosts do not provide direct root access, instead they allow you to become a root user after you have logged in. AWS EC2 does this for example. For handling that (feel free to combine with the -i flag in case it requires an identity file as well), login normally, e.g. by issuing:
Code:
After logging in, become a root user by issuing:
Code:
 sudo -i
It might ask for the password again. If it does, enter the password again.

Step 2

Install docker.


This step can be a little daunting, and it is bit of a tutorial by itself. You could follow the official guide and install it by yourself. If you want to do that, read the following guide:

Code:
https://docs.docker.com/engine/install/ubuntu/

But hey, we are blackhatters right? :D

I have actually made a convenience script that will do the following:

1) Update the server's operating system.
2) Install git, curl and nginx.
3) Install docker and docker compose.

VT of the convinience script:
Code:
https://www.virustotal.com/gui/file/b2ad20975d55a5aeb727c6e6d7864a60bee88ec1a563f2ca8f7936fad2e5185e?nocache=1

Download the script by issuing the following:
Code:
wget https://raw.githubusercontent.com/noc2spam/shelly/main/dockerize.sh
It will download dockerize.sh in the same folder you are in right now. Verify that the script downloaded correctly, by issuing:
Code:
 ls -l
You will see dockerize.sh in the list of files.
Now, run the script by issuing:
Code:
sh dockerize.sh
It will install the above mentioned softwares once you run this command.

Variations/Gotchas

1.
Your ubuntu may be missing the wget package. If it does, you won't be able to download the script atall, it will error out saying wget is not found. If that happens, issue the following command to install wget, and then continue with the Step 2.

Code:
 apt install wget -y

2. During installation, you might encounter the following screens:

screen 1:
1689947303621.png

If you see this screen, just press enter. and it will continue.

Screen 2:
1689935883772.png

If you see this screen, press TAB once, and then press enter. It will continue.




Step 3

Install a fresh instance of WP


Trust me, we have already done more than half of the work! Was it very difficult? I guess not, lol. You could use this setup for any kind of apps you can imagine (vpn clients/servers, reverse proxies, forum softwares, python scripts, node.js scripts and many more!). But let's focus on getting our site live first.

Let's first understand what a typical wp installation needs. It has two parts - first is the actual php server, that runs wp itself. Second part is the mysql server, that is the database of the wp installation. Addititionally, we need to access the database time to time, and for that we will install phpmyadmin as well.

Luckily, because you are using docker, you will not have to install any of the dependencies manually. All you need is a docker-compose.yaml file to define what you need to install, and docker will take care of virtualising everything for you. We will also need an .env file for defining the db access details. For keeping everything clean and well maintained, let's keep all our files in ~/sites/project-name (the ~ translates to the home folder, which in our case is /root/, because we are logged in as the root user.). Let's make a directory by issuing:
Code:
mkdir -p ~/sites
Then go to the sites folder:
Code:
 cd ~/sites

Now, you could create your own docker-compose.yaml file, or for saving time, use this one I have already made for you.
Here's the repository:
Code:
https://github.com/noc2spam/wp-on-docker/

VT:
Code:
https://www.virustotal.com/gui/file/81d1d00bfdc28e33bcdaf4a6dd04844483b3eecfe61d366ec94fc2f96e5f58c4?nocache=1
To clone this repository, issue the following (I am considering you already are on ~/sites):
Code:
git clone https://github.com/noc2spam/wp-on-docker/ project-name

Change the project-name with the name of your project. Make sure there is a space between the repository url and the folder-name. After the command finishes running, go the folder by issuing (change project-name with the folder name you chose):
Code:
cd project-name

Now, let's make our .env file by copying the .env.example file provided in the repository. Issue the following command for doing so:
Code:
 cp .env.example .env

Then open the .env file for editing the db details. We will be using nano editor because it is the easiest to deal with (That's what the vi jokes are all about!). You can navigate to the lines by using your keyboard's arrow keys. You can save the file by pressing ctrl + x then pressing y, then pressing enter.

Code:
nano .env

What you need to change here are these lines:
Code:
https://github.com/noc2spam/wp-on-docker/blob/e7383465ccf1a7bde7cec581be82d121662a5649/.env.example#L2-L5
You could keep the WORDPRESS_DB_USER and WORDPRESS_DB_NAME the same, but be absolutely sure to change the WORDPRESS_DB_PASSWORD and WORDPRESS_ROOT_PASSWORD, because otherwise you are opening doors to the hackers.

Verify that the changes are correct, by issuing:
Code:
cat .env

After you have modified the .env file, issue the following command to install the whole stack, as well as sending the stack to the background (-d achieves that. Without this flag, the stack will keep running in the foreground, and if you exit the terminal, the containers will all stop. You can also press ctrl + z to exit without stopping the containers, just in case you ever need to).

Code:
 docker compose up -d

Give it a minute or two to setup completely, and Voila!

You now have phpmyadmin, wordpress and mysql installed. But the question is, how would you now connect these to your domain? How would you setup ssl?

I feel this is where it gets a bit more complicated, and people give up. But believe me, it is not very difficult to do so. Yes, issuing ssl certs can be a little challenging to achieve, but there is a shortcut to that. We will be using cloudflare flexible ssl for avoiding having to setup SSL ourselves.

First, setup Cloudflare with your domain. Follow the official doc if you are not sure how to do that:
Code:
https://developers.cloudflare.com/fundamentals/get-started/setup/add-site/

Then add 3 A records with the following values (all records should be "proxied", not dns only. Also make sure to change the IP to your server IP):
Code:
Host: @, IP: 10.10.1.100, TTL: leave it default
Host: www, IP: 10.10.1.100, TTL: leave it default
Host: phpmyadmin, IP: 10.10.1.100, TTL: leave it default

This will connect yourdomain.com to the server IP. After that, go to the SSL/TLS and check the Flexible SSL option on, like this:

1689943687999.png

Verify that it works by going to both www and non www version of your domain. It should show you the default nginx page that we installed when we installed the docker convenience script. It should already have the https on, even if our server only listens to port 80.

Then go to the Edge Certificates menu, and make sure 'Always Use HTTPS' is turned on. This will save you from having to setup a rule yourself.

Now, go back to the terminal, and go to /etc/nginx/sites-enabled folder by issuing:
Code:
 cd /etc/nginx/sites-enabled
This directory has the nginx configurations for connecting the local containers to the domain (nginx works as a reverse proxy here).
We will create a new config here called yoursitename (change yoursitename with something easy to remember) by issuing:
Code:
 nano yoursitename
Inside the editor, copy paste the following code (IMPORTANT: be sure to change yourdomain.com to your domain name):
Code:
https://gist.github.com/noc2spam/241b1a0e0b9083b8769c37937463775c
Press ctrl + x, press y and press enter to save and exit.
Verify there is no mistake in the nginx setting by issuing:
Code:
nginx -t
If it says the configuration is correct, then restart nginx service by issuing:
Code:
service nginx restart
Now try visiting the following URLs:
Code:
yourdomain.com
www.yourdomain.com
phpmyadmin.yourdomain.com
The first domain should point to the wp installation.
The second domain should redirect to the first domain.
The third domain should point to the phpmyadmin, which you can login with the WORDPRESS_DB_USER and WORDPRESS_DB_PASSWORD (or the root password, with root as username) that you had setup earlier.

Things to note:
Your wp installation is available at:
Code:
~/sites/project-name/wordpress
Your database's files are available at
Code:
~/sites/project-name/mysql

You can stop the containers by going to ~/sites/project-name and issuing:
Code:
docker compose down

Your can prune docker cache (it can become huge if not maintained for a while) by issuing:
Code:
docker system prune -a

You can check if your containers are running fine, by issuing:
Code:
docker ps

You can monitor memory usage by issuing:
Code:
free -m

You can restart the server anytime you want to by issuing
Code:
reboot
This will not stop the containers. The containers will all start automatically when the server reboots (so yeah, your wp installation is now fault tolerant as well!).


Did I miss anything? Do you think I could do it in a better way ( I feel like the nginx could also be a part of the stack, but I installed it separately so that people can learn how to make it work without too much sweat)? Please comment below. :)
Not to mention, if you have any trouble following this guide, please reply here. I will do my best to help you out.

Thank you for taking the time to read this.

Have a nice time with the installation!
 
Good guide :) Wish I didn‘t had to figure the docker stuff out on my own when I started
 
Who needs chatgpt or stack overflow when you got blurry! What are the disadvantages to docker, so I know that the advantages outweigh them? How easier is it to develop with a setup like this, if you are updating theme code for example?
 
Great guide, though myself I am to lazy and use Runcloud .. Thanks for taking the time to write it .. =)
 
I've been battling with docker for ages. I love it but I cannot stand it at the same time. The first issue I find is that I most of the times end integrating multiple systems, which already have multiple database servers (for sql replication for example), which is very frustrating (because replication in SQL works really bad

So ultimately I don't feel the need of using docker most of the times and prefer to stay leaner (if not chosing to go the DirectAdmin path)

Also I find docker difficult to maintain, because many people deploy one single instance of docker per site which is great in terms of isolation, but it really bad in terms of maintenance (you have to keep maintaining each single container upgrades permanently). Also recovering a docker instance is kind of obnoxious. Ultimately working with linux straight, have a ton of recovery options if something has been corrupted (for example fail safe mode). But in Docker, simply willing to change a simple configuration parameter (for example if service cron is not running by default in the image and you need such service, a new container must be built from scratch with the new init parameters)

For some reason, in my experience docker containers, end working as virtual machines, despite they are not supposed to be working like that, and a lot of configuration files end in places that are not volumes, which means, if the container is lost, a ton of configurations could be lost accidentally (and contrarily to a Linux raw machine, a docker container breaks way more easily for a lot of issues in the init script).

Conclusion: I would not use docker if you are not a super-expert with docker. It brings more headaches than happiness. I would keep things simple in the Linux VPS without extra layers.
 
Comprehensive and good to know for the future. Thanks, Mr. BluryBit
Great guide, though myself I am to lazy and use Runcloud .. Thanks for taking the time to write it .. =)
wow great guide

Good guide :) Wish I didn‘t had to figure the docker stuff out on my own when I started
Thank you so much for taking the time to read this. :)

Who needs chatgpt or stack overflow when you got blurry! What are the disadvantages to docker, so I know that the advantages outweigh them? How easier is it to develop with a setup like this, if you are updating theme code for example?
Docker does have a learning curve, but once you become confident about it, there’s nothing that can beat it in a monolithic setup. Development is pretty easy as well. But for custom themes and so on, I would not put the wordpress folder in .gitignore (which basically ignores the folder from git). I would rather set everything up locally (instead of directly setting up in the VPS first) and will first run the stack locally. Running the stack locally for the first time will create the wordpress folder, which I will then commit to git. For deployment, I would pull everything inside the VPS as usual, but it will also include that wordpress folder. I guess people don't even put the whole wordpress folder in the volume, but only the wp-content folder (other files are not needed to be touched for like 99.99% cases).

Docker is pretty much a standard in the industry, which speaks for itself.

I've been battling with docker for ages. I love it but I cannot stand it at the same time. The first issue I find is that I most of the times end integrating multiple systems, which already have multiple database servers (for sql replication for example), which is very frustrating (because replication in SQL works really bad

So ultimately I don't feel the need of using docker most of the times and prefer to stay leaner (if not chosing to go the DirectAdmin path)

Also I find docker difficult to maintain, because many people deploy one single instance of docker per site which is great in terms of isolation, but it really bad in terms of maintenance (you have to keep maintaining each single container upgrades permanently). Also recovering a docker instance is kind of obnoxious. Ultimately working with linux straight, have a ton of recovery options if something has been corrupted (for example fail safe mode). But in Docker, simply willing to change a simple configuration parameter (for example if service cron is not running by default in the image and you need such service, a new container must be built from scratch with the new init parameters)

For some reason, in my experience docker containers, end working as virtual machines, despite they are not supposed to be working like that, and a lot of configuration files end in places that are not volumes, which means, if the container is lost, a ton of configurations could be lost accidentally (and contrarily to a Linux raw machine, a docker container breaks way more easily for a lot of issues in the init script).

Conclusion: I would not use docker if you are not a super-expert with docker. It brings more headaches than happiness. I would keep things simple in the Linux VPS without extra layers.
I understand. I did have to fight as well. But I took the time and learned it.
For normal wp instances, you shouldn't need to touch the docker containers atall. You could also have multiple database servers, but you will have to map the ports correctly (it can be tricky, because mariadb/mysql containers are exposed to port 3306 by default). The easiest way to avoid this is to have multiple dbs inside one container, but that also needs to be done correctly.

Same actually goes for maintainence as well. If you are good with docker, it will be really easy. But if not, you should probably not touch it much. But knowing this wonderful software is certainly a step forward to become a devop/dev at the same time. In any modern software team, people would want you to know docker, because it makes it possible to run the apps in any kind of environment be it linux/windows/mac or so on. For personal project, you could keep it simple and avoid using docker though.
 
Update: Another thing that could be helpful to add is the fact that you CAN use your ssh details in a file manager such as Filezilla. You don't need another FTP server. Use these settings:
Code:
https://serversaurus.com.au/knowledge-base/connect-via-sftp-using-ssh-key-authentication-with-filezilla/
So, whereever you had to use nano editor, you could just do it from your favorite ftp client as well.
 
Nice and detailed tut!

Haven't used docker will look into it.

I prefer something like cyberpanel or cloudpanel since I have to setup multiple sites and I always mess up things without a control panel.
 
One question, what is more important for a website to work without overload, a lot of CPU core or a lot of memory?
 
One question, what is more important for a website to work without overload, a lot of CPU core or a lot of memory?
This varies depending on what your website does. If your hosting provider has a way to monitor the load, check and adjust hardware accordingly. AWS/digital ocean allows you to customise hardware of a vps for example. Perhaps choose a provider that offers such customisation.
 
Good one. Thanks.
i have a question. Why Linux and ssh but not Windows/IIS ?
Umm not sure to be honest. Perhaps it could be done, but I prefer debian based operating systems for hosting apps. It’s opensource and it works, everytime. Which also means that there’s less chance of getting hacked because of a hidden vulnerability in the kernel, because these opensource projects are audited by thousands if not more smart people.

Nothing against windows though. For me it doesn’t make sense. :)
 
One question, what is more important for a website to work without overload, a lot of CPU core or a lot of memory?
In general: memory.
Unless your server is doing something cpu-intensive (eg you have a video streaming website and your server transcodes videos on the fly, or you're hosting an online game on your webserver), the limiting factor for it will be available memory.

Most websites are what we call "io-bound". and a lot of backend code out there won't exploit multiple cpu cores anyways.
 
Good one. Thanks.
i have a question. Why Linux and ssh but not Windows/IIS ?
For one, docker engine doesn't run natively on windows.

And two, Linux and ssh is like the "de-facto" os and protocol on the internet. Linux vpses are much cheaper, and all of them come with SSH.
 
This is a great step by step tutorial! Should try this out on my free time. :)

Noob question. What are the pros and cons of running the WP site on docker compared to cPanel, cloudpanel and the like?
 
Back
Top