Hermod API — Deployment to api.hermod.ng ========================================= GitHub repo: git@github.com:Hermodng/hermodapi.git Server: 159.198.66.158 Deploy user: hermod (not root) Path: /home/hermod/hermodngapi URL: https://api.hermod.ng/api/v1 GitHub Actions deploys on push to main/master using secret SSH_PRIVATE_KEY. Manual deploy: root (sshpass) or hermod (SSH key). 0. One-time: GitHub repo and SSH key ------------------------------------- Repo: Ensure local hermod-api is the repo root and has remote: cd hermod-api git remote -v # origin git@github.com:Hermodng/hermodapi.git If not: git init && git remote add origin git@github.com:Hermodng/hermodapi.git Server SSH for hermod (one-time): Run the setup script so user hermod can receive SSH from GitHub Actions. It generates a key pair, installs the public key in /home/hermod/.ssh/authorized_keys, and prints the PRIVATE key. Add that private key to GitHub repo Secrets as SSH_PRIVATE_KEY. sshpass -p 'ROOT_PASSWORD' ssh -o StrictHostKeyChecking=accept-new root@159.198.66.158 'bash -s' < hermod-api/deploy/setup-server-ssh-for-hermod.sh Copy the entire "-----BEGIN OPENSSH PRIVATE KEY-----" … "-----END OPENSSH PRIVATE KEY-----" block into GitHub → Settings → Secrets and variables → Actions → New repository secret → Name: SSH_PRIVATE_KEY, Value: (paste). First push: Add, commit, and push the hermod-api code to GitHub so the repo Hermodng/hermodapi has the code. Then GitHub Actions can deploy on push. cd hermod-api git add . git commit -m "Initial commit" git push -u origin main # If the default branch is master: git push -u origin master PHP-FPM pool and ownership (one-time, as root): So user hermod can chmod all files in /home/hermod/hermodngapi (including storage cache/sessions/views/logs), the PHP-FPM pool for api.hermod.ng must run as hermod. On the server: 1. Copy deploy/php-fpm-pool-api.hermod.ng.conf to the PHP-FPM config dir (e.g. /opt/cpanel/ea-php82/root/etc/php-fpm.d/api.hermod.ng.conf). 2. Restart PHP-FPM: systemctl restart ea-php82-php-fpm (or equivalent). 3. One-time chown so existing files are owned by hermod: chown -R hermod:hermod /home/hermod/hermodngapi After that, PHP creates all new files as hermod and the deploy workflow can run chmod -R 775 storage bootstrap/cache without "Operation not permitted". 1. Set build version (automatic on push, or before rsync) --------------------------------------------------------- So https://api.hermod.ng/ shows the deployed commit as "build". One-time: install the pre-push hook so version.txt is updated on every push: cd hermod-api && ./scripts/install-git-hook.sh Then version.txt is written automatically when you "git push". No need to run set-version.sh before deploy. If you don't use the hook, run before rsync: ./scripts/set-version.sh version.txt is not committed (.gitignore). Compare local "git rev-parse --short HEAD" with the API "build" value to confirm deploy is up to date. 2. Rsync from local to server (manual) -------------------------------------- As root (password; requires sshpass): rsync -avz --delete \ --exclude='.env' --exclude='.git' --exclude='node_modules' --exclude='vendor' \ --exclude='storage/logs/*' --exclude='storage/framework/sessions/*' \ --exclude='storage/framework/views/*' --exclude='storage/framework/cache/data/*' \ --exclude='bootstrap/cache/*' --exclude='.phpunit.result.cache' \ -e "sshpass -p 'j71L9hgpNgQ0zS1P9G' ssh -o StrictHostKeyChecking=accept-new" \ /path/to/hermod-api/ root@159.198.66.158:/home/hermod/hermodngapi/ As hermod (SSH key): use -e "ssh -i /path/to/hermod_deploy_key" and hermod@159.198.66.158:/home/hermod/hermodngapi/ 3. Commands on the server (after deploy) ---------------------------------------- SSH as root (password) or as hermod (key): sshpass -p 'ROOT_PASSWORD' ssh root@159.198.66.158 # or: ssh -i /path/to/key hermod@159.198.66.158 Then run (as root, chown first if needed; as hermod, run directly): cd /home/hermod/hermodngapi composer install --no-dev --optimize-autoloader --ignore-platform-reqs php artisan migrate --force php artisan config:cache php artisan route:cache # Fix storage symlink if it pointed at a local path rm -f public/storage && php artisan storage:link chown -R hermod:nobody . chmod -R 775 storage bootstrap/cache 4. Server .env -------------- Ensure CACHE_STORE=file so the app does not require a database cache table: CACHE_STORE=file If you use database cache, create the cache table (e.g. php artisan cache:table and migrate) instead. 5. Verify --------- curl -sS -o /dev/null -w "%{http_code}" "https://api.hermod.ng/api/v1/category-list" Expect 200. Check that deployed build matches local commit: curl -sS "https://api.hermod.ng/" git -C hermod-api rev-parse --short HEAD The "build" value in the JSON should equal the local short hash if deploy is up to date. 6. Nginx -------- Config: /etc/nginx/conf.d/api.hermod.ng.conf Root: /home/hermod/hermodngapi/public PHP-FPM: 127.0.0.1:9001 Local reference: hermod-api/deploy/nginx-api.hermod.ng.conf To push updated nginx config from local: scp -o StrictHostKeyChecking=no hermod-api/deploy/nginx-api.hermod.ng.conf \ root@159.198.66.158:/etc/nginx/conf.d/api.hermod.ng.conf ssh root@159.198.66.158 "nginx -t && systemctl reload nginx"