FeaturedHow To's

From Permission Denied to Published: A Deep-Dive into a Real-World Ghost Installation

How to Install Ghost on a VPS with CloudPanel and Fix All Issues

This is not a short, “copy-paste these five commands” tutorial. This is a long-form case study, a detailed story of a real-world Ghost installation that went wrong in almost every way imaginable. It is written for the beginner who is new to managing their own VPS, who has perhaps followed a simple guide and immediately hit a wall.

If you’ve ever seen an error like Permission denied, command not found, or Could not communicate with Ghost and felt completely lost, this guide is for you. We will walk through every error we encountered, explain the detective work used to diagnose it, and provide the precise, battle-tested solution. We will treat every command not as a magic spell, but as a tool we can understand. By the end of this article, you will not only have a working Ghost installation, but you will also understand the fundamental concepts of Linux users, permissions, and server management that are essential for your journey.

So, grab a coffee. Let’s begin.

Part 1: The Stage and the Characters

Before our story begins, let’s meet the key players and understand the environment we are working in.


DOWNLOAD FREE FILES NOW

The Stage (Our Tools)

  • VPS (Virtual Private Server): Think of this as your own private, powerful computer that lives on the internet. You rent it from a hosting company, and you have full control over it. It’s a blank canvas for you to build upon.
  • CloudPanel: This is a free, modern control panel with a user-friendly website that you install on your VPS. It’s like the helpful front desk of a hotel. It helps you with common tasks like creating websites, managing databases, and setting up security certificates, so you don’t have to do everything from the complex command line.
  • SSH (Secure Shell): This is a secure tunnel that lets you connect from your home computer directly to your VPS’s command line. If CloudPanel is the front desk, SSH is the key to the server’s “engine room.”
  • The Command Line (or Terminal): This is the text-based interface where you can talk directly to your server. It’s incredibly powerful and is where we will do most of our work.
  • Ghost: This is the software we want to install. It’s a beautiful, professional publishing platform for blogs and newsletters.

The Cast of Characters (The Linux Users)

On a Linux server, everything is done by “users.” Different users have different levels of power. Understanding their roles is the key to solving most server problems. We’ll use an apartment building analogy.

  • root (The Server God / CEO): This user is the ultimate owner of the entire server. It has 100% power and can do absolutely anything. It is the original, built-in super-administrator. Using root for everything is powerful but dangerous, like using a sledgehammer for every task.
  • The Administrator (cloudpanel or our new telvice user): This is like the Building Manager. This user isn’t the owner, but the root user has given them a set of master keys (sudo powers). They can perform administrative tasks, install new software, and fix problems. This is the user you should use for server management.
  • The Site User (mdundomp3): This is like a Tenant living in one apartment. They have the key to their own apartment’s files and can decorate it as they wish. However, they cannot change the building’s main locks, fix the plumbing in the walls, or enter other people’s apartments. CloudPanel creates a new “Tenant” like this for every website you add.
  • The Service User (ghost): This is like a dedicated Employee hired to do one specific job—in this case, run the Ghost blog software. This user has very limited power for security. It can’t do anything except its one job. It is created automatically by the Ghost installer.

Part 2: The Perfect World – How the Installation Should Have Worked

The journey we are about to embark on is complex because our server had hidden problems. To appreciate the journey, let’s first look at the map of the “perfect world” installation. This is the baseline.

  1. Create the Site in CloudPanel: The Building Manager (telvice) asks the Front Desk (CloudPanel) to prepare a new apartment for a new website. CloudPanel creates the empty space and sets up the address so people can find it (this is the Nginx reverse proxy).
  2. Log in and Prepare: The Building Manager (telvice) uses their secure tunnel (SSH) to enter the engine room (command line). They go to the new apartment and unlock the door for renovations (sudo chown).
  3. Install the Tools: The Building Manager (telvice) installs the necessary tools (ghost-cli) for the job into the building’s main workshop (/usr/bin).
  4. Install the Application: The Building Manager (telvice) runs the installer (ghost install) inside the apartment. The installer asks a few questions (What’s the address? Where are the database blueprints?) and then builds everything. It also hires the ghost employee and sets up its life support system (systemd) so it will always be running.

This process is clean and logical. Our process was not. Let’s begin the investigation.

Part 3: The Investigation – A Cascade of Errors

Our story begins after Step 1. The site was created in CloudPanel, which also created our “Tenant,” the mdundomp3 user. The initial mistake was to try and perform the installation as this user.

Chapter 1: The Case of the Wrong Keys (Permission Denied)

