Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Little Sail Laravel Package

neo/little-sail

View on GitHub
Deep Wiki
Context7

Getting Started

Little Sail is a drop-in replacement for the sail-* application images bundled with Laravel Sail. The images are built FROM alpine rather than ubuntu, so instead of ~1.2 GB per service you typically land around 300–500 MB. That is the entire value proposition: faster docker pull, faster cold CI, less disk churn. Nothing in your Laravel app changes — it is a Docker image substitution.

Step 1 — confirm you actually run Sail. If docker-compose.yml still has:

laravel.test:
  build:
    context: ./vendor/laravel/sail/runtimes/8.1
    dockerfile: Dockerfile

you are on the stock image and can swap it.

Step 2 — replace the build: block with an image: reference.

services:
  laravel.test:
    image: neoighodaro/little-sail:8.1
    ports:
      - '${APP_PORT:-80}:80'
    environment:
      WWWUSER: '${WWWUSER}'
      LARAVEL_SAIL: 1
      XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
      XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
    volumes:
      - '.:/var/www/html'
    networks:
      - sail
    depends_on:
      - mysql
      - redis

Keep the rest of the Sail skeleton (volumes, networks, depends_on, the WWWUSER/LARAVEL_SAIL env vars) intact — the image expects them.

Step 3 — rebuild and verify. Because you removed build:, you must explicitly recreate the container so Docker drops the old image layer:

sail down
sail up -d
sail php -v          # confirm 8.1 and that extensions loaded
sail composer --version
sail artisan about

Where to look first. The repo's README lists the available tags (PHP 8.0 and 8.1 variants at the time of the last release). Check the tag list before assuming a version exists — there is no latest you should trust. Then compare against docker/sail/Dockerfile in your installed Sail version to see which extensions the stock image installs that Little Sail might not, and php -m inside the running container to catch gaps.

First real use case. Local dev on a small-SSD laptop where two or three Sail projects' worth of Ubuntu images (plus MySQL and Redis) is eating 8–10 GB. Swapping just the laravel.test service reclaims the bulk of it, and sail up starts noticeably faster on a cold cache.

Implementation Patterns

Use it as a base layer, not just a pull. The most durable pattern is to write your own tiny Dockerfile that pins the Little Sail tag and layers on the extensions your app needs. This keeps you immune to the package being unmaintained for a specific extension:

FROM neoighodaro/little-sail:8.1

# apk, not apt — and PHP's pecl/install-php-extensions behave differently here
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS \
    && docker-php-ext-install bcmath \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && apk del .build-deps

Then point build: at your local docker/ directory in docker-compose.yml. This is also how you upgrade past the frozen tag list.

Compose override file for team-wide opt-in. Do not edit the tracked docker-compose.yml if you have colleagues on slow networks who would rather not pull a new image. Add docker-compose.little.yml:

services:
  laravel.test:
    image: neoighodaro/little-sail:8.1
    build: !reset

