Skip to content

EdyTheCow/docker-whmcs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 

Repository files navigation

📚 About

The point of this project is a production ready solution for running WHMCS in docker under Traefik reverse proxy. There's already a couple other projects attempting something similar. However, they are either meant for development only, are outdated and/or not optimized to be ran under Traefik. This project complies with all of the official WHMCS security and packages recommendations that are found at "Further Security Steps" and "System Environment Guide".

Note

This exact installation is currently being used in live production. It is being actively maintained and tested. PRs, suggestions and issue reports are more than welcome. Consider leaving a star if you found this project helpful! ❤️

✨ Features

  • Pre-built docker images: whmcs-nginx and whmcs-php-fpm, ready to be deployed
  • As minimal as possible, includes only configuration and dependencies needed to run WHMCS
  • Based on official images: nginx and php-fpm, no weird and obscure base image
  • Follows best practices according to official WHMCS docs (references are provided below)
  • Uses WHMCS public API to download WHMCS files into docker volume automatically
  • Modular scripts to automate parts of installation and configuration (more info in docker-images branch)
  • Dokploy support, easily deploy WHMCS using provided docker compose in whmcs-dokploy

👓 Quick Overview

The _base directory currently only includes Traefik. If you're already using Traefik, you can use it as a guide and plug & play the whmcs part into your existing setup. Directory whmcs-dokploy can be ignored. If you're interested in using Dokploy, read the instructions found inside of whmcs-dokploy.

Both _base and whmcs has directories called compose (stores compose file and .env) and data (stores all of data generated by compose). This is just a structure I came up with that I use for all my projects.

To simplify installation further, pre-built docker images with dependencies and configuration are used for this setup. These images can be inspected in the docker-images branch.

🧰 Getting Started

This project uses Nginx instead of Apache as a web server, WHMCS was developed with Apache in mind so few extra steps are required to achieve production ready setup. Majority of modifications have been already implemented, rest of manual modifications are covered in the guide below.

Requirements

  • Domain
  • Valid WHMCS license

🏗️ Installation

Clone repository

git clone https://github.com/EdyTheCow/docker-whmcs.git

Set correct acme.json permissions
Navigate to _base/data/traefik/ and run:

sudo chmod 600 acme.json

Create docker network

docker network create docker-whmcs-network

Generate basic auth user and password
This will set a basic auth for WHMCS admin page. Setting this up is highly recommended. In practice this means, as an admin you'll have to login with basic auth and then login with WHMCS admin credentials. This is extremely effective against bots and endless spam of attempted and failed logins. Basic auth is usually cached by web browser, normally you'll only need to login once. This will not affect normal users, only admins.

Don't use the same credentials as WHMCS admin account in case you'll have to share it with another admin. You can set up multiple basic auth credentials, but this is only used as a simple tactic against bots, so set it as something simple. You'll still need WHMCS admin credentials to actually login into WHMCS. If you don't want this, simply remove traefik labels under comment "Basic auth for /admin page" in docker-compose.yml.

To generate basic auth credentials you can use this one-liner command. It uses the official Apache docker image from official source on Docker Hub.

docker run --rm --entrypoint htpasswd httpd:latest -Bbn YOUR_USER_HERE YOUR_PASSWORD_HERE | sed -e s/\\$/\\$\\$/g

Paste the output into whmcs/compose/.env for variable BASIC_AUTH_CREDENTIALS.

Start docker compose
Inside of _base/compose/ run the command below. This will start Traefik reverse proxy.

docker-compose up -d

Set .env variables for WHMCS
Navigate to whmcs/compose/.env and set these variables:

Variable Example Description
DOMAIN portal.domain.com Domain for WHMCS installtation
MYSQL_PASSWORD MySQL user password Generate a password for your mysql user
MYSQL_ROOT_PASSWORD MySQL root password Do not use the same password, generate a new one
TRAEFIK_SUBNET 172.18.0.0/16 It's normally 172.18.x.x you can find it by running docker inspect on the traefik container and looking for docker-whmcs-network
PUBLIC_SERVER_IP - This is used to verify the WHMCS license. Insert your server's public / external IP

