• Home
  • |
  • Blog
  • |
  • Detailed Procedure To Set Up Your Own WordPress Hosting Platform On Ubuntu Or Debian Platform!
Set up Your Own WordPress Hosting Platform

Whether you are an individual or a small business that wants to have your own website, you have multiple options to go with. You will have ready-to-use hosting services and a lot of web design and development consultants with a lot of exciting offers. Well, you can use them. We are not against using those services. However, we also urge you to learn, and if possible, set up your own WordPress hosting platform either for your primary website or just to create a standby website just in case of disasters. In our experience, we can definitely say that every website owner will come across a situation at least once in his life where he realized that he should have been learned to set up his own WordPress hosting platform. So, before getting too late. Let’s learn how to set up your own WordPress hosting platform either on a local server or a cloud platform.

We suggest you set up your own hosting platform on a cloud platform rather than setting up on a local server. However, the procedure is the same. If you have tight pockets, then you can try this out on a local server. Then you can move towards the cloud.

Why Should You Set Up Your Own WordPress Hosting Platform?

As we said earlier, you can go with any of the best online hosting platform. However, we also recommend having your own too. It gives a lot of freedom, control, and transparency. Let’s see the benefits of having your own hosting platform.

  1. If you own your hosting, you will have full control over it. You can perform any activities at any given time.
  2. You will have full control over the data and security policies. You can manage everything in your own way.
  3. You can use your hosting platform as a DR setup during the time of disasters.
  4. You can use the platform as a test machine. You can test the changes on your locally hosted platform before implementing them on the production site. This helps in maintaining the production site secure and intact.

Whatever may be the reason, it is better to have your own hosting platform as a DR setup.

There are some downsides as well:

  1. You are not going to have support if something goes wrong.
  2. You should manage everything, from building to maintenance, so it needs strong technical knowledge.
  3. You should bear with an extra cost. You should be good at capacity planning. Otherwise, you may end up with a huge cost.

Keeping all these disadvantages, especially for small businesses or individual website owners, we recommend buying an online hosting platform for your primary site. And build a copy of that on your own hosting platform.

Prerequisites To Set up Your Own WordPress Hosting Platform:

Prerequisites are simple. The one must-have thing is that a server, no matter whether on on-premises or on the cloud. When we say server, we are not talking about a big size servers most likely deployed on data centers. You can have a small system that has single-core processors, 1 GB of RAM, with 10 GB of disk storage. It is up to you how much you can spend on hardware. You do not need to worry about the software requirements. The software we are going to use here is all open-source. No additional cost is required for software. If you want to buy premium plugins for your WordPress, then it’s your decision.

What Is WordPress?

WordPress is an open-source Content Management System (CMS) written in PHP language. WordPress is one of the best and most used website builders today. It can be used to build a blog, e-commerce, business, portfolio website. Its ease of use, highly customizable features, tons of plugins, themes, cost-free, and platform flexibility have captured more than 35% of the website hosting landscape.

How do WordPress Websites work?

Before we jump right into setting up the WordPress hosting platform, we should urge to learn how does WordPress works in the background. This will help a lot to work on the production deployments. Please don’t skip this section as you are not going to get this information on most of the blog posts. People just skip this and just start building WordPress without prior knowledge.

WordPress needs three main components to work:

  1. Webserver: A server that receives web requests and responds with the requested content.
  2. PHP: PHP is a server-side programming language, PHP FPM interpreter. It sits between the requested resources and the Webserver. It supplies the requested content to the Webserver.
  3. MySQL: It stores all the data in its tables. It supplies the queried data to the PHP interpreter.

To answer How do WordPress Websites work in the background:

  1. When a Webserver receives a request from a user’s browser.
  2. The Webserver will create an Inter-Process Communication channel over a TCP or Unix socket with the PHP FPM interpreter and send the request to the PHP FPM interpreter.
  3. PHP FPM interpreter will assign the request to the PHP interpreter pool.
  4. The assigned PHP Interpreter will query the MySQL database asking the PHP resource stored in its table.
  5. When MySQL retributive the PHP data and shares the data to the PHP interpreter.
  6. The interpreter then executes the PHP file received from the MySQL database and sends the output of the PHP file to the PHP FPM. PHP FPM will process the output and send the output to the Webserver.
  7. The Webserver will respond to the browser with the data to render.