(Sail 8.x's compose supports !reset; on older versions just document that the override wins on image but you must comment out build in the base file.) Run with docker compose -f docker-compose.yml -f docker-compose.little.yml up -d.

CI jobs. For GitHub Actions, use the image directly for the PHP test job instead of shivammathur/setup-php:

services:
  mysql:
    image: mysql:8.0
    env:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: testing
    ports: ['3306:3306']
jobs:
  tests:
    runs-on: ubuntu-latest
    container:
      image: neoighodaro/little-sail:8.1
    steps:
      - uses: actions/checkout@v4
      - run: composer install --prefer-dist --no-interaction
      - run: cp .env.example .env && php artisan key:generate
      - run: php artisan test

The Alpine base is the point here — a smaller image means fewer seconds spent pulling on every matrix leg.

Multi-project sharing. Because the image is a single pullable artifact rather than a per-project build, several Laravel repos on a machine share one layer set. Standardise on one tag across projects:

docker images | grep little-sail   # see what you already have locally

Mixed stacks. Little Sail gives you an Alpine laravel.test, but MySQL and Redis images in Sail are still the upstream Debian ones. That asymmetry is fine — keep the database services on Sail's defaults and only shrink the app container, which is the big one anyway.

Debugging workflow. Run the same commands you would against Sail, since the entrypoint is Sail-compatible:

sail exec laravel.test sh          # ash, not bash — see gotchas
sail logs -f laravel.test
docker inspect --format '{{.Config.Env}}' $(sail ps -q laravel.test 2>/dev/null)

Gotchas and Tips

It has not been released since February 2022. This is the single most important fact in this assessment. There are no PHP 8.2, 8.3, or 8.4 images, no arm64 variants, and no fixes for anything found since. Treat the tags as frozen artifacts: pin them explicitly, never use an unpinned tag, and plan to maintain your own FROM layer if you need to move forward. Check docker manifest inspect neoighodaro/little-sail:8.1 before committing your team to it.

Apple Silicon will hurt. If the published images are amd64-only, Docker Desktop's emulation layer makes a "smaller" image feel slower than the native Ubuntu one despite the pull advantage. Verify architecture support with docker inspect --format '{{.Architecture}}' on the pulled image before you sell this to the team on speed grounds.

musl vs glibc is the silent killer. Alpine uses musl. Things that compile fine on Sail's Ubuntu image and fail here:

  • Proprietary or prebuilt binaries distributed as glibc-linked ELF (some SDKs, some static analysers, certain database CLIs).
  • Older Node.js tarball installs if you bypass apk.
  • pecl extensions that assume glibc headers.
  • Anything in your app's CI that shells out to a downloaded .so or binary.

Symptom is usually a not found when running a binary that plainly exists on disk — that is the dynamic loader, not permissions. apk add gcompat libc6-compat sometimes papers over it; usually you rewrite the install step.

No bash. Sail muscle memory includes sail shell dropping you into bash. Alpine ships ash. Either apk add bash in your derived Dockerfile or retrain the habit to sail exec laravel.test sh.

UID/GID and file permissions. Sail's stock image creates a user matching WWWUSER/WWWGID from .env so files written in the container are owned by you on the host. Confirm Little Sail honours both variables, not just WWWUSER:

sail exec laravel.test id        # should show your uid/gid, not root
touch test.txt && ls -ln test.txt

If it comes back root-owned on the host, add the usermod/chown steps yourself in a derived Dockerfile. This is the most common source of "why can't my editor save storage/logs/laravel.log" complaints.

Xdebug is off and the config path differs. XDEBUG_CONFIG and XDEBUG_MODE are passed through, but if your team relies on a mounted xdebug.ini, the stock Sail path is Ubuntu's /etc/php/8.1/...; Alpine uses /usr/local/etc/php/conf.d/. Mount accordingly or your Xdebug silently never activates. Verify with sail php -i | grep xdebug.

Composer and Node versions are frozen at the image's build date. The Composer 2.x baked in will be from early 2022. sail composer self-update works inside the container but is lost on recreate. Put RUN composer self-update in your derived Dockerfile instead, or accept the version and be aware that composer.lock content-hash mismatches on very new plugin requirements are a real possibility.

Don't fight sail:publish. Running sail artisan sail:publish regenerates docker/8.x/ and can confuse docker-compose.yml if you have half-swapped to an image. If you go the image route, remove the build: block entirely rather than leaving it dangling — Compose will otherwise rebuild the Ubuntu image on sail build --no-cache and you will wonder why your container is 1.2 GB again.

Extension points, ranked. (1) Derived Dockerfile FROM neoighodaro/little-sail:<tag> — best balance of size and control. (2) The raw apk package list from the upstream repo's Dockerfile — copy it into your own multi-stage build if you want to be fully independent. (3) Compose override file for a per-developer opt-in without touching tracked config. There is no supported plugin mechanism, no config file, and no Laravel-side integration — it is an image and nothing more, so treat every customisation as a Dockerfile concern.

Fallback if it breaks. The stock Sail runtime is one git checkout away: restore the build: context: ./vendor/laravel/sail/runtimes/<version> block and sail build --no-cache. Because Little Sail only ever touched image:/build:, the rollback is trivial — keep that diff small and isolated in a single commit so a team can revert in seconds during a demo.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager