Install LiteCart on Raspberry Pi
Raspberry Pi is a low-cost micro computer. In this guide we will let a Raspberry Pi computer host your LiteCart installation. Suitable for small businesses in development countries who wants an online presence but without any costs of hosting.
For this guide we used a fresh installation of Raspberry Pi OS Lite (Bookworm).
Sign in to your Raspberry Pi device
You can sign in to your device by hooking up a keyboard and display, or by signing in remotely via SSH over a network. To sign in remotely over a network you might need to first enabling the service.
Enable remote access using SSH
# Enable the service for automatic starting next reboot
sudo systemctl enable ssh
# Start the service now
sudo systemctl start ssh
# Show the device IP address and make notes
ip a
Sign in remotely over a network using SSH on Windows
-
Open Windows Terminal from your Start menu.
-
Type the following command in Windows Terminal to sign in to your Raspberry Pi:
ssh username@hostname-or-ip-address
Install the necessary software to run LiteCart
Once signed in, pass the following commands.
# Become root (or you will need to pass `sudo` before every command)
# (If this is not enabled. Set a root password first by the command: sudo passwd root)
su
# Make sure all sources and software on the device is up to date
apt update && apt -y full-upgrade && apt -y autoremove
# Install necessary software
apt -y install curl nano unzip apache2 libapache2-mod-php mariadb-server php php-common php-cli php-fpm php-apcu php-curl php-dom php-gd php-imagick php-mysql php-simplexml php-mbstring php-intl php-zip php-xml certbot python3-certbot-apache
# Install additional locales if missing (Example: language-pack-{language_code})
apt -y install language-pack-es language-pack-fr language-pack-de
# Enable some required Apache modules
a2enmod proxy_fcgi rewrite headers setenvif ssl
# Enable the PHP-FPM configuration for PHP 8.2
a2enconf php8.2-fpm
# Secure your MySQL/MariaDB server
# Alternatively run a handsfree command for securing MariaDB/MySQL:
# mysql -uroot <<END
# ALTER USER 'root'@'localhost' IDENTIFIED BY '{desired_root_password_here}';
# GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
# DROP USER IF EXISTS ''@'localhost';
# DROP DATABASE IF EXISTS test;
# FLUSH PRIVILEGES;
# END
mysql_secure_installation
# Let's make som changes to the PHP configuration
sed -ri 's/;?memory_limit\s*=\s*[^\s]*/memory_limit = 256M/' /etc/php/8.2/apache2/php.ini
sed -ri 's/;?upload_max_filesize\s*=\s*[^\s]*/upload_max_filesize = 64M/' /etc/php/8.2/apache2/php.ini
sed -ri 's/;?date\.timezone\s*=\s*[^\s]*/date.timezone = Europe\/London/g' /etc/php/8.2/apache2/php.ini
Install LiteCart
# Create a directory for LiteCart
mkdir /var/www/litecart
# Create an Apache virtualhost configuration directive for mydomain.tld pointing to the folder of LiteCart
cat <<EOL > /etc/apache2/sites-enabled/mydomain.tld.conf
<VirtualHost *:80>
ServerName mydomain.tld
ServerAlias www.mydomain.tld
ServerAdmin webmaster@mydomain.tld
DocumentRoot /var/www/litecart
ErrorLog \${APACHE_LOG_DIR}/error.log
CustomLog \${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/litecart>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
EOL
# Restart Apache to apply all changes
systemctl restart apache2
# Create the LiteCart database in MariaDB/MySQL
read -p "New database name: " newdb_name
read -p "New database user: " newdb_user
read -sp "Password for database user '$newdb_user': " newdb_password
mysql -u root -p <<EOL
CREATE DATABASE $newdb_name;
CREATE USER '$newdb_user'@'localhost' IDENTIFIED BY '$newdb_password';
GRANT ALL PRIVILEGES ON $newdb_name.* TO '$newdb_user'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOL
# Go to the document root for your site
cd /var/www/litecart
# Install LiteCart
bash -c "$(curl https://raw.githubusercontent.com/litecart/installer/master/cli/install.sh)"
# When the LiteCart web installation is completed, do some cleanup:
rm -Rf install/
# Change owner of the files and folders to Apache web user
chown -R www-data:www-data ./
# Install an SSL Certificate using Let's Encrypt
certbot --apache -w /var/www/litecart -d mydomain.tld
# Install a virtualhost for HTTPS connections
cat <<EOL > /etc/apache2/sites-enabled/mydomain.tld-ssl.conf
<VirtualHost *:443>
ServerName mydomain.tld
ServerAlias www.mydomain.tld
ServerAdmin webmaster@mydomain.tld
DocumentRoot /var/www/litecart
ErrorLog \${APACHE_LOG_DIR}/error.log
CustomLog \${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/litecart>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mydomain.tld/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.tld/privkey.pem
</VirtualHost>
EOL
# Restart Apache web server for SSL
systemctl restart apache2
Automatically update a Cloudflare DNS Record with the machine's Public IP Address
If you are using Cloudflare for your domain's DNS records. Install a script to keep the A-record up to date. Having a dynamic IP address will impact your online availability. But if a static IP-address is not an option this will at least make your website available most of the time.
cat <<EOL > /etc/network/if-up.d/cloudflare-updater.conf
#!/bin/bash
# My WAN adapter
WAN_ADAPTER = "eth0" # Replace with your adapter name found in `ip link show`
# Cloudflare API credentials
ZONE_ID="your_zone_id" # Replace with your Cloudflare zone ID
RECORD_ID="your_record_id" # Replace with the DNS record ID you want to update
API_TOKEN="your_api_token" # Replace with your Cloudflare API token
DNS_NAME="myvirtualhost.tld" # The DNS record you want to update
# Check if interface eth0 (or your interface) is up
if [ "\$IFACE" == \$WAN_ADAPTER ]; then
# Get current public IP
CURRENT_IP=\$(curl -4 -s ifconfig.me)
# Get the existing IP from Cloudflare DNS record
EXISTING_IP=\$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/\$ZONE_ID/dns_records/\$RECORD_ID" \
-H "Authorization: Bearer \$API_TOKEN" \
-H "Content-Type: application/json" | jq -r .result.content)
# Compare IPs
if [ "\$CURRENT_IP" != "\$EXISTING_IP" ]; then
echo "IP has changed. Updating Cloudflare DNS record..."
# Update the DNS record on Cloudflare
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/\$ZONE_ID/dns_records/\$RECORD_ID" \
-H "Authorization: Bearer \$API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"'"\$DNS_NAME"'","content":"'"\$CURRENT_IP"'","ttl":300,"proxied":false}'
echo "DNS record updated to \$CURRENT_IP"
else
echo "IP address is unchanged."
fi
fi
END
# Make script executable
chmod +x /etc/network/if-up.d/cloudflare-updater.conf
Troubleshooting
Why doesn't my website resolve?
First make sure the DNS record for your domain is pointing to your machine's WAN IP (curl -4 ifconfig.me
). This allows the world to find it when accessing the hostname. If you are behind a router you need to make sure that incoming traffic to your router (TCP ports 80 and 443) gets forwarded internally to your Raspberry Pi device. If you have a firewall installed in your Pi computer you will need to allow incoming traffic (ufw allow http https
).
Why doesn't my certificate get generated and installed?
A common issue is that the domain does not resolve or isn't pointing to your machine.
I just updated my DNS records, but I am still having troubles.
Let the DNS changes propagate around the world by waiting a couple of hours.
How do I find my WAN IP?
Your WAN IP is stated in your router, or by navigating to https://whatsmyip.com/, or by running the command curl -4 ifconfig.me
from the Pi computer.