stackinstance/docker-centos
stackinstance/docker-centos provides a Dockerized CentOS environment for StackInstance projects, offering PHP teams a reproducible, ready-to-use container setup with simplified configuration, consistent runtime behavior, and smoother local development or deployment workflows. It helps standardize te...
stackinstance/docker-centos is not a Composer package — there is nothing to composer require. It is a Docker base-image repository (a CentOS-based Dockerfile) intended to be used as a foundation for PHP/Laravel application containers. Treat it as infrastructure, not a library.
First steps:
FROM line (which CentOS tag — centos:7 is EOL, and that matters enormously for your PHP version options), the installed PHP version, the extension list, and whether it ends with CMD ["php-fpm"], CMD ["httpd", "-DFOREGROUND"], or something else. Your entire integration strategy depends on that final command.git clone https://github.com/stackinstance/docker-centos
cd docker-centos
docker build -t stackinstance/centos:local .
docker run --rm -it stackinstance/centos:local sh -c 'cat /etc/os-release; php -v; php -m'
Confirm PHP is present at all, confirm the extension list includes pdo_mysql, mbstring, openssl, tokenizer, xml, ctype, json, bcmath, fileinfo — the standard Laravel requirements. Missing any of these is a blocker you should discover in minute one, not day three.php-fpm service in a docker-compose.yml, with your Laravel app bind-mounted at /var/www/html (or wherever the image's WORKDIR points — check the Dockerfile). Pair it with a stock nginx service and a mysql:8 service.If step 3 reveals a CentOS 7 base with PHP 7.x, decide immediately whether that is acceptable for your project. For a new Laravel 10/11 app it is not, and you should be looking at the official php:8.x-fpm images or serversideup/php instead. This package is best treated as a starting point to fork and modernize, not a dependency to consume.
Pattern 1 — Extend, don't consume. The dominant pattern for a base image this small is a thin project-level Dockerfile:
FROM stackinstance/centos:local
# App-specific extensions the base doesn't ship
RUN yum install -y php-gd php-intl && yum clean all
WORKDIR /var/www/html
COPY --chown=apache:apache . .
RUN composer install --no-dev --optimize-autoloader
Pin the base to a digest (FROM stackinstance/centos@sha256:...) once you have a working build. With zero stars and zero dependents there is no upstream stability guarantee, and digest pinning is your only protection against a silent rebuild breaking production.
Pattern 2 — Composer multi-stage split. The base likely includes build tooling. Split vendor installation into a builder stage and copy only artifacts into the runtime stage so your final image isn't carrying gcc and yum caches:
FROM stackinstance/centos:local AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
FROM stackinstance/centos:local
WORKDIR /var/www/html
COPY --from=vendor /app/vendor ./vendor
COPY . .
RUN composer dump-autoload --optimize
Pattern 3 — Compose topology. Standard three-service layout with the CentOS image as app:
services:
app:
build: .
volumes: ["./:/var/www/html"]
depends_on: [db, redis]
web:
image: nginx:alpine
ports: ["8080:80"]
volumes: ["./:/var/www/html", "./docker/nginx.conf:/etc/nginx/conf.d/default.conf"]
db:
image: mysql:8
environment:
MYSQL_DATABASE: app
MYSQL_ROOT_PASSWORD: secret
Two things bite here: the nginx root must match the WORKDIR in the Dockerfile exactly, and fastcgi_pass must point at the service name and port the image's PHP-FPM actually listens on (verify with docker exec app ss -tlnp — CentOS 7 images sometimes use netcat-less minimal builds, so fall back to ps aux | grep php-fpm).
Pattern 4 — CI parity. Use the same image in GitHub Actions so your pipeline matches local dev:
jobs:
test:
runs-on: ubuntu-latest
container: stackinstance/centos:local
steps:
- uses: actions/checkout@v4
- run: composer install
- run: php artisan test
This is where a CentOS base earns its keep — if production is CentOS, CI on the same base catches extension and locale differences that ubuntu-latest silently hides. Locale is a common Laravel landmine: setlocale() and strftime-adjacent formatting behave differently, so ensure en_US.UTF-8 is generated in the image (localedef -i en_US -f UTF-8 en_US.UTF-8).
Pattern 5 — Artisan and queue workers. Derive a second image or override command for queue:work and schedule:run:
worker:
build: .
command: php artisan queue:work --tries=3 --timeout=90
restart: unless-stopped
Because both share the base image, opcache settings and PHP ini values stay consistent between web and worker — a frequent source of "works in the request, fails in the job" bugs.
CentOS 7 EOL is the headline risk. If the image is centos:7, its yum mirrors were retired (mid-2024) and yum install will fail against default repos. You will need the vault rewrite:
RUN sed -i 's/mirrorlist/#mirrorlist/g; s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' \
/etc/yum.repos.d/CentOS-*.repo
Without this, your first docker build extension install fails with a wall of 404s. This is the single most likely reason a developer abandons this package in the first ten minutes.
Do not assume php exists. "Docker Centos" in the name does not guarantee PHP was baked in — many such repos are intentionally bare OS bases meant to be composed with other Stack Instance images. Run the smoke test above before writing any Laravel config.
Repo health is a real signal here. Zero stars and zero dependents means no one is filing issues, so bugs stay unfixed and undocumented. There is no security patching cadence. For anything production-facing, fork it into your org, own the Dockerfile, and set up Dependabot or a scheduled rebuild so you at least see when base layers rot.
Permission mismatches between host and container. CentOS images typically run as apache (uid 48) or root. On Linux hosts with a bind mount, storage/ and bootstrap/cache will throw permission-denied writes. Either chown inside an entrypoint, or pass a build arg mapping the container uid to your local uid:
ARG UID=1000
RUN useradd -u ${UID} -m app && chown -R app:app /var/www/html
USER app
docker compose exec app id is your fastest diagnostic.
PHP-FPM daemonization. Some minimal images start php-fpm with --nodaemonize missing, causing the container to exit immediately with no logs. If docker compose up shows the app container "Exited (0)", check the CMD/ENTRYPOINT and override with command: php-fpm -F in Compose.
SELinux on the host. On CentOS/RHEL/Fedora hosts, bind mounts need the :z or :Z volume suffix or nginx gets 403 on every request. Easy to overlook if you developed on Ubuntu and moved to a CentOS workstation.
Extension installation is where builds get slow. Every yum install layer without yum clean all && rm -rf /var/cache/yum bloats the image by hundreds of MB. Combine installs into one RUN, clean in the same layer, and use .dockerignore to keep vendor/ and node_modules/ out of the build context — with a CentOS base the context upload is often slower than the build itself.
No healthcheck by default. Add one so Compose depends_on ordering is meaningful rather than a race:
HEALTHCHECK --interval=10s --retries=5 \
CMD php-fpm-healthcheck || exit 1
Or the dependency-free version: CMD cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1.
The honest recommendation. Use this package to learn how a CentOS-based PHP image is assembled, then fork it, pin every version, add a healthcheck and a non-root user, and put it behind your own registry. The absence of stars isn't a verdict on quality — it's a statement that nobody is maintaining it for you. Treat the Dockerfile as a template you now own.
How can I help you explore Laravel packages today?