Files
dewemoji/deployment-live-walkthrough.md
2026-03-16 01:06:41 +07:00

4.7 KiB

Dewemoji Operations Runbook

This is the single operational guide for local, staging, and production workflows.

1) Environment model

Local (safe default)

APP_ENV=local
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=sqlite
DEWEMOJI_BILLING_MODE=sandbox
DEWEMOJI_LICENSE_ACCEPT_ALL=false
DEWEMOJI_ALLOWED_ORIGINS=http://127.0.0.1:8000,http://localhost:8000

Staging / Production

  • Use DEWEMOJI_BILLING_MODE=live
  • Configure real DB + provider credentials
  • Keep DEWEMOJI_LICENSE_ACCEPT_ALL=false

For full production variable template, use production-env.md.

2) Live deployment sequence

Pre-deploy

  1. Confirm env values are set in server/Coolify.
  2. Confirm webhook URLs are reachable:
  • https://<domain>/v1/paypal/webhook
  • https://<domain>/webhooks/pakasir
  1. Recommended:
DEWEMOJI_BILLING_PENDING_COOLDOWN_SECONDS=120

Deploy code

git fetch --all
git checkout main
git pull origin main
composer install --no-dev --optimize-autoloader

Post-deploy (required order)

php artisan optimize:clear
php artisan migrate --force
php artisan config:cache

Optional:

php artisan route:cache
php artisan view:cache
php artisan queue:restart

3) Ensure admin access

Promote existing user:

php artisan tinker --execute="\App\Models\User::where('email','dewemoji@gmail.com')->update(['role'=>'admin']);"

Or create missing admin:

php artisan tinker --execute="
\$u=\App\Models\User::firstOrCreate(
 ['email'=>'dewemoji@gmail.com'],
 ['name'=>'Dewemoji Admin','password'=>\Illuminate\Support\Facades\Hash::make('ChangeMeNow123!'),'tier'=>'free','email_verified_at'=>now()]
);
\$u->role='admin';
\$u->save();
"

4) Live smoke tests

Core routes

  1. /
  2. /emoji/grinning-face
  3. /pricing
  4. /api-docs
  5. /support
  6. /privacy
  7. /terms
  8. /robots.txt
  9. /sitemap.xml

API checks

BASE=https://<domain>/v1
curl -s "$BASE/health" | jq .
curl -s "$BASE/categories" | jq 'keys | length'
curl -s "$BASE/emojis?q=love&limit=5" | jq '.items | length'

Billing and webhook checks

tail -n 200 storage/logs/laravel.log
php artisan tinker --execute="dump(\App\Models\WebhookEvent::latest()->take(10)->get(['id','provider','event_type','status','created_at'])->toArray());"
php artisan tinker --execute="dump(\App\Models\Payment::latest()->take(10)->get(['id','provider','plan_code','status','created_at'])->toArray());"

5) Billing runtime validation (staging)

Verify these behaviors end-to-end:

  1. pending cooldown lock on repeat checkout attempts (409 pending_cooldown)
  2. resume pending payment via dashboard Pay
  3. webhook delay handling (pending -> paid transition)
  4. race/edge handling (payment_not_pending, payment_expired)

Minimum assertions:

  • cooldown response includes retry_after
  • resume PayPal returns mode=redirect + approve_url
  • resume Pakasir returns mode=qris with expiry data

6) Staging SQL sync

Set MySQL connection env, then run in container:

cd /var/www/html
php artisan migrate
php artisan dewemoji:import-live-sql /var/www/html/dewemojiAPI_DB.sql --truncate

Sanity check:

php artisan tinker --execute="echo DB::table('emojis')->count().PHP_EOL;"
php artisan tinker --execute="echo DB::table('emoji_keywords')->count().PHP_EOL;"

Expected: emojis ~2131, emoji_keywords ~13420.

7) MySQL GUI access via SSH tunnel

For internal-only Coolify MySQL, tunnel to container IP.

Resolve MySQL container IP:

MYSQL_IP=$(ssh SERVER_USER@SERVER_HOST "docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \$(docker ps --format '{{.ID}} {{.Names}}' | awk '/mysql|mariadb/{print \$1; exit}')")
echo "$MYSQL_IP"

Create tunnel:

ssh -N -L 3307:${MYSQL_IP}:3306 SERVER_USER@SERVER_HOST

Then connect in Sequel Ace/TablePlus using:

  • Host 127.0.0.1
  • Port 3307
  • standard DB credentials

8) Local provider parity test (optional)

Switch local to live provider mode and verify with real keys.

BASE=http://127.0.0.1:8000/v1
curl -X POST "$BASE/license/verify" -H "Content-Type: application/json" -d '{"key":"<real_key>"}'

Also test activate/deactivate cycle, then return local env to sandbox mode.

9) APK release dependency note

App updater URLs used by the site:

  • https://dewemoji.com/downloads/version.json
  • https://dewemoji.com/downloads/dewemoji-latest.apk

For detailed APK build/release flow, use dewemoji-apk-companion-build-walkthrough.md.

10) Rollback

  1. Re-deploy previous known-good commit.
  2. Run:
php artisan optimize:clear
php artisan config:cache
php artisan queue:restart
  1. If issue is dataset-specific, switch to a known-good snapshot via admin tooling.