<!--
  canonical-url: https://www.avonture.be/blog/docker-init-php-apache
  published:     2025-01-05
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# Using Docker init to quickly dockerize your PHP application

> Quickly dockerize your PHP application with Apache using the docker init command. This wizard-based tool generates the necessary Docker files and shows secure database integration.

---
![Using Docker init to quickly dockerize your PHP application](/img/v2/docker_init.webp)

**TL;DR**

Learn how to quickly dockerize an existing PHP and Apache application using the `docker init` command. This guide walks you through the interactive wizard that automatically generates your `Dockerfile`, `compose.yaml`, and `.dockerignore` files. It demonstrates the process with a sample PHP script, shows how to run the newly containerized application, and explains the purpose of each generated file. The article also provides a tip on how to extend the configuration to securely add a database service using Docker Secrets.

How about asking Docker to create the files it needs itself?

If you're a regular reader of this blog, you'll know by now that you need a `Dockerfile` to describe how the Docker image should be created and what should be included in it, and very often you'll also need a `compose.yaml` file to explain how the container should be created, e.g. which port to map to, which volumes to use, and so on.

Imagine you've an existing PHP application and you don't want to create the files needed for the dockerization by hand.

You just want, very quickly and using a wizard, to be able to answer a few questions and hop, it's ready.

The `docker init` command is the one you're looking for. *I had already given it a first try, back when PHP support had just landed, in [Docker init now supports PHP](/blog/docker-init); this article revisits it on a real application.*

## Get some scripts

As an illustration, I'll use my [aeSecure - QuickScan - Free viruses scanner](/blog/aesecure-quickscan) project already introduced in my blog.

This is a Web application that scans files (a local website) for patterns that might indicate the presence of a virus.

So, to run aeSecure QuickScan, we need PHP and Apache.

Let's play...

First, we'll create a temporary folder and grab a copy of the script:

```bash
$ mkdir -p /tmp/aesecure_quickscan && cd $_
$ curl https://raw.githubusercontent.com/cavo789/aesecure_quickscan/master/aesecure_quickscan.php -o index.php
```

You've now a local version of the script. It's a single `index.php` script; nothing more at this stage.

## Docker init

Just start `docker init` in the console:

![Starting docker init](./images/docker_init.webp)

As we can see, Docker init has already detected the presence of a PHP file so it's suggesting **PHP with Apache**. Great, just press `Enter`.

The next question will be about the version of PHP, type the one you wish (f.i. `8.2`) and press `Enter`.

The third question will be about the relative path to use for the project. In our case, our PHP script is located in the root folder of our project (not in f.i.`/app`) so just press `Enter`.

Now, you'll need to specify which port should be used for the application, I'll use the port 8080 but you can use the one you wish (as soon as not yet used).

And that's it.

![Docker init has created our files](./images/docker_init_done.webp)

It's too simple, isn't it? Let's try the suggested commands and see if the site actually works.

First, create the container by running the `docker compose up --build` command then, once finished, just open your browser and surf to your local site (in my case `http://localhost:`8080) and ...

> Screenshot — http\://localhost:8080
>
> The application is running

## Let's take a look on created files

### .dockerignore

The `.dockerignore` file specifies files and directories that should be excluded from Docker builds. So, when creating a Docker image you certainly don't want, for instance, the `.git` folder to be copied into the image. That folder (and many others) should stay on the computer.

By opening that file with a code editor, you'll then see that line:

**.dockerignore**

```
**/.git
```

Refer to <https://docs.docker.com/go/build-context-dockerignore/> for more explanations.

### compose.yaml

> **Note:**
>
> Previously, the file was named `docker-compose.yaml` (or `docker-compose.yml`).

The file will teach Docker how to make more than one container work together, f.i. our PHP application and a database service.

By opening the file, you'll see that right now, the only un-commented lines are those:

**compose.yaml**

```yaml
services:
  server:
    build:
      context: .
    ports:
      - 8080:80
```

The rest is just for illustration.

Refer to <https://docs.docker.com/go/compose-spec-reference/> for more explanation.

### Dockerfile

There are a lot of commented lines, if we look at un-commented ones, we can see this:

**Dockerfile**

```docker
FROM php:8.2-apache

COPY . /var/www/html

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

USER www-data
```

So, we'll use the PHP 8.2 Docker image shipped with apache in it (one image with both PHP and Apache).

We'll copy all files from our project (remember, our project is stored in folder `/tmp/aesecure_quickscan`) into the `/var/www/html` folder of the image. All files? No, that's incorrect. Remember the `.dockerignore` file: we'll copy all files that are not mentioned in `.dockerignore`.

Docker also takes care of renaming the standard `php.ini-production` file to `php.ini`.

The last command is to switch to the `www-data` user (so the container will not be running as `root`).

Refer to <https://docs.docker.com/go/dockerfile-reference/> for more explanation.

### README.Docker.md

As a reminder of how to use your dockerized application, this file will give you the essential commands to run.

## Generated files are yours

The generated files won't be modified by Docker while you'll not run `docker init` again. This means you can make any changes you like to the files, but your changes won't be lost. It's a great way to quickly dockerize an application.

The example given in this blog post is a stand-alone project so `docker init` does all the magic. Assuming we'd needed a database, all we have to do is return to the `compose.yaml` file and un-comment the lines like below:

**compose.yaml**

```yaml
services:
  server:
    build:
      context: .
    ports:
      - 8080:80
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt
```

> **Docker secrets is used here:**
>
> Hey! Did you see? Instead of hardcoding the password in the file, `docker init` has used a secret. This is smart.

> **Read my Docker secrets - Using your SSH key during the build process article if you don't know what is a secret:**

To make the example here above working, just create a folder called `db` with a file called `password.txt` there and paste your database password into it.

Of course, files generated by `docker init` are just skeletons: you can change what you want, so if you don't want to use secrets, no problem, you can hardcode the password; it's up to you.