We logged into the server as the site user mdundomp3 and tried to install Ghost. This led to our first set of clues.

  • The Clue: The Ghost installer tried to create the ghost employee, which is an administrative task. It prompted for a [Sudo Password]. When we entered the password for mdundomp3, the server responded:
    Sorry, user mdundomp3 is not allowed to execute '/usr/sbin/useradd' as root.
  • The Deduction: This error is the server telling us, “The tenant is trying to use a master key, but they don’t have one.” The command sudo is the master key. It stands for “Super User Do” and it allows a regular user to temporarily borrow the power of the root user for a single command. Only users in a special “sudo group” are allowed to do this. Our mdundomp3 user was not in this group.
  • The Solution: We realized we needed to be the Building Manager, not the Tenant.
    1. Finding the Manager: The first step was to find the real administrator account. The user did not know the name. We determined that the ultimate administrator, root, is always present. The login details for root are provided by the hosting company in the initial “Welcome Email” or can be reset from the hosting company’s website via the “Reset Root Password” feature. This is the server’s emergency master key.
    2. Becoming the Manager: The user found their root password. For security, it’s best not to work as root all the time. So, while logged in as root, we created a new, dedicated administrator user.
      # Logged in as root. This command creates a new user.
      adduser telvice
      # This command adds our new user to the 'sudo' group, giving them the master key.
      usermod -aG sudo telvice

    From this point forward, we performed all administrative work as the new, empowered telvice user.

Chapter 2: The Mystery of the Vanishing Command (command not found)

Now logged in as the proper administrator telvice, we tried to install the Ghost Command Line Interface (CLI).

  • The Clue: We ran the installation command, which seemed to work.
    sudo npm install -g ghost-cli@latest
    # Output looked successful: "changed 634 packages"

    But when we tried to use the command, the server said:
    ghost: command not found

  • The Deduction: This error means the terminal can’t find the program we’re trying to run. To understand why, imagine your terminal has a treasure map called the $PATH. When you type a command like ghost, the terminal only looks for it in the specific folders listed on that map. If the program was installed in a folder that’s not on the map, the terminal will never find it.
  • The Investigation:
    1. We first checked the map with echo $PATH. It seemed to list the standard locations.
    2. We tried to manually add the correct folder to the map by editing the shell’s configuration files (~/.profile and later ~/.bashrc). These files are like a set of instructions the terminal reads every time it starts.
    3. This didn’t work. We then suspected the terminal had a “short-term memory” (a hash cache) and was remembering that the command didn’t exist from before. We cleared this memory with hash -r.
    4. This also didn’t work. This is when the case took a shocking turn. We tried to manually create a “shortcut” (a symbolic link) to where the file should have been. This revealed the final truth: the ghost program file did not exist anywhere on the server.
  • The Shocking Twist: The npm install command was lying. It reported success, but it was not actually installing the files. This pointed to a deep, fundamental problem with the server’s Node.js and NPM installation itself.
  • The Solution: Scorched Earth: When a core tool like NPM is fundamentally broken, trying to fix it is often a waste of time. The only guaranteed solution is to remove it completely and start fresh.
    # Logged in as telvice
    # 1. Purge (completely remove) the broken Node.js
    sudo apt-get purge -y nodejs
    sudo rm -rf /etc/apt/sources.list.d/nodesource.list
    
    # 2. Clean up any leftovers
    sudo apt-get autoremove -y && sudo apt-get clean
    
    # 3. Reinstall Node.js and NPM from scratch
    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
    sudo apt-get install -y nodejs

    After this complete reinstallation of the underlying engine, we were finally able to successfully install the Ghost-CLI tool globally.

Chapter 3: The Final, Bizarre Bug (systemd and the Temporary Folder)

We had a working administrator. We had a working Node.js environment. We ran the final, clean installation. It went through all the steps and then failed at the very last moment: ✖ Starting Ghost.

  • The Clue: We used the most powerful diagnostic tool for services, journalctl, to read the system’s logbook.
    sudo journalctl -u ghost_mdundomp3-com -n 50

    The log contained a very strange error:
    Error: Cannot find module '/home/telvice/.npm/_npx/...'

  • The Deduction: This was the final, most subtle problem. The path in the error message, .../.npm/_npx/..., pointed to a temporary cache folder used by the npx tool. Earlier in our journey, we had used npx as a workaround. The Ghost installer had seen us use this temporary tool and had written a permanent startup file (systemd service) that mistakenly pointed to this temporary location. When the server tried to start the blog using the permanent startup file, the temporary npx folder was long gone, and the service crashed.
  • The Solution: Manual Surgery on the Startup File: The installer’s automation had failed us. We had to perform manual surgery on the “life support” file for our blog.
    1. Open the file: We used a special command to safely edit the service file.
      sudo systemctl edit --full ghost_mdundomp3-com.service
    2. Find the broken instruction: We located the line that started with ExecStart=. It pointed to the broken, temporary npx path.
    3. Replace it with the correct instruction: We replaced the entire line with the simple, correct, and permanent command.
      ExecStart=/usr/bin/ghost run
    4. Reload and Start: We told the system to re-read its instructions and start the service.
      sudo systemctl daemon-reload
      ghost start

