Search by

devshaded / laravel-sanctum-starter-kit

DevShaded

An API-only Laravel starter kit with Sanctum bearer tokens and Docker development.

Package info

github.com/DevShaded/laravel-sanctum-starter-kit

Type:project

pkg:composer/devshaded/laravel-sanctum-starter-kit

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 2

v1.0.0 2026-10-18 16:35 UTC

This package is auto-updated.

Last update: 2026-10-18 17:21:20 UTC


README

A Laravel 13 API using Sanctum bearer tokens, PHP 8.5, and Laravel Sail. The application has no frontend framework, JavaScript dependencies, or asset build.

Create a project

Use GitHub's Use this template button to create your own repository, then clone it and enter its directory. Requirements: Git, Docker Engine or Docker Desktop with Docker Compose v2, and a POSIX shell (Linux, macOS, or Windows through WSL2). Host PHP, Composer, and Node are not required.

Create with Composer

The public Composer package is devshaded/laravel-sanctum-starter-kit. With Composer 2.10+ and PHP 8.5, use the following command after the package has been registered on Packagist:

composer create-project devshaded/laravel-sanctum-starter-kit example-app \
  --prefer-dist --no-install --no-scripts
cd example-app

Composer selects the latest stable release. To select a specific release, add its version after example-app, for example 1.0.0. Continue with Fresh-clone setup below. --no-install --no-scripts defers dependency installation and application initialization until Docker is configured.

Until Packagist registration is complete, the public GitHub repository works directly without repository credentials:

composer create-project devshaded/laravel-sanctum-starter-kit example-app 1.0.0 \
  --prefer-dist --no-install --no-scripts \
  --repository='{"type":"vcs","url":"https://github.com/DevShaded/laravel-sanctum-starter-kit"}'
cd example-app

Composer package names are lowercase. create-project takes the package name directly; it does not display a starter-kit selection menu.

Fresh-clone setup

Create the local environment and record your local user/group IDs:

cp .env.example .env
printf '\nWWWUSER=%s\nWWWGROUP=%s\n' "$(id -u)" "$(id -g)" >> .env

Before starting containers, edit .env:

  • Set APP_NAME to your application name.
  • Set COMPOSE_PROJECT_NAME to a unique lowercase name such as my-api. This isolates containers, networks, volumes, and the built Sail image (my-api-sail:8.5) from other projects.
  • Set DB_DATABASE to your application's database name before the first database startup.
  • Choose unused host ports for APP_PORT, FORWARD_DB_PORT, FORWARD_REDIS_PORT, FORWARD_MAILPIT_PORT, and FORWARD_MAILPIT_DASHBOARD_PORT. Update APP_URL to match APP_PORT.

Sail lives in vendor, so download dependencies with a disposable Composer container before invoking Sail:

docker run --rm \
  --user "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$PWD:/app" -w /app \
  composer:2.10 install --ignore-platform-reqs --no-scripts --no-plugins --no-interaction --prefer-dist

vendor/bin/sail up -d --build
vendor/bin/sail composer setup
vendor/bin/sail composer check-platform-reqs
vendor/bin/sail composer check
vendor/bin/sail composer audit --locked

The bootstrap container only downloads locked dependencies. Platform checks, plugins, and scripts run inside Sail with PHP 8.5 during composer setup; check-platform-reqs verifies the real runtime. Initial image builds may take several minutes. If an image build encounters a temporary package-mirror failure, rerun it.

composer setup installs dependencies, creates .env if missing, clears cached configuration, generates APP_KEY only when empty, and runs pending migrations. It can be rerun without rotating your key. Do not use it for production deployment. Rebuild with vendor/bin/sail build after changing WWWGROUP.

Daily development

vendor/bin/sail up -d
vendor/bin/sail composer dev

composer dev runs the queue worker in the current terminal. Run the scheduler in another terminal when needed:

vendor/bin/sail artisan schedule:work

Default host ports bind to localhost:

Service Host port Container address
API 8081 laravel.test:80
PostgreSQL 5433 pgsql:5432
Redis 6380 redis:6379
Mailpit dashboard 8026 mailpit:8025
Mailpit SMTP 1026 mailpit:1025

Application connections use container service names and container ports; changing a forwarded host port does not change DB_PORT, REDIS_PORT, or MAIL_PORT.

Stop containers with vendor/bin/sail stop, or remove containers and networks with vendor/bin/sail down. Volumes persist. down --volumes deletes the project's database and Redis data. Changing DB_DATABASE after PostgreSQL initializes does not rename or create databases in an existing volume.

Customize the template

  • Change Composer name, description, and keywords in composer.json. Refresh the lock metadata with vendor/bin/sail composer update --lock --no-install --no-scripts --no-plugins.
  • Customize .env.example application/database names and Compose project name for your repository, then update your untracked .env.
  • Assign distinct Compose project names and all five host ports to run multiple generated projects together.
  • Keep the MIT copyright notice when reusing the code; add your own copyright attribution as appropriate.
  • Replace this README's title and project-specific guidance as your application grows.

API authentication

  • GET /up is the public health endpoint. Send Accept: application/json for a JSON response.
  • GET /api/user returns the authenticated user and requires Authorization: Bearer <token>.
  • Missing, invalid, expired, or revoked tokens return JSON with status 401. Browser session authentication and Sanctum's CSRF-cookie endpoint are disabled.
  • This is an API scaffold. Registration and login endpoints have not been added.

For a local development token, open Tinker:

