Docker lamp php 8

LAMP Docker setup with PHP 8 and MariaDB for Symfony projects

Yet another one?! Well, either my searching skills are getting rusty or my request was too specific while at the same time being pretty basic, or something would crash and break during the build process after following available online tutorials or downloading existing projects. but I couldn’t find a single solution which I could reuse for my exact needs with just a couple of changes in the configuration.
I had to come up with my own, which is the result of bits and pieces taken from those that didn’t fully work for me, as well as some knowledge and understanding of Docker I gained along the way. I’d like to share it; maybe it will be useful for someone else in this very format. I’ve decided to use Docker for my local development because different projects I’m working on require different versions of PHP, NodeJS and even different versions of Composer. and switching/upgrading/downgrading those versions whenever I switched my focus on another project became cumbersome.
Docker can be really slow, but listing pros and cons of Docker is not the topic here. I don’t intend to get into the details of each line of code and explain all used commands. What I can do is encourage you into having a look at this great «Docker for local web development» series where you can learn much more. This was my main resource as well.

Читайте также:  Как создавать файлы зависимостей python

Let’s get started

All my new projects will be using PHP 8 because of some great features I’d like to exploit which were not there prior to version 8. I think it’s worth using the latest versions when starting fresh, so that’s the stack I’m dealing with. Symfony 5.2 includes support for PHP 8 attributes to define routes and required dependencies, and that’s one more argument in favour of it. I’ll also use Apache for server and MariaDB for database.
On top of my Symfony project, I’ll add PhpMyAdmin to save me some trouble when manually dealing with DB stuff. I intend to have multiple projects locally with this exact stack, so I had to come up with something simple enough and reusable to get me started quick, but something I can build on top of and extend when necessary. Prerequisites are installed Docker and Docker Compose (which, depending on your platform, might be a part of the Docker installation). If you’re using Windows, make sure you have the WSL2 feature enabled.

Folder structure overview

. ├── codebase/ ├── docker/ │ ├── db/ │ │ └── mariadb/ │ │ └── my.cnf │ └── server/ │ ├── apache/ │ │ └── sites-enabled/ │ │ └── site.conf │ ├── php/ │ │ └── php.ini │ └── Dockerfile ├── .env └── docker-compose.yml 

All folder names are arbitrary. Make sure, if you’re going to rename them, to rename them accordingly in the configurations. codebase folder will hold all our project code. Since this will be a Symfony app, we will have public folder with index.php file within it and that’s what we’ll rely on throughout the setup. For starters, codebase folder is empty. In .env file, we’ll have project-level Docker environment variables. As a part of this guide, I will not configure local machine’s hosts file to make site access more user friendly, but will access it over localhost:[PORT]. You must make sure that the port is not occupied already and map available ports from your local machine to container’s port 80 . In the same manner, I’ll map a port for PhpMyAdmin. Stick with some convention and be consistent.
E.G. use ports 8101 and 8102 for project A, 8103 and 8104 for project B and so on.
The same applies for DB port. You might already have default port 3306 occupied on your local machine.
I’m using APP_NAME variable to avoid some extra copy-pasting in the configurations, but that’s completely up to you.
MYSQL_* config variables are pretty self-explanatory. Here’s what my .env file looks like:

APP_NAME=symfony_project_2021 APP_PORT=8101 APP_DB_ADMIN_PORT=8102 DB_PORT=33016 MYSQL_ROOT_PASS=superSecr3t MYSQL_USER=app_user MYSQL_PASS=t3rceS MYSQL_DB=symfony_project_2021 

Docker Compose

