Skip to main content

Docker init now supports PHP

Containerize your PHP application fast! This guide shows you how to use the new Docker init feature with PHP and Apache, including a walk-through of the generated Dockerfile and compose.yaml files.

· 5 min read
View raw
Christophe
Markdown, WSL and Docker lover ~ Insatiable curious.
Cet article existe aussi en français — lire la version française.

This article is over a year old but was reviewed on July 30, 2026 — the content is still accurate.

Docker init now supports PHP

⚡
TL;DR

This article tries Docker Desktop 4.26's new docker init PHP+Apache template, which scaffolds a Dockerfile, compose.yaml, and .dockerignore through an interactive wizard. It walks through a bug in that first release (the COPY instruction was missing its source path) and explains why .dockerignore keeps most local files out of the built image.

But what a happy and strange coincidence. In its new version (4.26) released yesterday (on my birthday), Docker adds support for PHP with Apache to its docker init instruction. Let's see how this translates into a practical case.

The official blog post: https://www.docker.com/blog/docker-desktop-4-26/

Caution

We'll give it a try but spoiler, it's still in a very early stage.

Please start a Linux shell and run mkdir -p /tmp/docker-init && cd $_ to create a folder called docker-init in your Linux temporary folder and jump in it.

Now, in your console, just run docker init and follow the wizard.

>user@machine: ~/yourproject

Make sure to select PHP with Apache - suitable for a PHP web application.

For the next questions:

  • What version of PHP do you want to use?, please enter f.i. 8.2,
  • What's the relative directory for your app?, just press enter to select the current directory,
  • What local port do you want to use to access your server?, just press enter to use the proposed port number or f.i. enter 8080.
>user@machine: ~/yourproject

The wizard is quite straight-forward but, then, we got four files.

Two are really important right now: compose.yaml and Dockerfile.

compose.yaml​

By opening compose.yaml with Visual Studio Code, you'll see a lot of comments.

By default, everything is commented except:

Your values for this page
default
Applies to the commands on this pageSaved on this device only
services:
server:
build:
context: .
ports:
- 8080:80

This is a Docker Compose configuration that defines a single service called 'server'. It builds a Docker image from the current directory and maps port 8080 on your machine to port 80 inside the container, so you can access the service through localhost:8080.

Ok, that just means that we'll not use a standard, pre-existing, Docker image but we'll build yours and the definition of that image is located in the current folder (context: .). The definition of your Docker image has to be written in the, standard, Dockerfile.

The second thing we see here is the port number we've chosen. The Docker container will be published on the port 8080.

Dockerfile​

Here too, docker init has created a file with a lot of comments. If we remove them, here is the non-commented lines:

FROM php:8.2-apache
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY . /var/www/html
USER www-data

This Dockerfile sets up a PHP 8.2 web server using Apache as the base image, configures PHP to use production settings, copies the application code into the web root directory, and then switches to run everything as the www-data user (the typical unprivileged user for web servers) for security.

Bug in Docker 4.26 - Docker init - PHP + Apache

There is a bug in the release 4.26, the COPY statement has to be COPY . /var/www/html (i.e. we need to specify the source folder .). I've created an issue on the Docker repository (https://github.com/docker/cli/issues/4702)

Please update the file Dockerfile and change the line COPY /var/www/html to COPY . /var/www/html

So, we can see we'll use the php:8.2-apache image (since we've asked for PHP 8.2), we'll copy the content of your current folder (.) to the /var/www/html folder inside the Docker image, we'll also use the php.ini file for production (see Update php.ini when using a Docker image if you need to tweak it) and will switch the current Linux user used inside the container to www-data.

Run the container​

Ok, nothing really difficult until now. We'll create the image by running docker compose up --build.

Once built, we can surf to http://localhost:8080 and ... ouch.

http://localhost:8080

Forbidden

And this is totally normal. Remember, your current folder only contains actually the four files created by docker init.

Please create the index.php file with this content:

<?php
phpinfo();

This is a simple PHP file that calls the phpinfo() function, which outputs a detailed report about the PHP installation and configuration on the server. This is commonly used to check what version of PHP is running, what extensions are loaded, and various server settings.

Go back to your console, press CTRL-C to stop the first container and run docker compose up --detach --build this time (so the console won't be blocked and the container stay running in background).

http://localhost:8080

phpinfo

Enter in the container​

We'll start an interactive shell in the container. We just need to know how the container is named.

Back to the compose.yaml file, we can retrieve the name of the container; it's the name of the service: server in this case.

services:
# highlight-next-line
server:
[...]

This is a YAML configuration file that defines services, with a special comment on line 2 marking that the next line (the 'server' service definition) should be highlighted, likely for documentation or UI purposes.

To run an interactive shell, please run the following command:

>user@machine: ~/yourproject

As expected, you're now inside the container. You can display the list of files by running ls -alh

>user@machine: ~/yourproject

So, even if your current folder, on your machine, contains now five files, only README.Docker.md and index.php are present. Why not the other files?

.dockerignore​

On your machine, we've thus five files:

>user@machine: ~/yourproject

And only README.Docker.md and index.php have been copied into the container.

The reason is: the other files have been ignored because they have been mentioned in the .dockerignore file.

# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/
**/.classpath
//highlight-next-line
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
//highlight-next-line
**/compose*
!**/composer.json
!**/composer.lock
//highlight-next-line
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/vendor
LICENSE
README.md

This is a .dockerignore file that tells Docker which files and directories to exclude when building a container image. It's similar to .gitignore but for Docker—anything listed here won't be copied into the container, keeping the image smaller and faster to build. The file excludes common development artifacts, IDE settings, dependencies, and configuration files that aren't needed in production.

We have reached the end of this article. We've used the docker init instruction to create the bare essentials needed to run a PHP script in an Apache container.

If all you need is to run a script quickly, without any generated file at all, The easiest way to run a PHP script / website is a one-liner.

In the next months, I'll keep an eye on how docker init will evolve concerning PHP.


Was this article helpful?
Did you try the steps in this article?