./vendor/bin/sail artisan tinker
$user = App\Models\User::factory()->create();
$user->createToken('local-development', ['*'], now()->addDay())->plainTextToken;

Use the returned token:

curl -H 'Accept: application/json' \
  -H 'Authorization: Bearer <token>' \
  http://localhost:8081/api/user

The factory creates a development user; it is not an account provisioning workflow for production. Revoke its tokens with $user->tokens()->delete() when finished.

Tokens do not expire by default. Set the third argument of createToken for per-token expiry, or configure expiration in config/sanctum.php for a global lifetime in minutes. The scheduler runs sanctum:prune-expired --hours=24 daily at midnight (application timezone), deleting tokens expired for more than 24 hours while keeping active and non-expiring tokens. Run one scheduler for the application.

API documentation

Scramble generates the interactive reference at /docs/api and the OpenAPI document at /docs/api.json. Both are available in the local environment without browser sessions. Outside local, the starter kit denies access with HTTP 403 through Scramble's RestrictedDocsAccess middleware. Keep that restriction unless you deliberately implement an access policy for your application.

Quality checks

Larastan extends PHPStan with Laravel support. phpstan.neon uses level 10, the strictest current level, with no baseline or ignored errors. Analysis covers application code, bootstrap files, configuration, database code, routes, and tests.

Rector targets the PHP version required by Composer and applies dead-code, code-quality, and type-declaration rules. Pint handles formatting.

./vendor/bin/sail composer analyse       # Larastan
./vendor/bin/sail composer rector:check  # Report changes without modifying files
./vendor/bin/sail composer rector        # Apply refactorings
./vendor/bin/sail composer format        # Format PHP
./vendor/bin/sail composer test          # PHPUnit
./vendor/bin/sail composer check         # Larastan, Rector dry run, and PHPUnit

Tests use Sail's separate PostgreSQL testing database, with isolated cache, queue, mail, and session drivers.

CI validates Composer configuration, audits locked dependencies, and runs composer check on PHP 8.5 with PostgreSQL 18. A second job verifies the Docker-only fresh-clone setup. Dependabot checks Composer, GitHub Actions, and Docker Compose images weekly; review and merge its pull requests after checks pass. The locally built Sail image is updated through the laravel/sail Composer dependency.

The Composer audit policy permits only the abandoned development dependency symplify/rule-doc-generator-contracts, currently required by driftingly/rector-laravel. All security advisories and other abandoned packages still fail the audit. Remove the exception when the upstream dependency is removed. See Composer's dependency policy.

Deployment

Sail is the local development environment. Deploy using Laravel Cloud or a production runtime with PHP 8.5 and the extensions required by composer check-platform-reqs --no-dev, PostgreSQL, and Redis. Serve only the public directory over HTTPS and allow the application to write to storage and bootstrap/cache.

Configure production secrets through your hosting platform: APP_ENV=production, APP_DEBUG=false, the HTTPS APP_URL, database credentials, Redis credentials, and production mail/storage settings. Preserve this application's DB_CONNECTION=pgsql, QUEUE_CONNECTION=redis, and CACHE_STORE=redis unless deliberately replacing those services. Assign distinct Redis databases or prefixes for applications sharing Redis.

Generate APP_KEY once in the production runtime, store it in the platform's secret manager, and preserve it across deployments. Do not copy the development key or regenerate it during releases. Back up the database and the key. Deploy the committed composer.lock; production does not need development dependencies or frontend builds.

Run these commands in the production application's runtime, using its PHP/Composer executables (Sail prefixes apply only to local development):

composer install --no-dev --prefer-dist --no-interaction --optimize-autoloader
composer check-platform-reqs --no-dev
php artisan migrate --force --no-interaction
php artisan optimize
php artisan queue:restart

Run php artisan queue:work --tries=3 --timeout=60 under a process supervisor that restarts exited workers. Keep the queue connection's retry_after greater than the worker timeout; adjust both for your jobs. queue:restart makes workers finish their current jobs and exit so the supervisor loads the new release. Review failed jobs with php artisan queue:failed.

Run the scheduler on one application node with a cron entry once per minute:

* * * * * cd /path/to/application && php artisan schedule:run >> /dev/null 2>&1

Use your production application's actual path and PHP binary. Monitor queue workers, scheduler failures, application logs, database backups, and the /up health endpoint after deployment. API documentation remains restricted in production.

Publishing releases

This public repository is also a GitHub template. Keep .env, credentials, dependencies, logs, and generated caches out of Git; commit .env.example, composer.lock, application files, tests, workflows, and LICENSE.

Before releasing, require both PHP checks and tests and Fresh clone setup to pass on the release commit. Create a semantic version tag such as v1.0.0; Composer derives versions from Git tags, so do not add a version field to composer.json.

For the initial Packagist publication, sign in at Packagist, open Submit, and enter https://github.com/DevShaded/laravel-sanctum-starter-kit. Enable Packagist's GitHub integration for automatic updates when tags are pushed. Verify that the package page lists the stable release before using the short installation command above. Subsequent releases use new version tags; existing tags must not be moved.

License

This starter kit is licensed under the MIT license.

Laravel Boost

Boost is installed as a development dependency. boost.json records the selected integrations. Start Sail before connecting an agent to the Boost MCP server. Machine-local agent configuration is excluded from Git.

Refresh generated guidelines and skills after dependency changes:

./vendor/bin/sail artisan boost:update --no-interaction