gon remote

Run commands on the production server without manual SSH. Resolves the current project from gon.json, looks up its host in ~/.gon/servers.json, and executes inside /opt/{project} on the remote machine. Three sub-commands cover the common cases: a Laravel artisan wrapper, an arbitrary shell executor, and an interactive container shell.

Commands

gon remote:artisan <args...> # Run php artisan on the production app container
gon remote:exec <command...> # Run any shell command in the project directory
gon remote:shell [service] # Interactive bash inside a docker compose service

All three commands require that the current directory contains a valid gon.json and that the project is registered in ~/.gon/servers.json (via gon server:add-project). They SSH as the deploy user by default.

remote:artisan

Runs a Laravel artisan command inside the app container on the production server. Output is streamed in real time with TTY passthrough, so interactive commands like tinker work as expected.

gon remote:artisan about
gon remote:artisan cache:clear
gon remote:artisan migrate --force
gon remote:artisan queue:restart
gon remote:artisan tinker
gon remote:artisan tinker --execute="echo \Modules\Users\Models\User::count();"

Flags like --force, --env=foo, and --execute="..." are forwarded to artisan transparently — gon does not interpret them as its own options.

Under the hood:

ssh -t deploy@<host> "cd /opt/<project> && docker compose exec -T app php artisan <args>"

remote:exec

Runs an arbitrary shell command inside /opt/{project} on the production server. Useful for log tailing, container status checks, disk usage, or anything that doesn't go through artisan.

gon remote:exec ls -la
gon remote:exec tail -100 storage/logs/laravel.log
gon remote:exec docker compose ps
gon remote:exec docker compose logs -f --tail=50 app
gon remote:exec df -h
gon remote:exec du -sh storage/app storage/logs

The command runs in the host shell at /opt/{project}, not inside the app container. To run something inside a container, prefix explicitly with docker compose exec, or use remote:artisan / remote:shell.

remote:shell

Opens an interactive bash session inside a docker compose service. Defaults to the app container but you can target any service defined in docker-compose.yml.

gon remote:shell # bash inside the app container
gon remote:shell mysql # bash inside the mysql container
gon remote:shell horizon # bash inside the horizon queue worker

Type exit (or Ctrl+D) to return to your local terminal. Under the hood:

ssh -t deploy@<host> "cd /opt/<project> && docker compose exec <service> bash"

Errors

If the current directory has no gon.json:

gon remote:artisan about
# gon.json not found in current directory.

If the project isn't registered for a server:

gon remote:artisan about
# No server configured for project "myapp". Run `gon server:add-project` first.

Scope & safety

  • Whoever has an SSH key on the server can use these commands — there's no additional authorization layer
  • There's no denylist or sanitization; gon remote:exec rm -rf / will do exactly what you'd expect. Treat it like a direct SSH session
  • Only projects with a single production host are supported today; multi-environment targeting (staging, etc.) is not yet implemented

Related