Skip to content

Commit

Permalink
📝 Update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
bdsoha committed Jan 22, 2025
1 parent 40e3372 commit 5947037
Showing 1 changed file with 201 additions and 15 deletions.
216 changes: 201 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,206 @@
# Laravel Docker Base

> Docker base image for Laravel production applications
> Docker base image for **Laravel production** applications using **FrankenPHP**
This repository provides a minimal yet comprehensive Docker *base* image for deploying
your Laravel application in production.
**It is intended purely as a foundation image** — you should **extend** it in your
project rather than run it directly [*(see below)*](#getting-started).

## Release Tags

- **Development *(`:dev`)***: Built automatically from every commit to the `main` branch.
- **Production *(`:vX.Y.Z`)***: Tagged versions for stable releases, with `:latest`
pointing to the most recent version.

## Table of Contents

- [Release Tags](#release-tags)
- [Table of Contents](#table-of-contents)
- [Features](#features)
- [Getting Started](#getting-started)
- [Environment Variables](#environment-variables)
- [Container Modes](#container-modes)
- [`app`](#app)
- [`worker`](#worker)
- [`horizon`](#horizon)
- [`scheduler`](#scheduler)
- [Manual Setup vs Automatic Setup](#manual-setup-vs-automatic-setup)
- [Testing Connections](#testing-connections)
- [Contributing](#contributing)
- [License](#license)

## Features

- **FrankenPHP**: Powered by the [FrankenPHP][] runtime, providing a performant way to
serve Laravel.
- **Container Modes**: Easily switch between `app`, `worker`, `horizon`, and `scheduler`
modes.
- **Connection Testing**: Optional checks for database, cache, S3, and SMTP connections
before serving the app.
- **Automatic Setup**: Laravel migrations, caches *(config, routes, views, events)*, and
storage linking happen by default.
- **PHP Extensions**: Commonly used PHP extensions for a typical Laravel application
*(bcmath, bz2, intl, redis, etc.)*.

## Getting Started

Because this is a base image, you’ll typically reference it in your own `Dockerfile`.
We strongly recommend using multi-stage builds to handle dependencies
*(e.g., installing Composer or Node packages)*, ensuring your final production image is as
lean as possible.

Below is an example `Dockerfile` that extends `laravel-docker-base`:

```dockerfile
FROM ghcr.io/kloudkit/laravel-docker-base:latest AS base

#################################### Vendor ####################################

FROM base AS vendor
WORKDIR /build

COPY composer.json .
COPY composer.lock .
COPY packages packages

RUN composer install \
--ignore-platform-reqs \
--no-cache \
--no-interaction \
--no-scripts \
--prefer-dist

#################################### NodeJS ####################################

FROM node:latest AS client
WORKDIR /build

COPY package*.json .
COPY postcss.config.js .
COPY tailwind.config.js .
COPY vite.config.js .

COPY resources resources
COPY --from=vendor /build/vendor vendor

RUN npm install && npm run build

##################################### App ######################################

FROM base

COPY --chown=laravel:laravel composer.json composer.json
COPY --chown=laravel:laravel composer.lock composer.lock
COPY --chown=laravel:laravel app app
COPY --chown=laravel:laravel bootstrap bootstrap
COPY --chown=laravel:laravel config config
COPY --chown=laravel:laravel database database
COPY --chown=laravel:laravel packages packages
COPY --chown=laravel:laravel public public
COPY --chown=laravel:laravel resources resources
COPY --chown=laravel:laravel routes routes
COPY --chown=laravel:laravel --from=client /build/public public

RUN composer install \
--no-ansi \
--no-dev \
--no-interaction \
--no-progress \
--no-scripts \
--prefer-dist \
--quiet \
&& composer dump-autoload \
--classmap-authoritative \
--no-dev
```

## Environment Variables

| `env` | Default | Mode |
| -------------------------- | -------------- | ------ |
| `APP_DEBUG` | `false` | `*` |
| `APP_ENV` | `"production"` | `*` |
| `CONTAINER_MANUAL_SETUP` || `*` |
| `CONTAINER_MODE` | `"app"` | `*` |
| `CONTAINER_PORT` | `8000` | app |
| `CONTAINER_WORKER_DELAY` | `10` | worker |
| `CONTAINER_WORKER_SLEEP` | `5` | worker |
| `CONTAINER_WORKER_TRIES` | `3` | worker |
| `CONTAINER_WORKER_TIMEOUT` | `300` | worker |
| `TEST_DB_CONNECTION` | `true` | `*` |
| `TEST_CACHE_CONNECTION` | `true` | `*` |
| `TEST_CONNECTION_TIMEOUT` | `10` | `*` |
You can customize the container by setting the following environment variables:

| **Variable** | **Default** | **Modes** | **Description** |
| -------------------------- | -------------- | --------- | --------------------------------------------------------------------- |
| `APP_DEBUG` | `false` | `*` | Laravel debug mode |
| `APP_ENV` | `"production"` | `*` | Laravel environment name |
| `CONTAINER_MANUAL_SETUP` | *(empty)* | `*` | Skips automatic setup *(migrations, caching, etc.)* |
| `CONTAINER_MODE` | `"app"` | `*` | Define the container mode *(see [Container Modes](#container-modes))* |
| `CONTAINER_PORT` | `8000` | `app` | Port FrankenPHP listens to *(when in `app` mode)* |
| `CONTAINER_WORKER_DELAY` | `10` | `worker` | `queue:work` delay |
| `CONTAINER_WORKER_SLEEP` | `5` | `worker` | `queue:work` sleep |
| `CONTAINER_WORKER_TRIES` | `3` | `worker` | `queue:work` tries |
| `CONTAINER_WORKER_TIMEOUT` | `300` | `worker` | `queue:work` timeout |
| `TEST_CACHE_CONNECTION` | `true` | `*` | Test cache connection on startup |
| `TEST_DB_CONNECTION` | `true` | `*` | Test database connection on startup |
| `TEST_S3_CONNECTION` | `false` | `*` | Test S3 connection on startup |
| `TEST_SMTP_CONNECTION` | `false` | `*` | Test SMTP connection on startup |
| `TEST_CONNECTION_TIMEOUT` | `10` | `*` | Seconds to attempt each connection test before failing |

## Container Modes

This image supports multiple container modes via the `CONTAINER_MODE` variable, each
focusing on a specific type of service:

### `app`

- Serves the Laravel application using FrankenPHP on port `CONTAINER_PORT`
*(default `8000`)*.
- Ideal for load-balanced or standalone app containers.

### `worker`

- Runs `php artisan queue:work` with the provided settings *(`CONTAINER_WORKER_*`)*.
- Suitable for handling asynchronous jobs.

### `horizon`

- Runs `php artisan horizon`.
- Ideal if you prefer Laravel Horizon for managing queues.

### `scheduler`

- Runs `php artisan schedule:work` in the foreground.
- Great for cron-like, scheduled tasks.

## Manual Setup vs Automatic Setup

By default, this image **automatically**:

- Tests connections *(DB, cache, S3, SMTP)* if `TEST_*` variables are set to `true`.
- Runs `php artisan migrate --force`.
- Creates the storage symlink *(if not already present)*.
- Caches config, events, routes, and views.

If you need to skip these steps *(e.g., you manage migrations separately)*, set
`CONTAINER_MANUAL_SETUP` to any non-empty value, and the container will **skip** all
auto-setup steps, running the [Container Mode](#container-modes) command directly.

## Testing Connections

The image's entrypoint can optionally test common connections before starting
*(or failing fast)*, depending on environment variables:

- **Database:**: Controlled by `TEST_DB_CONNECTION` *(`true` by default)*.
- **Cache:**: Controlled by `TEST_CACHE_CONNECTION` *(`true` by default)*.
- **S3:**: Controlled by `TEST_S3_CONNECTION` *(`false` by default)*.
- **SMTP:**: Controlled by `TEST_SMTP_CONNECTION` *(`false` by default)*.

Each test will attempt a connection for up to `TEST_CONNECTION_TIMEOUT` seconds before
giving up and exiting with a non-zero code.
This ensures your container won’t fully start unless its dependencies are actually ready.

> [!IMPORTANT]
> Ensure you provide the correct authentication environment variables
> *(DB_HOST, DB_USERNAME, DB_PASSWORD, etc.)* for any connections you enable.
## Contributing

Contributions are welcome!
Please open issues or submit pull requests for any improvements or fixes you find.

## License

This project is open-sourced software licensed under the [MIT license](LICENSE).
Feel free to adapt it to your needs.

[FrankenPHP]: https://frankenphp.dev

0 comments on commit 5947037

Please sign in to comment.