If you're still unsure about your Traefik's subnet, set it as example value shown above for now. Then later on once WHMCS is running navigate to System Logs > Admin Log and you'll see IP Address. It should look something like 172.18.0.2 or similar. We're interested in the second number. So if the IP shown was 172.18.0.2 the subnet that should be set as: 172.18.0.0/16. Restart and check the logs again, this time your real IP should be displayed.

Start docker compose
Inside of whmcs/compose/ run the command below. This will start WHMCS and rest of the services.

docker compose up -d

Latest stable version of WHMCS should be automatically downloaded to whmcs/data/whmcs using WHMCS public API. Now you can navigate to your-domain.com/install and follow the installation insturctions.

Field Default value
License Key
Database Host mysql
Database Username whmcs
Database Password Found in whmcs/compose/.env
Database Name whmcs

Tip

You can automate majority of configuration by using post-install script. You can run the script by using the command below, once you reach screen asking you to delete install directory. Steps marked with [automated by script] can be ignored if you choose to run the script. You can inspect the script itself at docker-images branch.

Navigate to whmcs/compose/ and run command below. Proceed with steps without [automated by script] tag.

docker compose exec nginx sh -lc '/usr/local/bin/whmcs-post-install-config.sh'

If you choose not to run the script, complete all the steps below manually.

🔒 Security Hardening

Make sure to complete all of the steps below! Once completed, you should be ideally left with two warning and none "Needing Attention" complaints inside "System Health" tab. One warning complaining about it running Nginx instead of Apache (this is safe to ignore). The other complaining about usage of default template names. This is also safe to ignore, but linked documentation should be read if you plan on customizing templates to follow the best practices.

Setting correct URL

Official source: docs.whmcs.com
Sometimes the URL in admin panel might be using http instead of https which may cause a warning for invalid SSL certificate. In the WHMCS panel navigate to System Setting > General Settings and make sure Domain and WHMCS System URL are using https.

Setting update folder

Official source: help.whmcs.com
Setting update folder will allow you to automatically update WHMCS in the future. Similar to file storage the update folder will be located above the web root inside whmcs_storage directory. Navigate to Automation Status (gear icon) > Update WHMCS > Configure Update Settings and set the directory to /var/www/whmcs_storage/whmcs_updater_tmp_dir

Moving Files Above Web Root

Moving files above web root is a recommended practice by official WHMCS documentation. This is fairly easy to do using docker volumes. The volume whmcs_storage is used for this exact purpose, directories have been already created so all you need to do is change them in the admin panel.

File Storage

Official source: docs.whmcs.com
Navigate to System Setting > Storage Settings under Configurations add listed local storage:

Path
/var/www/whmcs_storage/downloads
/var/www/whmcs_storage/attachments
/var/www/whmcs_storage/attachments/projects

Navigate to Settings tab and replace the old paths with the newly added ones.

Templates Cache [automated by script]

Official source: docs.whmcs.com
Navigate to whmcs/data/whmcs/configuration.php and change path for $templates_compiledir to /var/www/whmcs_storage/templates_c

Crons Directory [automated by script]

Official source: docs.whmcs.com

  1. Navigate to whmcs/data/whmcs and move crons directory to whmcs/data/whmcs_storage.
  2. Navigate to whmcs/data/whmcs_storage/crons and edit config.php.new, inside the config uncomment the whmcspath option and set the new path to /var/www/html/.
  3. Rename the config.php.new to config.php.
  4. Navigate to whmcs/data/whmcs/configuration.php and add this line at the bottom of the configuration $crons_dir = '/var/www/whmcs_storage/crons/';

If done correctly, crons should be now located outside web root and system set to look for new crons location as recommended by WHMCS.

Changing Configuration Permissions [automated by script]

Official source: docs.whmcs.com
Navigate to whmcs/data/whmcs/ and run

sudo chmod 400 configuration.php

eMail Import Cron (optional)

Official source: docs.whmcs.com
Navigate to whmcs/compose and edit docker-compose.yml, inside the file uncomment the two commands under the ofelia-labels.
Rebuild stack with docker compose down && docker compose up -d.

🐛 Known issues

📝 Planned

  • Create and test an alternative installation with Apache web server
  • (Done) Create a ready to deploy Dokploy docker compose example

📜 Credits

About

Dockrized WHMCS running under Traefik proxy! Fully functional and ready for production use.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors 5