{"id":19156001,"url":"https://github.com/markkimsal/laravel-docker-platform","last_synced_at":"2026-04-21T05:34:09.577Z","repository":{"id":66691787,"uuid":"480371144","full_name":"markkimsal/laravel-docker-platform","owner":"markkimsal","description":"docker container for laravel and php projects","archived":false,"fork":false,"pushed_at":"2025-02-01T13:11:28.000Z","size":94,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-15T05:54:00.561Z","etag":null,"topics":["docker","horizon","laravel","nginx","php-fpm"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markkimsal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-11T12:31:15.000Z","updated_at":"2025-02-01T13:11:32.000Z","dependencies_parsed_at":"2024-06-01T18:16:24.113Z","dependency_job_id":"c6ece61e-8159-4f37-8d25-68a402102382","html_url":"https://github.com/markkimsal/laravel-docker-platform","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markkimsal%2Flaravel-docker-platform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markkimsal%2Flaravel-docker-platform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markkimsal%2Flaravel-docker-platform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markkimsal%2Flaravel-docker-platform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markkimsal","download_url":"https://codeload.github.com/markkimsal/laravel-docker-platform/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240241799,"owners_count":19770463,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","horizon","laravel","nginx","php-fpm"],"created_at":"2024-11-09T08:32:56.497Z","updated_at":"2026-04-21T05:34:04.546Z","avatar_url":"https://github.com/markkimsal.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# laravel-docker-platform\nDocker container for Laravel and PHP projects.  Graceful shutdown.  No-python supervisor. No-SSH.\n\n# Customizing\nYou can add your own one-time, start up scripts to `/platform/start-container.d/`\n\nIf any script in `start-container.d` exists with a return code other than 0, the\ncontainer will fail to start.\n\nYou can change any PHP ini by bind mounting a file to `/usr/local/etc/php-fpm.d/` or\nusing your container orchestrator's config file functionality.\n\n# Available run-time environment variables\n\n  * LARAVEL_WORK_DIR  (defaults to /app)\n  * LARAVEL_HORIZON_WORK_DIR (defaults to /app)\n  * LARAVEL_QUEUE_WORK_DIR (defaults to /app)\n  * LARAVEL_MIGRATE_COMMAND  (defaults to \"/usr/local/bin/php artisan migrate --force\")\n  * LARAVEL_SCHEDULER_COMMAND (defaults to \"/usr/local/bin/php artisan schedule:run\")\n  * ENABLE_MIGRATIONS\n  * ENABLE_CONFIG_CACHE\n  * ENABLE_CHANGE_OWNER\n  * ENABLE_ARTISAN_SCHEDULER  (creates /etc/cron.d/laravel-artisan-schedule-run)\n\n# Config cache\nOne of the start-up scripts will cache the config with artisan.  You can enable\nthis step by setting the environment variable\n`ENABLE_CONFIG_CACHE` to any value.\n\n# Running queue:work as a standalone container\nThe script `/platform/start-queue` can be used to start artisan `queue:work`\n\nset `LARAVEL_QUEUE_WORK_COMMAND` with your desired_commands\n\n```\n---\nversion: '3.7'\n\nservices:\n  laravel:\n    image:  your-docker-repo/your-app-name:latest-prod\n  queue:\n    image:  markkimsal/php-platform:8.0-nginx-fpm\n    entrypoint: /platform/start-queue\n\n    environment:\n      LARAVEL_QUEUE_WORK_DIR: /app\n      LARAVEL_QUEUE_WORK_COMMAND: /usr/local/bin/php artisan queue:work default --tries=1 --sleep=3\n```\n\n\n# Running horizon as a standalone container\n\nThe script `/platform/start-horizon` can be used to call only artisan:horizon and no other processes.\nYou can deploy the same built app container with 2 different `command` values to get 2 different\ncontainer behaviors.\n\n```\n---\nversion: '3.7'\nnetworks:\n  traefik_ingress:\n    external: true\n\nservices:\n  laravel:\n    image:  your-docker-repo/your-app-name:latest-prod\n    networks:\n      - 'traefik_ingress'\n\n    deploy:\n      endpoint_mode: dnsrr\n      mode: replicated\n      replicas: 3\n      labels:\n        - \"traefik.enable=true\"\n        - \"traefik.docker.network=traefik_ingress\"\n        - \"traefik.http.routers.laraveltest.rule=Host(`app.localhost.test`)\"\n        - \"traefik.http.routers.laraveltest.entrypoints=websecure\"\n        - \"traefik.http.routers.laraveltest.tls=true\"\n        - \"traefik.http.routers.laraveltest.tls.certresolver=myresolver\"\n        - \"traefik.http.routers.laraveltest.service=laraveltest\"\n        - \"traefik.http.services.laraveltest.loadbalancer.server.port=8080\"\n\n  horizon:\n    image:  your-docker-repo/your-app-name:latest-prod\n    entrypoint: /platform/start-horizon\n\n    deploy:\n      endpoint_mode: dnsrr\n      mode: replicated\n      replicas: 2\n    environment:\n      LARAVEL_HORIZON_WORK_DIR: /app\n```\n\n# Running horizon as supervised service\nIf you want to run horizon under the supervisor `runit` you can add an environment variable `START_HORIZON_AS_SERVICE=yes` to your docker container by any means.\n\n\n# Running artisan schedule:run as a standalone container\nThe entrypoint `/platform/start-cron` can be used to run cron, with `ENABLE_ARTISAN_SCHEDULER` environment variable\nyou can run `artisan schedule:run` every minute.\n\n```\n---\nversion: '3.7'\n\nservices:\n  scheduler:\n    image:  your-docker-repo/your-app-name:latest-prod\n    entrypoint: /platform/start-queue\n\n    environment:\n      ENABLE_ARTISAN_SCHEDULER: 1\n```\n\n\n# WWWUID and WWWGID\nYou can change the id of the `www-data` user to match any owner of files on your production system.\n\nOn your local development system, you can set WWWUID and WWWGID to 1000 so there are no ownership\nproblems between your code and the running www-data user.  (Note, this is only an issue on Gnu/Linux)\n\nSet WWWUID and WWWGID like this:\n\n```\n---\nversion: '3.7'\n\nservices:\n  queue:\n    image:  markkimsal/php-platform:8.0-nginx-fpm\n    command: /platform/start-queue\n\n    environment:\n      LARAVEL_QUEUE_WORK_DIR: /app\n      LARAVEL_QUEUE_WORK_COMMAND: /usr/local/bin/php artisan queue:work default --tries=1 --sleep=3\n      WWWUID: '${WWWUID:-33}'\n      WWWGID: '${WWWGID:-33}'\n```\n\n# PHP Extensions\nI found that each extension barely takes up any more disk space or memory.  If you don't want them, attach blank files\nto the container ini files when you deploy.\n\n\n|PHP Version - flavor |  7.3-nginx-fpm |  7.3-tools | 7.4-nginx-fpm | 7.4-tools | 8.0-nginx-fpm | 8.0-tools | 8.1-nginx-fpm | 8.1-tools |\n|---------------------|----------|-----------------|-----|-----|-----|-----|---|----|\n| BCMATH               | X |  X | X | X | X |  X | X | X |\n| Intl                 | X |  X | X | X | X |  X | X | X |\n| gd                   | X |  X | X | X | X |  X | X | X |\n| mysql                | X |  X | X | X | X |  X | X | X |\n| pgsql                | X |  X | X | X | X |  X | X | X |\n| sqlite3              | X |  X | X | X | X |  X | X | X |\n| readline             | X |  X | X | X | X |  X | X | X |\n| memcached (igbinary) | X |  X | X | X | X |  X | X | X |\n| redis                | X |  X | X | X | X |  X | X | X |\n| xdebug               | X |  X | X | X | X |  X | X | X |\n| zip                  | X |  X | X | X | X |  X | X | X |\n| SOAP                 | X |  X | X | X | X |  X | X | X |\n| SSH2                 | X |  X | X | X | X |  X | X | X |\n| pcntl                | X |  X | X | X | X |  X | X | X |\n| sysvsem              | X |  X | X | X | X |  X | X | X |\n| sysvshm              | X |  X | X | X | X |  X | X | X |\n| sysvmsg              | X |  X | X | X | X |  X | X | X |\n| lib sodium           | X |  X | X | X | X |  X | X | X |\n| FFI                  |   |    | X | X | X |  X | X | X |\n| nginx                | X |  X | X | X | X |  X | X | X |\n| yarn                 |   |  X |   | X |   |  X |   |   |\n| nodejs-15.x          |   |  X |   | X |   |  X |   |   |\n| composer2            |   |  X |   | X |   |  X |   | X |\n| composer1.10         |   |  X |   | X |   |  X |   | X |\n| deployer - 6         |   |  X |   | X |   |  X |   | X |\n| deployer - 7         |   |    |   |   |   |    |   | X |\n| altax                |   |  X |   | X |   |  X |   |   |\n| git                  |   |  X |   | X |   |  X |   | X |\n| jq                   |   |  X |   | X |   |  X |   | X |\n| unzip                |   |  X |   | X |   |  X |   | X |\n| openssh              |   |  X |   | X |   |  X |   | X |\n\n\n# Tools images\nHaving an image that can also run tests and build your image as part of your CI pipeline is useful.  I could not find an\nimage of nodejs that also had git, and at least one of my node dependencies required git to install so... here we are with\nnodejs 15 baked into this image.\n\nSometimes composer complains when you don't have a host OS `unzip` program, so that's been added to the tools variant.\n\nAlso, for deploying with PHP deployer, I found that having ssh, unzip, git are usefull or required.\n\nI used to use `altax` for remote deployment so that's also on there.\n\nI can't find an image on google cloud build that has `jq`, so I installed `jq` as well.\n\n\n# Supervisor runit\nRunit is a small, c process supervisor.  It tries to restart failed processes until you tell it to stop.  The problem with runit\nis that you cannot send a signal that will gracefully stop all managed services.  You must stop all services \"by-hand\", which is \nweird.  You'd think that a simple SIGSTOP could initiate a graceful shutdown, but there's no way to do this.  Runit (or runsv or runsvdir) will\nrespond to TERM signals mostly by dieing immediately and letting children float to PID 1 and get reaped.\n\nThere is a small bash file that - in combination with `dumb-init` - will act as pid 1, take `docker stop` SIGQUIT or SIGTERM and gracefully try\nto shutdown the running services.  This is essentially what the `/sbin/my_init` program from phusion/baseimage does.\n\n\n# Contributing and building your own images\n\nUpdate the all Dockerfiles\n```\nphp ./make-versions.php\n```\n\nBuild a single image images with\n```\nbash ./build-image.sh 8.0\n```\n\nIf you are on a Mac M1 (or other ARM environments)\n\n```\nexport DOCKER_DEFAULT_PLATFORM=linux/arm64\nbash ./build-image.sh 8.0\n```\n\nI think for RaspberryPi it might be\n\n```\nexport DOCKER_DEFAULT_PLATFORM=linux/arm/v7\nbash ./build-image.sh 8.0\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkkimsal%2Flaravel-docker-platform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkkimsal%2Flaravel-docker-platform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkkimsal%2Flaravel-docker-platform/lists"}