-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/cu 86dwa58wh/upgrade dockerfile serversideup #298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 12.x
Are you sure you want to change the base?
Changes from all commits
fadbd41
51941b9
7d6cd1c
621c19d
ebb45d2
ac01dc8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Dockerfile for Laravel using serversideup/php (API-Only) | ||
|
||
# | ||
# Builder Stage (Stays the same) | ||
# | ||
FROM serversideup/php:8.4-cli AS builder | ||
USER root | ||
RUN apt-get update && apt-get install -y \ | ||
build-essential \ | ||
libpng-dev \ | ||
libjpeg62-turbo-dev \ | ||
libfreetype6-dev \ | ||
locales \ | ||
zip \ | ||
jpegoptim optipng pngquant gifsicle \ | ||
vim \ | ||
unzip \ | ||
git \ | ||
curl | ||
RUN install-php-extensions intl | ||
WORKDIR /var/www/html | ||
USER www-data | ||
RUN git config --global --add safe.directory /var/www/html | ||
COPY --chown=www-data:www-data composer.json composer.lock ./ | ||
RUN composer install --optimize-autoloader --no-dev --no-scripts | ||
COPY --chown=www-data:www-data . . | ||
RUN composer run-script post-autoload-dump | ||
|
||
# Temporarily use a file-based cache and a non-existent in-memory database | ||
# for the build process, preventing errors when a real DB is not available. | ||
ENV CACHE_DRIVER=array | ||
ENV DB_CONNECTION=sqlite | ||
ENV DB_DATABASE=:memory: | ||
# Clear any previous caches and optimize for production | ||
# This caches configuration and routes for faster performance | ||
#RUN php artisan optimize:clear | ||
RUN php artisan optimize | ||
|
||
# | ||
# ---- Final App Stage (Web Server) ---- | ||
# This is your final, lean image for the web application. | ||
# | ||
FROM serversideup/php:8.4-fpm-nginx AS api | ||
WORKDIR /var/www/html | ||
USER root | ||
RUN install-php-extensions intl | ||
COPY --from=builder /var/www/html /var/www/html | ||
RUN chown -R www-data:www-data /var/www/html | ||
RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache | ||
USER www-data | ||
ENV AUTORUN_ENABLED=true | ||
ENV PHP_OPCACHE_ENABLE=1 | ||
ENV AUTORUN_LARAVEL_MIGRATION=true | ||
EXPOSE 8080 | ||
|
||
# ---- Final Scheduler Stage (CLI Worker) ---- | ||
# This is the new, optimized image just for your scheduler. | ||
# | ||
FROM serversideup/php:8.4-fpm-nginx AS scheduler | ||
WORKDIR /var/www/html | ||
|
||
# ⬇️ 1. We are the ROOT user by default here. This is correct. ⬇️ | ||
USER root | ||
|
||
# 3. Copy application code and cron files, still as ROOT. | ||
COPY --from=builder /var/www/html /var/www/html | ||
RUN chown -R www-data:www-data /var/www/html | ||
RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache | ||
|
||
# 2. Install any additional PHP extensions needed for the scheduler. | ||
RUN install-php-extensions intl | ||
|
||
COPY ./.docker/scheduler-entrypoint.sh /var/www/html/scheduler-entrypoint.sh | ||
RUN chmod +x /var/www/html/scheduler-entrypoint.sh | ||
|
||
# 4. ⬇️ NOW, switch to the low-privilege user for running the application. ⬇️ | ||
USER www-data | ||
|
||
ENV AUTORUN_ENABLED=true | ||
ENV PHP_OPCACHE_ENABLE=1 | ||
|
||
EXPOSE 8080 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Laravel Docker Environment | ||
|
||
This project provides a production-ready Docker setup for a Laravel application using `serversideup/php` images. It includes a multi-stage `Dockerfile` for optimized builds and a `docker-compose.yml` file to orchestrate the application, database, and caching services. | ||
|
||
## Prerequisites | ||
|
||
- Docker | ||
- Docker Compose | ||
|
||
## Setup & Installation | ||
|
||
1. **Clone the Repository:** | ||
Clone this project to your local machine. | ||
|
||
2. **Configure Environment:** | ||
Create a `.env` file in the project root by copying the example file: | ||
```bash | ||
cp .env.example .env | ||
``` | ||
Update the `.env` file with your specific application and database settings. The default database configuration is set up to work with the `docker-compose.yml` file provided. | ||
|
||
3. **Generate Application Key:** | ||
If this is a new project, you'll need to generate a Laravel application key. First, start the containers, then run the command. | ||
```bash | ||
# Start containers in the background | ||
docker-compose up -d --build | ||
|
||
# Generate the key | ||
docker-compose exec app php artisan key:generate | ||
``` | ||
|
||
## Usage | ||
|
||
- **Build and Start Containers:** | ||
```bash | ||
docker-compose up -d --build | ||
``` | ||
Your application will be available at `http://localhost:8080`. | ||
|
||
- **Stop Containers:** | ||
```bash | ||
docker-compose down | ||
``` | ||
|
||
- **Stop Containers and Remove Volumes:** (Use this to start fresh) | ||
```bash | ||
docker-compose down -v | ||
``` | ||
|
||
## Scheduled Tasks (Cron) | ||
|
||
To run Laravel's scheduled tasks, this setup includes a dedicated `scheduler` service in the `docker-compose.yml` file. | ||
|
||
This container uses the same application image but runs a loop that executes `php artisan schedule:run` every minute. This is the standard way to handle cron jobs in a containerized Laravel application. | ||
|
||
All of your scheduled tasks are defined in the `app/Console/Kernel.php` file as usual. The `scheduler` service will automatically pick up and execute any tasks you define there. | ||
|
||
## Laravel Automations (`serversideup/php`) | ||
|
||
The `serversideup/php` image provides a powerful automation system that can run common Laravel commands for you when the container starts. This is perfect for production deployments. | ||
|
||
### Master Switch | ||
|
||
All automations are controlled by a single master switch. They will **only run** if this is enabled. | ||
|
||
- **`AUTORUN_ENABLED`**: Set to `"true"` to enable the automation scripts. Defaults to `false`. | ||
|
||
### Automation Flags | ||
|
||
If `AUTORUN_ENABLED` is set to `"true"`, you can then toggle individual automations. | ||
|
||
| Environment Variable | Default | Command Executed | Description | | ||
| ---------------------------------- | ------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `AUTORUN_LARAVEL_MIGRATION` | `true` | `php artisan migrate --force` | Automatically runs your database migrations. | | ||
| `AUTORUN_LARAVEL_CONFIG_CACHE` | `true` | `php artisan config:cache` | Caches your configuration files for a significant performance boost. | | ||
| `AUTORUN_LARAVEL_ROUTE_CACHE` | `true` | `php artisan route:cache` | Caches your route definitions. | | ||
| `AUTORUN_LARAVEL_VIEW_CACHE` | `true` | `php artisan view:cache` | Compiles and caches your Blade templates. | | ||
| `AUTORUN_LARAVEL_EVENT_CACHE` | `true` | `php artisan event:cache` | Caches your application's events and listeners. | | ||
| `AUTORUN_LARAVEL_STORAGE_LINK` | `true` | `php artisan storage:link` | Creates the symbolic link from `public/storage` to `storage/app/public`. | | ||
| `AUTORUN_LARAVEL_MIGRATION_ISOLATION` | `false` | `php artisan migrate --force --isolated` | Ensures only one container runs migrations at a time. Requires Laravel 9.38+ and a locking database. | | ||
| `AUTORUN_LARAVEL_MIGRATION_TIMEOUT` | `30` | N/A | The number of seconds the script will wait for the database to be available before migrating. | | ||
|
||
## Manual Artisan Commands | ||
|
||
You can run any `artisan` command manually by executing it inside the `app` container. | ||
|
||
- **Run Migrations:** | ||
```bash | ||
docker-compose exec app php artisan migrate | ||
``` | ||
|
||
- **Access Tinker:** | ||
```bash | ||
docker-compose exec app php artisan tinker | ||
``` | ||
|
||
- **Clear Cache:** | ||
```bash | ||
docker-compose exec app php artisan optimize:clear | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/bin/sh | ||
set -e | ||
|
||
echo "Scheduler entrypoint script started." | ||
|
||
while true; do | ||
# Run the Laravel scheduler command. | ||
# We use 'php -d memory_limit=-1' to ensure it doesn't run out of memory. | ||
php -d memory_limit=-1 /var/www/html/artisan schedule:run | ||
|
||
# Wait for 60 seconds before the next run. | ||
sleep 60 | ||
done | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,3 @@ | ||
# This workflow will build and push a new container image to Amazon ECR, | ||
# and then will deploy a new task definition to Amazon ECS, when there is a push to the "master" branch. | ||
# | ||
# To use this workflow, you will need to complete the following set-up steps: | ||
# | ||
# 1. Create an ECR repository to store your images. | ||
# For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`. | ||
# Replace the value of the `ECR_REPOSITORY` environment variable in the workflow below with your repository's name. | ||
# Replace the value of the `AWS_REGION` environment variable in the workflow below with your repository's region. | ||
# | ||
# 2. Create an ECS task definition, an ECS cluster, and an ECS service. | ||
# For example, follow the Getting Started guide on the ECS console: | ||
# https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun | ||
# Replace the value of the `ECS_SERVICE` environment variable in the workflow below with the name you set for the Amazon ECS service. | ||
# Replace the value of the `ECS_CLUSTER` environment variable in the workflow below with the name you set for the cluster. | ||
# | ||
# 3. Store your ECS task definition as a JSON file in your repository. | ||
# The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`. | ||
# Replace the value of the `ECS_TASK_DEFINITION` environment variable in the workflow below with the path to the JSON file. | ||
# Replace the value of the `CONTAINER_NAME` environment variable in the workflow below with the name of the container | ||
# in the `containerDefinitions` section of the task definition. | ||
# | ||
# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. | ||
# See the documentation for each action used below for the recommended IAM policies for this IAM user, | ||
# and best practices on handling the access key credentials. | ||
|
||
name: Deploy to Amazon ECS DEV | ||
|
||
on: | ||
|
@@ -33,27 +7,27 @@ on: | |
|
||
env: | ||
ENVIRONMENT: dev | ||
AWS_REGION: us-east-1 # set this to your preferred AWS region, e.g. us-west-1 | ||
ECR_REPOSITORY: REPLACEPROJECTNAME # set this to your Amazon ECR repository name | ||
ECS_CLUSTER: REPLACEPROJECTNAME # set this to your Amazon ECS cluster name | ||
# ECS_TASK_DEFINITION: MY_ECS_TASK_DEFINITION # set this to the path to your Amazon ECS task definition | ||
# file, e.g. .aws/task-definition.json | ||
CONTAINER_NAME: | ||
REPLACEPROJECTNAME # set this to the name of the container in the | ||
# containerDefinitions section of your task definition | ||
DOCKER_PLATFORM: linux/amd64 # set this to the platform you want to build for | ||
IMAGE_TAG: ${{ github.run_id }}-${{ github.run_attempt }} | ||
REGISTRY_URL: <ECR URL> | ||
AWS_REGION: REPLACEREGION | ||
ECS_CLUSTER: REPLACEPROJECTNAME # Your Amazon ECS cluster name | ||
# The base name for your ECR repositories. We'll append '-app' and '-scheduler'. | ||
ECR_REPOSITORY_BASE: REPLACEPROJECTNAME | ||
DOCKER_PLATFORM: linux/amd64 | ||
# A unique tag for this specific workflow run | ||
IMAGE_TAG: ${{ github.sha }} | ||
REGISTRY_URL: ${{ secrets.AWS_ACCOUNT_ID_DEV }}.dkr.ecr.us-east-1.amazonaws.com | ||
|
||
permissions: | ||
contents: read | ||
id-token: write | ||
|
||
jobs: | ||
setup: | ||
name: Deploy | ||
build-and-deploy: | ||
name: Build and Deploy ${{ matrix.service }} | ||
runs-on: ubuntu-latest | ||
# environment: dev # Works only on paid GH orgs | ||
environment: develop | ||
strategy: | ||
matrix: | ||
service: [api, scheduler] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No queue worker? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didnt have that present, will look into it, is there another side-service i should take into account? |
||
|
||
steps: | ||
- name: Checkout | ||
|
@@ -62,72 +36,43 @@ jobs: | |
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_GITHUB_ACTIONS_ROLE }} | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_DEV }}:role/${{ vars.AWS_GITHUB_ACTIONS_ROLE_DEV }} | ||
aws-region: ${{ env.AWS_REGION }} | ||
|
||
- name: Login to Amazon ECR | ||
id: login-ecr | ||
uses: aws-actions/amazon-ecr-login@v2 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
with: | ||
platforms: ${{ env.DOCKER_PLATFORM }} | ||
|
||
- name: Set environment | ||
uses: SpicyPizza/[email protected] | ||
with: | ||
envkey_VITE_APP_NAME: "${{ vars.VITE_APP_NAME }}" | ||
envkey_VITE_SENTRY_DSN: "${{ vars.VITE_SENTRY_DSN }}" | ||
envkey_VITE_SENTRY_ENVIRONMENT: "${{ vars.VITE_SENTRY_ENVIRONMENT }}" | ||
envkey_VITE_API_URL: "${{ vars.VITE_API_URL }}" | ||
envkey_VITE_APP_ENV: "${{ vars.VITE_APP_ENV }}" | ||
envkey_VITE_APP_URL: "${{ vars.VITE_APP_URL }}" | ||
|
||
file_name: .env | ||
|
||
- name: Build and push | ||
id: build-image | ||
env: | ||
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} | ||
- name: Build and push image | ||
uses: docker/build-push-action@v6 | ||
with: | ||
context: . | ||
file: ./.docker/Dockerfile | ||
target: ${{ matrix.service }} | ||
push: true | ||
platforms: ${{ env.DOCKER_PLATFORM }} | ||
tags: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} | ||
file: ./deployment/image/Dockerfile | ||
|
||
deploy: | ||
needs: setup | ||
runs-on: ubuntu-latest | ||
# environment: dev # Works only on paid GH orgs | ||
strategy: | ||
matrix: | ||
service: [app] | ||
steps: | ||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_GITHUB_ACTIONS_ROLE }} | ||
aws-region: ${{ env.AWS_REGION }} | ||
tags: ${{ env.REGISTRY_URL }}/${{ env.ECR_REPOSITORY_BASE }}-${{ matrix.service }}:${{ env.IMAGE_TAG }} | ||
cache-from: type=gha | ||
cache-to: type=gha,mode=max | ||
|
||
- name: Download task def | ||
- name: Download task definition | ||
run: | | ||
aws ecs describe-task-definition --task-definition ${{ matrix.service }}_task_definition_${{ env.ECR_REPOSITORY }} --query taskDefinition > task-definition.json | ||
aws ecs describe-task-definition --task-definition app_task_definition_${{ env.ECR_REPOSITORY_BASE }}-${{ matrix.service }} --query taskDefinition > task-definition.json | ||
|
||
- name: Fill in the new image ID in the Amazon ECS task definition | ||
- name: Fill in new image ID in task definition | ||
id: task-def | ||
uses: aws-actions/amazon-ecs-render-task-definition@v1 | ||
with: | ||
task-definition: task-definition.json | ||
container-name: ${{ env.CONTAINER_NAME }} | ||
image: ${{ env.REGISTRY_URL }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }} | ||
container-name: sensifai | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||
image: ${{ env.REGISTRY_URL }}/${{ env.ECR_REPOSITORY_BASE }}-${{ matrix.service }}:${{ env.IMAGE_TAG }} | ||
|
||
- name: Deploy Amazon ECS task definition | ||
uses: aws-actions/amazon-ecs-deploy-task-definition@v2 | ||
with: | ||
task-definition: ${{ steps.task-def.outputs.task-definition }} | ||
service: ${{ matrix.service }}_service_${{ env.ECR_REPOSITORY }} | ||
service: app_service_${{ env.ECR_REPOSITORY_BASE }}-${{ matrix.service }} | ||
cluster: ${{ env.ECS_CLUSTER }} | ||
wait-for-service-stability: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not work due to the sleep not taking into account the duration of the schedule run, also, error handling is missing. Either run
cron -f
as exec argument for the container with a new crontab, or haveschedule:run
as the exec of the container and run a new instance of the container every 60 seconds via ecs native schedulerhttps://laravel.com/docs/12.x/scheduling#running-the-scheduler
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/scheduling_tasks.html