Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JuanSCaicedo/Api-Ecommerce/llms.txt

Use this file to discover all available pages before exploring further.

API Ecommerce ships a GitHub Actions workflow at .github/workflows/main.yml that fully automates deployment to the production server on every push to the main branch. There is a single job — deploy — that opens an SSH connection to the OCI-hosted Ubuntu VPS and executes the deployment script remotely. Cloudflare sits in front of the server as a reverse proxy and CDN, terminating TLS and routing traffic to the application.

Pipeline overview

Trigger: Any git push to the main branch. Runner: ubuntu-latest (GitHub-hosted). Action used: appleboy/ssh-action@v1.0.3 — connects to the server over SSH and runs an inline shell script. The full deployment workflow:
# .github/workflows/main.yml
name: Deploy Laravel API

on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Deploy to Server
    runs-on: ubuntu-latest

    steps:
      - name: Ejecutar deploy por SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
              set -e

              PROJECT_PATH="/home/api-ecommerce.juandevops.com/public_html"

              echo "▶ Entrando al proyecto"
              cd $PROJECT_PATH

              echo "▶ Asegurando known_hosts"
              mkdir -p ~/.ssh
              ssh-keyscan github.com >> ~/.ssh/known_hosts

              echo "▶ Registrando safe.directory"
              git config --global --add safe.directory $PROJECT_PATH

              echo "▶ Tomando ownership para el deploy"
              sudo chown -R $USER:www-data $PROJECT_PATH
              sudo chmod -R 775 $PROJECT_PATH

              echo "▶ Usando repo por SSH"
              git remote set-url origin git@github.com:JuanSCaicedo/Api-Ecommerce.git

              echo "▶ Pull limpio del código"
              git reset --hard
              git pull origin main

              echo "▶ Actualizar dependencias"
              composer install \
                --no-dev \
                --optimize-autoloader \
                --no-interaction

              echo "▶ Asegurando permisos de Laravel"
              sudo chmod -R 777 /home/api-ecommerce.juandevops.com/public_html/storage/logs/laravel.log
              sudo chmod -R 777 /home/api-ecommerce.juandevops.com/public_html/storage/framework/cache/data
              sudo chmod -R 777 /home/api-ecommerce.juandevops.com/public_html/storage/framework/views
              sudo chmod -R 777 /home/api-ecommerce.juandevops.com/public_html/storage/framework/sessions

              echo "▶ Limpiando caché al final del deploy"
              php artisan optimize:clear
              php artisan cache:clear
              php artisan config:clear
              php artisan route:clear
              php artisan view:clear

              echo "✅ Deploy finalizado correctamente"

What the script does

StepDescription
set -eAbort immediately if any command exits with a non-zero status, preventing a partial deploy from leaving the app in a broken state
ssh-keyscan github.comAdds GitHub’s host key to known_hosts so the subsequent git pull over SSH does not hang waiting for host confirmation
git config safe.directoryRequired when the repo owner differs from the SSH user — suppresses Git’s “dubious ownership” error
chown / chmod 775Re-establishes correct ownership ($USER:www-data) and group-write permissions across the entire project before touching files
git remote set-urlSwitches the remote to the SSH URL so git pull authenticates via the deploy key rather than HTTPS tokens
git reset --hard && git pull origin mainDiscards any local modifications (e.g. accidental server-side edits) and fast-forwards to the latest commit on main
composer install --no-dev --optimize-autoloaderInstalls only production dependencies and generates an optimised class map
chmod -R 777 on framework pathsGrants the web server (www-data) write access to the log file and Laravel’s framework cache, view, and session directories
php artisan optimize:clearRuns all *:clear sub-commands in one pass, flushing the config, route, view, and event caches

Deployment target

ComponentDetails
HostOracle Cloud Infrastructure (OCI) — Ubuntu VPS
Project root/home/api-ecommerce.juandevops.com/public_html
Web serverNginx or Apache served from public_html/public/index.php
Process userDeployment SSH user, with www-data as the shared group
CDN / ProxyCloudflare — handles TLS termination, caching, and DDoS protection in front of the OCI instance

Required GitHub Secrets

Three secrets must be added to the repository under Settings → Secrets and variables → Actions before the workflow can connect to the server.
SecretDescription
SERVER_HOSTPublic IP address or hostname of the OCI VPS (e.g. 203.0.113.42 or api-ecommerce.juandevops.com)
SERVER_USERNAMELinux username that the runner will SSH into (must have sudo access to run chown/chmod commands in the script)
SSH_PRIVATE_KEYPEM-encoded private key whose public counterpart is listed in ~/.ssh/authorized_keys on the server
To generate a dedicated deploy key pair:
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/deploy_key
# Add deploy_key.pub to ~/.ssh/authorized_keys on the server
# Paste the contents of deploy_key (private) into the SSH_PRIVATE_KEY secret

Manual deployment

If you need to deploy outside of GitHub Actions — for example, after provisioning a new server or rolling back — follow these steps directly on the server.
1

Pull the latest code

SSH into the server and navigate to the project directory, then fetch the latest changes from main.
cd /home/api-ecommerce.juandevops.com/public_html
git reset --hard
git pull origin main
2

Install production dependencies

Run Composer without development packages and with classmap optimisation enabled.
composer install --no-dev --optimize-autoloader --no-interaction
3

Cache configuration and routes

Compile the configuration and route files into their cached equivalents so Laravel does not parse them on every request.
php artisan config:cache
php artisan route:cache
php artisan view:cache
4

Run database migrations

Apply any pending migrations. The --force flag is required in non-local environments because Laravel otherwise prompts for confirmation.
php artisan migrate --force
5

Fix storage permissions

Ensure the web-server process can write to Laravel’s runtime directories.
sudo chmod -R 777 storage/logs/laravel.log
sudo chmod -R 777 storage/framework/cache/data
sudo chmod -R 777 storage/framework/views
sudo chmod -R 777 storage/framework/sessions

Health check

Cloudflare proxies the production domain and performs its own availability monitoring. For application-level verification after a deploy:
  1. HTTP status check — Send a GET request to the API root or a lightweight status endpoint and confirm a 200 OK response:
    curl -I https://api-ecommerce.juandevops.com/api/v1/home
    
  2. Log review — Inspect the Laravel log for any bootstrap errors immediately after deployment:
    tail -n 50 /home/api-ecommerce.juandevops.com/public_html/storage/logs/laravel.log
    
  3. Cloudflare dashboard — Check the Analytics tab in the Cloudflare dashboard for a spike in 5xx errors or an unexpected drop in requests, which can indicate a failed deploy.
Because Cloudflare caches static assets and some API responses at the edge, you may need to purge the Cloudflare cache after deploying a change that affects cached routes. Use Cloudflare Dashboard → Caching → Purge Cache, or trigger a purge via the Cloudflare API.

Build docs developers (and LLMs) love