How To Set Up Your Own WordPress Hosting Platform On Ubuntu Or Debian platform?

You might have seen many blog posts on how to install WordPress on Linux, Windows, Mac, and cloud platforms. However, This blog is not just limited to the installation of WordPress on your favorite platform. It shows you how to set up your own hosting platform using WordPress, either on a local server or cloud platform. We have divided this procedure into six sub-sections to make you understand the process in a better way.

  1. Install the services required to run the WordPress:
  2. Configure nginx.conf file:
  3. Set up PHP interpreter:
  4. Set up MySQL security:
  5. Set up WordPress Application:
  6. Install WordPress:acc

Time needed: 1 hour.

How to Set up Your Own WordPress Hosting Platform on Ubuntu or Debian platform?

  1. 1st Section: Install the services required to run the WordPress:

    In the first section, we will install MySQL, PHP, and Nginx web servers.

    Before that let’s start by updating the repositories and installing new packages.

    $ sudo apt update && sudo apt upgrade -y

    Update package repositories and install the updated packages

  2. Install MySQL & PHP packages

    Install these four packages:
    1. mysql-server
    2. php-mysql
    3. php-fpm
    4. monit

    $ sudo apt install mysql-server php-mysql php-fpm monit

    Install mysql server and phe mysql on Ubuntu

  3. Add PPA repository for Nginx

    The purpose of adding the PPA repositories is to have the latest available version of Nginx.

    $ sudo add-apt-repository ppa:nginx/stable && sudo apt update

    Add Ngins PPA repository on Ubuntu

  4. Install Nginx

    $ sudo apt install nginx

    Install Nginx on Ubuntu

  5. Enable and check the status of mysql php-sql monit

    $ sudo systemctl start mysql nginx php7.4-fpm monit
    $ sudo systemctl enable mysql nginx php7.4-fpm monit
    $ sudo systemctl status mysql nginx php7.4-fpm monit | grep Active


    Enable and check the status of mysql php-sql monit

  6. 2nd Section: Configure nginx.conf file:

    Switch to the superuser and make a copy of nginix.conf file. Then create a new nginx.conf file in the same directory.

    $ sudo su
    # cd /etc/nginx/
    # mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original
    # nano /etc/nginx/nginx.conf


    Create nginx config file

  7. Update this content in the nginx.conf file

    user www-data;
    worker_processes auto;

    pid /run/nginx.pid;

    events {
    worker_connections 1024;
    }

    http {
    include mime.types;
    default_type application/octet-stream;

    #log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
    # ‘$status $body_bytes_sent “$http_referer” ‘
    # ‘”$http_user_agent” “$http_x_forwarded_for”‘;
    error_log /var/log/nginx_error.log error;
    #access_log logs/access.log main;

    sendfile on;
    #tcp_nopush on;

    keepalive_timeout 65;

    # SSL
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # no sslv3 (poodle etc.)
    ssl_prefer_server_ciphers on;

    # Gzip Settings
    gzip on;
    gzip_disable “msie6”;
    gzip_vary on;
    gzip_min_length 512;
    gzip_types text/plain text/html application/x-javascript text/javascript application/javascript text/xml text/css application/font-sfnt;

    fastcgi_cache_path /usr/share/nginx/cache/fcgi levels=1:2 keys_zone=microcache:10m max_size=1024m inactive=1h;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    }


    Content of nginx.conf file

  8. Create casheing file and test the nginx configurations

    # mkdir -p /usr/share/nginx/cache/fcgi
    # nginx -t


    Create casheing file and test the nginx configurations

  9. 3rd Section: Set up PHP interpreter:

    To set up PHP interpreter, some PHP packages are required to install. Let’s update the repository before installing PHP packages.

    # apt update


    Update package repositories

  10. Install some of these PHP extension packages required to set up php interpreter

    Install these packages:
    1. php-json
    2. php-xmlrpc 3.
    3. php-curl
    4. php-gd
    5. php-xml
    6. php-mbstring

    # apt install php-json php-xmlrpc php-curl php-gd php-xml php-mbstring


    Install packages required to set up php interpreter

  11. Set up php-interpreter configuration file

    PHP interpreter is a middle entity sits between a webserver and PHP application. It is mandatory to set up PHP interpreter to function WordPress.

    Take a backup of php-fpm.conf and create a new php-fpm.conf file.

    # mkdir /var/run/php-fpm
    # cd /etc/php/7.4/fpm/
    # cp php-fpm.conf php-fpm.conf.orig
    # echo “” > php-fpm.conf
    # nano /etc/php/7.4/fpm/php-fpm.conf


    Set up php pool configuration file

  12. Content of php-fpm.conf file

    php-fpm is a global interpreter file in which we should have set the path in which we are going to have default pool configuration for each website.

    [global]
    pid = /run/php/php7.4-fpm.pid
    error_log = /var/log/php-fpm.log
    include=/etc/php/7.4/fpm/pool.d/*.conf


    Content of php pool config file

  13. Create a new thesecmaster.conf file

    In previous step we have configured the pool PHP interpreter file. In this step we will configure the default PHP pool per site file.

    # nano /etc/php/7.4/fpm/pool.d/thesecmaster.conf

    This file let you configure how many requests, process, etc can handle simultaneously, the values are really depends on the hardware resources. If you have a server with more number of RAM and processor then you can increase the values to the extent.

    [thesecmaster]
    listen = /var/run/php/thesecmaster.sock
    listen.owner = arunkl
    listen.group = www-data
    listen.mode = 0660
    user = arunkl
    group = www-data
    pm = dynamic
    pm.max_children = 75
    pm.start_servers = 8
    pm.min_spare_servers = 5
    pm.max_spare_servers = 20
    pm.max_requests = 500

    php_admin_value[upload_max_filesize] = 10G
    php_admin_value[error_log] = /home/arunkl/logs/phpfpm_error.log
    php_admin_value[open_basedir] = /home/arunkl:/tmp


    Configuration of fpm pool file

  14. Content of top level PHP configuration file php.ini file

    This is the last process to set up PHP interpreter. This file has plethora of options to set. Just copy this content in your php.ini file. If you know more about in this file, just put your quaries in the comments section below in the post.

    # mv /etc/php/7.4/fpm/php.ini php.ini.orig
    # nano /etc/php/7.4/fpm/php.ini


    Create php.ini file

  15. Content of php.ini file

    [PHP]
    engine = On
    short_open_tag = Off
    asp_tags = Off
    precision = 14
    output_buffering = 4096
    zlib.output_compression = Off
    implicit_flush = Off
    unserialize_callback_func =
    serialize_precision = 17
    disable_functions =
    disable_classes =
    zend.enable_gc = On
    expose_php = Off
    max_execution_time = 30
    max_input_time = 60
    memory_limit = 128M
    error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
    display_errors = Off
    display_startup_errors = Off
    log_errors = On
    log_errors_max_len = 1024
    ignore_repeated_errors = Off
    ignore_repeated_source = Off
    report_memleaks = On
    track_errors = Off
    html_errors = On
    variables_order = “GPCS”
    request_order = “GP”
    register_argc_argv = Off
    auto_globals_jit = On
    post_max_size = 8M
    auto_prepend_file =
    auto_append_file =
    default_mimetype = “text/html”
    default_charset = “UTF-8”
    doc_root =
    user_dir =
    enable_dl = Off
    file_uploads = On
    upload_max_filesize = 25M
    max_file_uploads = 20
    allow_url_fopen = On
    allow_url_include = Off
    default_socket_timeout = 60
    [CLI Server]
    cli_server.color = On
    [Date]
    [filter]
    [iconv]
    [intl]
    [sqlite]
    [sqlite3]
    [Pcre]
    [Pdo]
    [Pdo_mysql]
    pdo_mysql.cache_size = 2000
    pdo_mysql.default_socket=
    [Phar]
    [mail function]
    SMTP = localhost
    smtp_port = 25
    mail.add_x_header = On
    [SQL]
    sql.safe_mode = Off
    [ODBC]
    odbc.allow_persistent = On
    odbc.check_persistent = On
    odbc.max_persistent = -1
    odbc.max_links = -1
    odbc.defaultlrl = 4096
    odbc.defaultbinmode = 1
    [Interbase]
    ibase.allow_persistent = 1
    ibase.max_persistent = -1
    ibase.max_links = -1
    ibase.timestampformat = “%Y-%m-%d %H:%M:%S”
    ibase.dateformat = “%Y-%m-%d”
    ibase.timeformat = “%H:%M:%S”
    [MySQL]
    mysql.allow_local_infile = On
    mysql.allow_persistent = On
    mysql.cache_size = 2000
    mysql.max_persistent = -1
    mysql.max_links = -1
    mysql.default_port =
    mysql.default_socket =
    mysql.default_host =
    mysql.default_user =
    mysql.default_password =
    mysql.connect_timeout = 60
    mysql.trace_mode = Off
    [MySQLi]
    mysqli.max_persistent = -1
    mysqli.allow_persistent = On
    mysqli.max_links = -1
    mysqli.cache_size = 2000
    mysqli.default_port = 3306
    mysqli.default_socket =
    mysqli.default_host =
    mysqli.default_user =
    mysqli.default_pw =
    mysqli.reconnect = Off
    [mysqlnd]
    mysqlnd.collect_statistics = On
    mysqlnd.collect_memory_statistics = Off
    [OCI8]
    [PostgreSQL]
    pgsql.allow_persistent = On
    pgsql.auto_reset_persistent = Off
    pgsql.max_persistent = -1
    pgsql.max_links = -1
    pgsql.ignore_notice = 0
    pgsql.log_notice = 0
    [Sybase-CT]
    sybct.allow_persistent = On
    sybct.max_persistent = -1
    sybct.max_links = -1
    sybct.min_server_severity = 10
    sybct.min_client_severity = 10
    [bcmath]
    bcmath.scale = 0
    [browscap]
    [Session]
    session.save_handler = files
    session.use_strict_mode = 0
    session.use_cookies = 1
    session.use_only_cookies = 1
    session.name = PHPSESSID
    session.auto_start = 0
    session.cookie_lifetime = 0
    session.cookie_path = /
    session.cookie_domain =
    session.cookie_httponly =
    session.serialize_handler = php
    session.gc_probability = 1
    session.gc_divisor = 1000
    session.gc_maxlifetime = 1440
    session.referer_check =
    session.cache_limiter = nocache
    session.cache_expire = 180
    session.use_trans_sid = 0
    session.hash_function = 0
    session.hash_bits_per_character = 5
    url_rewriter.tags = “a=href,area=href,frame=src,input=src,form=fakeentry”
    [MSSQL]
    mssql.allow_persistent = On
    mssql.max_persistent = -1
    mssql.max_links = -1
    mssql.min_error_severity = 10
    mssql.min_message_severity = 10
    mssql.compatibility_mode = Off
    mssql.secure_connection = Off
    [Assertion]
    [COM]
    [mbstring]
    [gd]
    [exif]
    [Tidy]
    tidy.clean_output = Off
    [soap]
    soap.wsdl_cache_enabled=1
    soap.wsdl_cache_dir=”/tmp”
    soap.wsdl_cache_ttl=86400
    soap.wsdl_cache_limit = 5
    [sysvshm]
    [ldap]
    ldap.max_links = -1
    [dba]
    [opcache]
    [curl]
    [openssl]

    Content of php.ini file

  16. 4th Section: Set up mysql security:

    WordPress store all the media files, posts, comments, themes, and such resources will store in a relational database format. So MySQL is required to set up WordPress. Setting up MySQL is a very simple task, however, setting up securely is also a simple task, But, for that you should know certain things to implement. Let’s see how to set up MySQL securely.

    First thing when it comes to security is password. You should have a strong difficult to guess strong password. You can use this command to create a password just on your server.

    Make a note of this password. You should use this in the next step.

    # echo -n @ && cat /dev/urandom | env LC_CTYPE=C tr -dc [:alnum:] | head -c 15 && echo

    Create a random password on CLI in Ubuntu

  17. Set up mysql with security

    You should install mysql-client program on your server to set up MySQL Client. But, before that it is always good to update the repository and upgrade the patches. After you install the MySQL Client, find the mysql_secure_installation file and run it to set up the MySQL Client. Make a note of the random string that you generated in the previous step to use that as the password for the database user.

    # sudo apt update && sudo apt upgrade
    # apt install mysql-client
    # locate mysql_secure_installation
    # /usr/bin/mysql_secure_installation

    # systemctl restart mysql


    Set up mysql with security

  18. 5th Section: Set up WordPress Application:

    There are few things are required to set up before installing WordPress.
    1. You should have Nginx virtual host file for your site.
    2. Create a dedicated user for your site (optional..)
    3. Create a database and DB user in MySQL

    Add this content in your site configuration file.


    # nano /etc/nginx/conf.d/thesecmaster.conf

    server {
    listen 80;
    server_name www.thesecmaster.local;

    client_max_body_size 20m;

    index index.php index.html index.htm;
    root /home/arunkl/public_html;

    location / {
    try_files $uri $uri/ /index.php?q=$uri&$args;
    }


    # pass the PHP scripts to FastCGI server
    location ~ \.php$ {
    # Basic
    try_files $uri =404;
    fastcgi_index index.php;

    # Create a no cache flag
    set $no_cache “”;

    # Don’t ever cache POSTs
    if ($request_method = POST) {
    set $no_cache 1;
    }

    # Admin stuff should not be cached
    if ($request_uri ~* “/(wp-admin/|wp-login.php)”) {
    set $no_cache 1;
    }


    # WooCommerce stuff should not be cached
    if ($request_uri ~* “/store.*|/cart.*|/my-account.*|/checkout.*|/addons.*”) {
    set $no_cache 1;
    }

    # If we are the admin, make sure nothing
    # gets cached, so no weird stuff will happen
    if ($http_cookie ~* “wordpress_logged_in_”) {
    set $no_cache 1;
    }

    # Cache and cache bypass handling
    fastcgi_no_cache $no_cache;
    fastcgi_cache_bypass $no_cache;
    fastcgi_cache microcache;
    fastcgi_cache_key $scheme$request_method$server_name$request_uri$args;
    fastcgi_cache_valid 200 60m;
    fastcgi_cache_valid 404 10m;
    fastcgi_cache_use_stale updating;


    # General FastCGI handling
    fastcgi_pass unix:/var/run/php/thesecmaster.sock;
    fastcgi_pass_header Set-Cookie;
    fastcgi_pass_header Cookie;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_intercept_errors on;
    include fastcgi_params;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff|ttf|svg|otf)$ {
    expires 30d;
    add_header Pragma public;
    add_header Cache-Control “public”;
    access_log off;
    }

    # deny access to .htaccess files, if Apache’s document root
    # concurs with nginx’s one
    #
    #location ~ /\.ht {
    # deny all;
    #}
    }


    server {
    listen 80;
    server_name thesecmaster.local;
    rewrite ^/(.*)$ http://www.thesecmaster.local/$1 permanent;
    }



    Configuring nginx virtual host file

  19. Remove default nginx site


    Remove default nginx site

  20. Create a dedicated user for your site

    Ideally, in a standard shared WordPress hosting platform a dedicated user accounts are created for their websites. technically, A dedicated user is required when you are setting up shared hosting platform. If you are going to have only one site in your server. this may not require.

    Create a public_html directory and logs files for your site and set the user permission.

    # mkdir /home/arunkl/logs public_html
    # chown -R arunkl:arunkl /home/arunkl/logs public_html/


    Create logs and public_html directories

  21. Create a database and DB user in MySQL

    This is the last step in this section. Login to the MySQL as a root, create a database for your site, create a user for the database, grant database access to the user, at last, publish the changes then exit from MySQL.

    # mysql -u root -p

    mysql> CREATE DATABASE thesecmaster;
    mysql> CREATE USER ‘arunkl’@’localhost’ IDENTIFIED BY ‘1KI03cs006!!’;
    mysql> GRANT ALL PRIVILEGES ON thesecmaster.* TO [email protected];
    mysql> FLUSH PRIVILEGES;
    mysql> exit

  22. 6th Section: Install WordPress:

    This is the important section of the process. In this section we will see how to install and set up WordPress application for your hosting platform.

    Download WordPress application from wordpress.org to public_html directory.

    $ cd /home/arunkl/public_html/
    $ wget https://wordpress.org/latest.tar.gz



    Download WordPress to public_html directory

  23. Unzip the WordPress file and remove the downloaded archive file

    $ tar zxf latest.tar.gz
    $ rm latest.tar.gz


    Unzip and remove the downloaded archive file

  24. Move the unzipped content to public_html directory

    $ mv wordpress/* /home/arunkl/public_html

    remove tar.gz file and move the content to public_html directory

  25. Restart php7.4-fpm mysql nginx

    Run this command to restart the php-fpm, mysql and nginx services.

    $ systemctal restart php7.4-fpm mysql nginx

    Restart php7.4-fpm mysql nginx

  26. Check the IP address

    Note down the IP address of your server. If you are on cloud server. you should note down the public IP of your cloud server. In our demo, as we are on our local server, we have taken the system IP address using ifconfig command.

    $ sudo ifconfig

    Check the IP address

  27. Edit the host file to configure site name

    Edit the host file and map the system IP with your site name. This will enable to use website name directly on your browser instead of IP address.

    $ sudo /etc/hosts
    Edit the host file to configure host name

  28. 7th Section: Install WordPress:

    In this last section, we will see how to access WordPress and set up login.

    1. Try access your WordPress with your IP or site name.
    http://192.168.0.112/wp-admin/
    or
    http://thesecmaster.local/wp-admin

    You will be greeted with welcome screen with language selection option. Select your language. Then click next.

    2. In the next step. you should input these four things:

    A. Database Name:
    B. Database User Name:
    C. Password:
    D. Database Host:
    E. Database Table Prefix:

    Note: Database Table Prefix is something to distinguish the table of multiple sites in case of multi-site deployment. You can leave the default value in case of single site deployment.

    3. After submitting the above five things, if everything goes well, you will be asked to set up a user account to login WordPress.

    A. Site Title:
    B. Username:
    C. Password;
    D. Your Email:
    E. Search Engine Visibility:

    Note: Chick the Search Engine Visibility option if you are going to set up a public website.

    4. After creating a user account for your WordPress. It prompts you to login. WordPress will greet you with this screen after your successful login.

    Welcome to your WordPress on your own hosting platform

Alright, now you have your WordPress site on your own hosting platform. This is how you can set up your own hosting platform. This shouldn’t be your destination. This is not the end. In fact, this is the beginning of your hosting platform. We will publish the things you should need to do in the up coming posts. We are going to cover how to secure, take backup, automate, monitor, and migrate your WordPress site from one WordPress platform to another.

Please be with us and follow us for more information.

We hope this post will help you in setting up your own WordPress hosting platform either on a local server or a cloud platform. Thanks for reading this tutorial post. Please share this post and help to secure the digital world. Visit our social media page on FacebookLinkedInTwitterTelegramTumblr, & Medium and subscribe to receive updates like this.

About the author

Arun KL

To know more about me. Follow me on LinkedIn Hi All, I am Arun KL, an IT Security Professional. Founder of “thesecmaster.com”. Enthusiast, Security Blogger, Technical Writer, Editor, Author at TheSecMaster. To know more about me. Follow me on LinkedIn

Leave a Reply

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

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Learn Something New with Free Email subscription

Email is also one of the ways to be in touch with us. Our free subscription plan offers you to receive post updates straight to your inbox.