And with that, the site was finally, truly working.

Part 4: The Ultimate A-to-Z Workflow

After this long and difficult investigation, we have a definitive, battle-hardened workflow that accounts for all the quirks of this server environment. This is the guide to follow.

Step 1: Prepare in CloudPanel

  1. Log into your CloudPanel web UI.
  2. Go to Sites -> Add Site -> Create a Node.js Site.
  3. Use these settings:
    • Domain Name: your-domain.com
    • Site User: Create a unique name, for example, yourdomain_user.
    • Node.js Version: 22.
    • App Port: 2368.
  4. Go to Databases -> Add Database. Create a new database and user. Write down the Database Name, User Name, and Password. You will need them soon.

Step 2: Prepare Your Server Administrator

  1. Log into your server via SSH as the root user using the credentials from your hosting company.
  2. Create a new, dedicated administrator user. This is the user you will use for all server management from now on.
    # This creates the user and asks you to set a password.
    adduser your_admin
    # This gives the user 'sudo' (administrator) powers.
    usermod -aG sudo your_admin
  3. Log out of root (exit) and log back in as your new administrator (ssh your_admin@YOUR_SERVER_IP).

Step 3: Clean Install of Node.js and Ghost-CLI

  1. Completely remove any old Node.js versions to prevent conflicts.
    sudo apt-get purge -y nodejs
    sudo rm -rf /etc/apt/sources.list.d/nodesource.list
    sudo apt-get autoremove -y && sudo apt-get clean
  2. Install a fresh copy of Node.js v22.
    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
    sudo apt-get install -y nodejs
  3. Install the Ghost-CLI tool globally.
    sudo npm install -g ghost-cli@latest
  4. Verify the installation.
    which ghost

    This command MUST return a path like /usr/bin/ghost. If it does not, something is still fundamentally wrong.

Step 4: Prepare the Installation Directory

  1. Allow your new administrator (your_admin) to access the site user’s (yourdomain_user) home directory.
    sudo chmod 755 /home/yourdomain_user
  2. Navigate to the htdocs directory and create a clean folder for your Ghost installation. This is crucial because CloudPanel creates a your-domain.com directory that we will not use, to avoid conflicts.
    cd /home/yourdomain_user/htdocs/
    sudo mkdir ghost-files
    sudo chown -R your_admin:your_admin ghost-files
    cd ghost-files

Step 5: Run the Ghost Installer

  1. Inside the clean ghost-files directory, run the installer.
    ghost install
  2. Answer the prompts carefully:
    • Blog URL: https://your-domain.com
    • MySQL details: Use the credentials you saved from Step 1.
    • Set up Nginx? No.
    • Set up SSL? No.
    • Set up Systemd? Yes.

Step 6: Finalize CloudPanel and Verify

  1. The installer will tell you Ghost is running on port 2368. Now you need to tell CloudPanel to point to the correct files.
  2. In the CloudPanel UI, go to your site’s Vhost settings.
  3. You must change the root path inside the location / block to point to the system/nginx-root folder that Ghost created. It should look like this:
    location / {
        # Replace the user and folder names with your own
        root /home/yourdomain_user/htdocs/ghost-files/system/nginx-root;
        
        # The rest of the proxy settings remain the same
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:2368;
    }
  4. Save the Vhost. Your site should now be live.
  5. Finally, check the status from your terminal to be sure the systemd service is running correctly.
    # Logged in as 'your_admin', inside the 'ghost-files' directory
    ghost ls

    The Process Manager should say systemd and the status should be running.

Conclusion: Lessons from the Trenches

This journey was far from simple, but it was incredibly educational. It taught us that on a self-managed server, nothing can be taken for granted. The key lessons were:

  • Know Your Users: Understanding the difference between a privileged administrator and a limited site user is the most important concept in server management.
  • Trust, but Verify: Software installers can fail silently. Commands like which and ls are your best friends to verify that a file or program actually exists where it’s supposed to.
  • Logs are Your Best Friend: When a service fails to start, the answer is always in the logs. Learning to use journalctl is a superpower.
  • Don’t Be Afraid to Start Over: When a core tool like NPM is fundamentally broken, the fastest way to a solution is often a complete purge and reinstall.

The final result of this long process is a Ghost installation that is not only working, but is stable, secure, and set up according to best practices. It was a difficult climb, but the view from the top is worth it.


Discover more from Cloudorian - Tech News, Reviews, Deals, and How-To's

Subscribe to get the latest posts sent to your email.

Montel Anthony

Montel Anthony is a passionate/enthusiastic Blogger who loves creating helpful guide contents for its users. I'm also a web developer, Graphics designer and Writer.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to top button

Adblock Detected

Please Disable Ad blocking and You can access the site. Thank you.