Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# syntax=docker/dockerfile:1

FROM php:8.2-apache

WORKDIR /var/www/html

# Install Composer by copying its binary from the official composer image
COPY --from=composer:lts /usr/bin/composer /usr/bin/composer

# Copy dependency manifests first so Docker can cache this layer
# (only re-runs composer install if these files change)
COPY composer.json composer.lock ./

# Install PHP dependencies (production only, no dev packages)
RUN composer install --no-dev --no-interaction --optimize-autoloader

# Use production php.ini defaults
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Copy the rest of the application source
COPY ./src /var/www/html

# Make sure the web server user owns the files
RUN chown -R www-data:www-data /var/www/html

USER www-data
105 changes: 103 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,104 @@
# docker-php-sample
# Docker PHP Sample

A simple PHP web application example for [Docker's PHP Language Guide](https://docs.docker.com/language/php/).
A simple PHP application containerized with Docker, using the official
`php:8.2-apache` image. Dependencies are managed with Composer.

## Project structure

```
docker-php-sample/
├── Dockerfile # Single-stage build: PHP 8.2 + Apache + Composer deps
├── composer.json # PHP dependency manifest
├── composer.lock # Locked dependency versions
├── src/ # Application source code (web root)
├── tests/ # Test suite
└── README.md
```

## Prerequisites

- [Docker](https://docs.docker.com/get-docker/) installed and running
- Your user added to the `docker` group (or use `sudo` for Docker commands)
```bash
sudo usermod -aG docker $USER
newgrp docker
```

## Build the image

From the project root:

```bash
docker build -t php-app:latest .
```

This will:
1. Start from the `php:8.2-apache` base image
2. Copy the Composer binary in from the official `composer` image
3. Install PHP dependencies via `composer install`
4. Switch to production `php.ini` defaults
5. Copy in the application source from `src/`
6. Run the container as the non-root `www-data` user

## Run the container

```bash
docker run -d -p 9000:80 php-app:latest
```

- `-d` runs the container in the background (detached)
- `-p 9000:80` maps port `9000` on your host to port `80` inside the container

Check it's running:

```bash
docker ps
```

You should see something like:

```
PORTS
0.0.0.0:9000->80/tcp
```

## Access the app

Open in your browser:

```
http://localhost:9000/hello.php
```

Or, if running on a remote server (e.g. EC2), replace `localhost` with the
server's public IP, and make sure port `9000` is allowed in your firewall /
security group inbound rules.

## Stopping the container

```bash
docker ps # find the container ID or name
docker stop <container> # stop it
docker rm <container> # remove it (optional)
```

## Rebuilding after code changes

Any time you change `src/`, `composer.json`, or the `Dockerfile` itself,
rebuild the image and restart the container:

```bash
docker build -t php-app:latest .
docker stop <container> && docker rm <container>
docker run -d -p 9000:80 php-app:latest
```

## Notes

- This Dockerfile is **single-stage** (no multi-stage build), so the final
image includes Composer and its cache — larger than a multi-stage build,
but simpler to read and doesn't require BuildKit.
- If you see `the --mount option requires BuildKit`, that means a
Dockerfile is using BuildKit-only syntax (`RUN --mount=...`). Either
enable BuildKit (`DOCKER_BUILDKIT=1 docker build ...`) or use the
single-stage Dockerfile in this repo, which avoids that syntax entirely.
47 changes: 0 additions & 47 deletions src/database.php

This file was deleted.