version: '3.9' networks: symfony_project_2021_net: services: server: build: context: . dockerfile: ./docker/server/Dockerfile container_name: '$-server' ports: - '$:80' working_dir: /var/www/html environment: - 'DATABASE_URL=mysql://$:$@db_server:3306/$?serverVersion=10.5' volumes: - ./codebase:/var/www/html - ./docker/server/apache/sites-enabled:/etc/apache2/sites-enabled - ./docker/server/php/php.ini:/usr/local/etc/php/conf.d/extra-php-config.ini depends_on: db_server: condition: service_healthy networks: - symfony_project_2021_net db_server: image: mariadb:10.5.9 container_name: '$-db' restart: always ports: - '$:3306' environment: MYSQL_ROOT_PASSWORD: '$' MYSQL_USER: '$' MYSQL_PASSWORD: '$' MYSQL_DATABASE: '$' volumes: - db_data:/var/lib/mysql - ./docker/db/mariadb/my.cnf:/etc/mysql/conf.d/my.cnf healthcheck: test: mysqladmin ping -h 127.0.0.1 -u root --password=$$MYSQL_ROOT_PASSWORD interval: 5s retries: 5 networks: - symfony_project_2021_net db_admin: image: phpmyadmin/phpmyadmin:5 container_name: '$-db-admin' ports: - '$:80' environment: PMA_HOST: db_server depends_on: db_server: condition: service_healthy volumes: - db_admin_data:/var/www/html networks: - symfony_project_2021_net volumes: db_data: db_admin_data: 

We’ll use official Docker images for building db_server and db_admin containers. You can find the official (and many other) container images on Docker Hub.

Читайте также:  Google apps java sdk

Server

We’ll use our own Dockerfile to specify what the server image looks like.
Content of /docker/server/Dockerfile :

FROM php:8.0-apache RUN a2enmod rewrite RUN apt-get update && apt-get install -y git unzip zip WORKDIR /var/www/html COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ RUN install-php-extensions gd pdo_mysql bcmath zip intl opcache COPY --from=composer:2.0 /usr/bin/composer /usr/local/bin/composer 

Docker PHP extension installer script will install all the required APT/APK packages. At the end of the script execution, packages that are no longer needed will be removed, so the image will be much smaller.
Using docker-php-ext-install didn’t always work for me, so I’m pulling this extra script. You can expand the list of extensions to install, if necessary.
After that, we’ll also pull the Composer. What do you think about setting up a separate container for Composer?

Content of our local folder codebase will be considered a volume mapped to /var/www/html , which is the project root.

Apache

Site is defined on Apache side, in docker/server/apache/sites-enabled/site.conf :

 DocumentRoot /var/www/html/public AllowOverride None Order Allow,Deny Allow from All Options -MultiViews RewriteEngine On RewriteCond % !-f RewriteRule ^(.*)$ index.php [QSA,L]   

Again, this is Symfony-specific (something very similar would be used for Laravel projects as well).

Configurations

Finally, there are some extra configurations for PHP and MariaDB in /docker/server/php/php.ini and /docker/db/mariadb/my.cnf , respectively.
You can configure and overwrite defaults in those files if necessary.

upload_max_filesize = 30M post_max_size = 80M short_open_tag = Off memory_limit = 256M 
[mysqld] collation-server = utf8mb4_unicode_ci character-set-server = utf8mb4 

We’ll use named volumes to persist data. We need such volumes because without them, every time the DB service container is destroyed the database is destroyed with it. This is what that final section in docker-compose.yml is for. Volumes are referenced in db_server and db_admin services.

Order in which containers are started is important and that’s what we’ve set with depends_on .

Alt Text

Specifying environment server variables is also completely up to you; you’re free to use another .env file in the Symfony project root folder. DATABASE_URL variable is Symfony-specific, and if you display it on the server, you should get

Variables defined like this will have precedence over those defined in .env files (in Symfony project root folder).
You can do the same thing for Laravel project.

Ready, set, .

In your terminal, run docker-compose up -d —build to start the containers. The process will take some time, but only the first time you’re building containers.

After this is done, check your containers by running docker-compose ps in the terminal.
Running containers
Also, in Docker Desktop app you should see:
Alt Text

Everything from now on should be a walk in the park. Or that’s what I thought when following all online resources I could find 😃

Execute Bash on server container (where server is the name you’ve given to container) by running docker-compose exec server bash

We’ve set our working directory on the server to /var/www/html . While at it, run composer create-project symfony/website-skeleton . . If you prefer, you can install Symfony installer as well (add it to Dockerfile ).
This will install the Symfony project.
It’s important that you do this directly on the server because your local Composer and PHP versions might be different and you could run into compatibility issues.

Alt Text

Now check http://localhost:8101/ and http://localhost:8102/. Your site and PhpMyAdmin should be available!

Was this guide «yet another» that didn’t fully work for your local setup? What would you improve or change completely?
Which other containers do you usually use to get your projects up and running?

Источник

Оцените статью