ErrandLink Complete Installation Guide

Choose your deployment method and follow step-by-step instructions for successful installation

Production Recommended: Docker Deployment
Docker (Recommended)
Ubuntu/Nginx VPS
cPanel/Shared Hosting
Apache Server

Quick Start with Docker on Ubuntu/Nginx

The fastest way to deploy ErrandLink is using Docker Compose.

Recommended
1

Extract Files

tar -xzf errandlink-v1.0.0.tar.gz
cd errandlink
2

Configure Environment

cp .env.example .env (do it for root, backend and frontend .env)
nano .env  # Edit with your settings
3

Create Database

sudo -u postgres psql

# In PostgreSQL shell:
CREATE DATABASE errandlink;
CREATE USER errandlink_user WITH ENCRYPTED PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE errandlink TO errandlink_user;
ALTER DATABASE errandlink OWNER TO errandlink_user;
\q
4

Build and Start

docker compose up -d --build
5

Complete Installation

Visit http://your-server-ip:5000/install in your browser to complete setup.

Success! Your Docker installation is now ready for setup.

Docker Services Included

backend

Laravel 11 API (PHP 8.2-FPM)

frontend

React + Vite (Nginx)

realtime

Node.js + Socket.IO

postgres

PostgreSQL 15

redis

Redis 7

Essential Docker Commands

# View logs
docker compose logs -f

# Restart services
docker compose restart

# Stop all services
docker compose down

# Rebuild after changes
docker compose up -d --build
Note: I personally tested the Docker quick start and it works. I think that method is more recommended for production.

Ubuntu/Nginx VPS Installation

Recommended for production deployments.

1

Update System

sudo apt update && sudo apt upgrade -y
2

Install Required Packages

# Add PHP 8.2 repository
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

# Install all dependencies
sudo apt install -y \
  nginx \
  php8.2-fpm \
  php8.2-pgsql \
  php8.2-mysql \
  php8.2-mbstring \
  php8.2-xml \
  php8.2-curl \
  php8.2-zip \
  php8.2-gd \
  php8.2-redis \
  php8.2-bcmath \
  php8.2-intl \
  postgresql \
  postgresql-contrib \
  redis-server \
  composer \
  nodejs \
  npm \
  unzip \
  git
3

Create Database

sudo -u postgres psql

# In PostgreSQL shell:
CREATE DATABASE errandlink;
CREATE USER errandlink_user WITH ENCRYPTED PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE errandlink TO errandlink_user;
ALTER DATABASE errandlink OWNER TO errandlink_user;
\q
4

Upload and Extract Files

# Create web directory
sudo mkdir -p /var/www/errandlink
cd /var/www

# Upload errandlink-v1.0.0.tar.gz to server, then extract
sudo tar -xzf errandlink-v1.0.0.tar.gz -C errandlink --strip-components=1

# Set ownership
sudo chown -R www-data:www-data /var/www/errandlink
5

Configure Backend

cd /var/www/errandlink/backend

# Install PHP dependencies
sudo -u www-data composer install --optimize-autoloader --no-dev

# Configure environment
sudo -u www-data cp .env.example .env
sudo nano .env  # Edit with your database credentials

# Generate application key
sudo -u www-data php artisan key:generate

# Run database migrations
sudo -u www-data php artisan migrate --force

# Set permissions
sudo chmod -R 755 storage bootstrap/cache
sudo chmod 644 .env
6

Build Frontend

Package comes with ready-built dist/ folder

7

Configure Nginx

Create /etc/nginx/sites-available/errandlink:

# Frontend Server
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    root /var/www/errandlink/frontend/dist;
    index index.html;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # Proxy API requests to backend
    location /api {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Proxy WebSocket for real-time
    location /socket.io {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

# Backend API Server
server {
    listen 8000;
    server_name localhost;
    root /var/www/errandlink/backend/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/errandlink /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
8

Setup Realtime Server

cd /var/www/errandlink/realtime
npm install --production

# Install PM2 globally
sudo npm install -g pm2

# Start realtime server
pm2 start server.js --name errandlink-realtime

# Save PM2 configuration
pm2 save
pm2 startup
9

Install SSL Certificate

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
10

Configure Firewall

sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable
11

Setup Laravel Queue Worker (Optional)

pm2 start "php /var/www/errandlink/backend/artisan queue:work" --name errandlink-queue
pm2 save
12

Setup Cron Job

sudo crontab -e

# Add this line:
* * * * * cd /var/www/errandlink/backend && php artisan schedule:run >> /dev/null 2>&1
13

Complete Installation

Visit https://yourdomain.com/install to complete setup and create your admin account.

Success! Your Ubuntu/Nginx installation is now complete and ready for production use.

cPanel/Shared Hosting Installation

For shared hosting environments with cPanel.

Limitations: Real-time features may not work on shared hosting. Consider Docker or VPS for full functionality.

Prerequisites

Component Requirement Status
PHP 8.2 or higher Check cPanel
Database PostgreSQL/MySQL Available in cPanel
SSH Access Recommended Optional but helpful
Node.js For frontend build Required locally
1

Build Frontend Locally

Info: Package comes with ready-built dist production folder
2

Upload Files to Server

Option A: cPanel File Manager

  • Upload and extract errandlink-v1.0.0.tar.gz
  • Move frontend/dist/* to public_html/
  • Move backend/ outside public_html
  • Example: /home/username/errandlink_backend/

Option B: Via SSH

  • Extract archive in home directory
  • Move frontend to public_html
  • Move backend to secure location
cd ~
tar -xzf errandlink-v1.0.0.tar.gz
mv errandlink/frontend/dist/* public_html/
mv errandlink/backend ~/errandlink_backend
3

Create Database

In cPanel interface:

PostgreSQL

  • Go to PostgreSQL Databases
  • Create database: yourusername_errandlink
  • Create user with strong password
  • Grant ALL PRIVILEGES to user

MySQL

  • Go to MySQL Databases
  • Create database: yourusername_errandlink
  • Create user with strong password
  • Add user to database
4

Configure Backend

Via SSH access your server:

cd ~/errandlink_backend
cp .env.example .env
nano .env

Update these essential settings:

APP_NAME=ErrandLink
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

DB_CONNECTION=pgsql   # or mysql
DB_HOST=localhost
DB_PORT=5432          # or 3306 for MySQL
DB_DATABASE=yourusername_errandlink
DB_USERNAME=yourusername_dbuser
DB_PASSWORD=your_database_password

FRONTEND_URL=https://yourdomain.com
Important: Generate application key and run migrations
php artisan key:generate
php artisan migrate --force
5

Set File Permissions

chmod -R 755 ~/errandlink_backend/storage
chmod -R 755 ~/errandlink_backend/bootstrap/cache
chmod 644 ~/errandlink_backend/.env
Security Note: Proper permissions prevent unauthorized access to sensitive files
6

Configure API Access

Option A: API Subdomain (Recommended)

  • In cPanel, go to Subdomains
  • Create: api.yourdomain.com
  • Set Document Root to: /home/username/errandlink_backend/public
  • Update frontend VITE_API_URL

Option B: .htaccess Proxy

Add to public_html/.htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    
    # Proxy API requests to backend
    RewriteCond %{REQUEST_URI} ^/api/
    RewriteRule ^api/(.*)$ /home/username/errandlink_backend/public/index.php/$1 [L,QSA]
</IfModule>
7

Setup Cron Job

In cPanel, go to Cron Jobs and add:

* * * * * cd /home/username/errandlink_backend && php artisan schedule:run >> /dev/null 2>&1
Note: This runs Laravel scheduled tasks every minute
8

Real-time Server (Optional)

Shared Hosting Limitation: WebSocket support is often limited on shared hosting

Separate VPS

  • Deploy realtime server on separate VPS
  • Update frontend WebSocket URL
  • Best for production use

Third-party Service

  • Use services like Pusher, Socket.io Cloud
  • Update configuration in backend
  • Easier setup, additional cost

Polling Fallback

  • App automatically uses polling
  • Slightly slower updates
  • No additional setup needed
9

Complete Installation

Final Step: Visit https://yourdomain.com/install to complete the web installation wizard and create your admin account

Apache Server Installation

For Apache servers (alternative to Nginx).

Note: Follow Ubuntu/Nginx steps first, then adapt for Apache configuration
1

Backend Virtual Host

Create /etc/apache2/sites-available/errandlink.conf:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/errandlink/frontend/dist

    <Directory /var/www/errandlink/frontend/dist>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        
        # SPA fallback
        FallbackResource /index.html
    </Directory>

    # Proxy API to backend
    ProxyPreserveHost On
    ProxyPass /api http://127.0.0.1:8000/api
    ProxyPassReverse /api http://127.0.0.1:8000/api

    # Proxy WebSocket
    ProxyPass /socket.io ws://127.0.0.1:3001/socket.io
    ProxyPassReverse /socket.io ws://127.0.0.1:3001/socket.io

    ErrorLog ${APACHE_LOG_DIR}/errandlink-error.log
    CustomLog ${APACHE_LOG_DIR}/errandlink-access.log combined
</VirtualHost>

<VirtualHost *:8000>
    ServerName localhost
    DocumentRoot /var/www/errandlink/backend/public

    <Directory /var/www/errandlink/backend/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>
2

Enable Required Modules and Site

sudo a2enmod rewrite proxy proxy_http proxy_wstunnel
sudo a2ensite errandlink.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2

Post-Installation Setup

Complete these steps after successful installation

1

Access Installation Wizard

Visit https://yourdomain.com/install and follow the wizard:

Database Connection

  • Verify database connectivity
  • Test connection settings
  • Confirm user permissions

Run Migrations

  • Create database tables
  • Seed initial data
  • Set up indexes

Create Admin Account

  • Set administrator credentials
  • Configure email
  • Set security preferences

Configure Settings

  • Set application name
  • Configure payment gateways
  • Setup branding
2

Configure Payment Gateways

In Admin Dashboard > Settings > Payment:

Stripe Setup

  • Create a Stripe account at stripe.com
  • Get your API keys from Stripe Dashboard
  • Enter Publishable Key and Secret Key
  • Configure webhook endpoint: https://yourdomain.com/api/v1/stripe/webhook

Paystack Setup

  • Create a Paystack account at paystack.com
  • Get your API keys from Paystack Dashboard
  • Enter Public Key and Secret Key
  • Configure webhook endpoint: https://yourdomain.com/api/v1/paystack/webhook
3

Configure Google Services (Optional)

Google Maps

  • Go to Google Cloud Console
  • Enable Maps JavaScript API and Places API
  • Create an API key with appropriate restrictions
  • Add to Admin Settings

Google OAuth

  • Go to Google Cloud Console > APIs & Services > Credentials
  • Create OAuth 2.0 Client ID
  • Add authorized redirect URI: https://yourdomain.com/auth/google/callback
  • Add Client ID and Secret to Admin Settings

reCAPTCHA

  • Go to Google reCAPTCHA Admin Console
  • Register your domain for reCAPTCHA v3
  • Add Site Key and Secret Key to Admin Settings

Troubleshooting

Common issues and solutions for ErrandLink installation

500 Internal Server Error

# Check Laravel logs
tail -f /var/www/errandlink/backend/storage/logs/laravel.log

# Fix permissions
sudo chmod -R 755 storage bootstrap/cache
sudo chown -R www-data:www-data storage bootstrap/cache

# Clear cache
php artisan cache:clear
php artisan config:clear
php artisan view:clear

Database Connection Failed

# Test PostgreSQL connection
psql -h localhost -U errandlink_user errandlink

# Check PostgreSQL is running
sudo systemctl status postgresql

# Restart PostgreSQL
sudo systemctl restart postgresql

Frontend Not Loading

# Check Nginx configuration
sudo nginx -t

# Restart Nginx
sudo systemctl reload nginx

# Verify frontend build exists
ls -la /var/www/errandlink/frontend/dist/

Real-time Features Not Working

# Check PM2 status
pm2 status

# View realtime logs
pm2 logs errandlink-realtime

# Restart realtime server
pm2 restart errandlink-realtime

CORS Errors

1. Verify CORS_ALLOWED_ORIGINS in backend .env
2. Check that frontend URL matches exactly (including https://)
3. Clear browser cache and try again

Payment Webhooks Failing

1. Verify webhook URLs in Stripe/Paystack dashboard
2. Check that webhooks can reach your server (no firewall blocking)
3. Verify webhook secrets match in .env
4. Check Laravel logs for webhook errors
Additional Support
  • Check application logs in backend/storage/logs/
  • Review browser console for frontend errors
  • Verify all environment variables are set correctly
  • Contact support at support@yourdomain.com
ErrandLink v1.0.0
Copyright (c) 2025-2026. All rights reserved.