Foundation for a php project with composer support and SSL encryption. E. g. useful for Symfony or Zend applications.
Table of contents
- Composer usage
- Initialize new skeletons for popular frameworks
- Start and exit the application
- Sending Commands
- PHP extensions
- Nginx Webserver
- MariaDB Server (MySQL)
- Symfony
- Zend
- Notes
The composer.sh
script in the project root is a wrapper for running composer within the /www
subdirectory.
Simply call the script with any flags/parameters you would give the usual composer command and they will be handed over.
E. g. to show the current used composer version, append the --version
flag.
./bin/composer.sh --version
Run the composer.sh
wrapper script with the update
parameter to update your modules and dependencies to
the highest allowed version according to the semver definitions in /www/composer.json
.
./bin/composer.sh update
This will ignore the exact specified versions in /www/composer.lock
and update them afterwards with the new installed versions.
Run the composer.sh
wrapper script with the install
parameter to install your modules and dependencies with
the exact version given in /www/composer.lock
.
./bin/composer.sh install
If there isn't already an /www/composer.lock
, it will act like an update and install the highest allowed version
(within the semver definitions in /www/composer.json
) and create a .lock file afterwards.
Clear the composer cache.
./bin/composer.sh clear-cache
Create a new skeleton for a Symfony application:
./bin/composer.sh create-project symfony/skeleton ./
The skeleton doesn't provide any controllers or routes. After starting the application, you will only see a default page, showing that the basic framework is running. If you want to enable the web-profiler toolbar later, you need at least one working route.
You may want to download the annotations plugin before, which enables defining routes directly within a controller.
./bin/composer.sh require annotations
Then create a simple controller, located in /www/src/Controller/IndexController.php
, with an indexAction
and
main route "/"
.
<?php
namespace App\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
class IndexController
{
/**
* @Route("/")
*/
public function indexAction()
{
return new Response(
'<html><body>It works!</body></html>'
);
}
}
Now you shouldn't see the default page of Symfony anymore, instead there is only a simple text telling you "It works!".
Create a new skeleton for a Zend application:
./bin/composer.sh create-project --stability="dev" zendframework/skeleton-application ./
If you want to enable the developer toolbar immediately while in dev-mode, make sure to answer with n
to the first question "Do you want a minimal install (no optional packages)?" and with y
to the following question
"Would you like to install the developer toolbar?".
Then choose to inject the ZendDeveloperTools into the file config/development.config.php.dist
to keep them disabled later in production.
Most other optional enabled modules should be injected into config/modules.config.php
,
so that they are available in both environments.
Create a new skeleton for a Zend Expressive (minimalist PSR-7 middleware) application:
./bin/composer.sh create-project zendframework/zend-expressive-skeleton ./
For further information see Zend Expressive in official Zend documentation.
To run the application the first time, let docker-compose automatically set up the containers:
docker-compose up -d --build
Starting/stopping already created containers:
docker-compose stop
docker-compose start
Destroy containers and release their resources (e. g. port mappings, volumes):
# remove only containers
docker-compose down
# remove containers and their stored data
docker-compose down -v
Warning: Usage of the parameter -v removes volumes and therefore stored data within them. Don't use it, if you want to keep created and filled databases. But it can be useful for cleaning the workspace, if you want to reset some test data and recreate your structure with SQL imports or Doctrine.
Interacting with containers can be done by using the right docker
and docker-compose
commands
as well as using some useful wrapper scripts located in /bin
subdirectory.
Open a shell directly in a running php or nginx container:
docker-compose exec php /bin/ash
docker-compose exec www /bin/ash
Replace php with www and vice versa to open a shell in the php or nginx container.
Open a shell in the MariaDB container:
docker-compose exec db /bin/bash
The command.sh
wrapper script allows to execute any commands inside the php container in docker.
E. g. show the installed php version:
./bin/command.sh php --version
Run a composer diagnose and bypass the composer.sh
wrapper:
./bin/command.sh composer diagnose
Call the Symfony console and bypass the console-sf.sh
wrapper:
./bin/command.sh php ./bin/console --version
./bin/command.sh php ./bin/console list
./bin/command.sh php ./bin/console list doctrine
Call the Doctrine ORM module directly and bypass the doctrine-zf.sh
wrapper:
./bin/command.sh ./vendor/bin/doctrine-module list
./bin/command.sh ./vendor/bin/doctrine-module orm:schema-tool:update --dump-sql
Following extensions are already installed:
- mysqli
- pdo-mysql
- zip
- bzip2
- intl
- Xdebug
- OPcache
- APCu
Override the default settings by mounting your own php.ini
file as /usr/local/etc/php/php.ini
at runtime.
The configuration for Xdebug
is located in /usr/local/etc/php/conf.d/xdebug.ini
.
If you need more extensions (e. g. a module requires them), you could clone this alpine based PHP7-FPM docker image on GitHub (visit on Docker Hub) or use the official php and build your own docker image.
For further information how to install php extensions, see the "How to install more PHP extensions" and following sections in the official PHP documentation on Docker Hub.
Depending on whether you want to use SSL encryption, it's necessary to put the certificate and matching private key in the proper places. Also Consider to disable SSL encryption if you use the application behind a reverse proxy and let the proxy handle it.
In order to have an active encryption, copy your certificate file into the path /conf/ssl/certs/nginx.crt
.
The private key file should be copied to /conf/ssl/private/nginx.key
.
In case the filenames shouldn't be changed to nginx.ext or the file extensions is something else (e. g. .pem),
it's needed to adjust the paths following paths in the /conf/nginx.conf
:
ssl_certificate /etc/ssl/certs/nginx.crt;
ssl_certificate_key /etc/ssl/private/nginx.key;
Disabling SSL can be done by removing the first server block in /conf/conf.d/vhost.conf
and changing the listen directives in the second one.
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server ipv6only=on;
… will be replaced by …
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
Simply remove the lines beginning with listen [::]:…
in the /conf/conf.d/vhost.conf
file.
An access.log
and error.log
can be found in the /logs/
subfolder after
a successfully start of the application (and some requests).
There are some MYSQL_… environment variables to provide an initial database name, root password and username/password.
You could provide them in the .env
file in the project root, they will be handed over to the MariaDB container.
For further information (available variables, alternative secrets file) see Environment Variables / Docker Secrets sections in the official MariaDB documentation on Docker Hub.
It's possible to put some .sql scripts into the /conf/initdb.d/
directory.
This way initial database structures or existing dumps can be loaded.
For further information (file extensions, execution order) see Initializing a fresh instance
section in the official MariaDB documentation on Docker Hub.
The console-sf.sh
wrapper script allows to execute symfony commands as if you would directly call them
with php bin/console …
(see also How to Use the Console).
Show Symfony version and environment:
./bin/console-sf.sh --version
Example to clear the development or production environment caches:
./bin/console-sf.sh cache:clear --no-warmup --env=dev
./bin/console-sf.sh cache:clear --no-warmup --env=prod
Show a list of all routes:
./bin/console-sf.sh debug:router
Before you install the profiler, follow the tutorial Create your First Page in Symfony
and create a controller with an index route if you don't have one already, otherwise you will see an Exception
with the message No route found for "GET /"
after installation.
Alternatively you can execute the steps in Symfony 4 section above and create a simple index route. Afterwards install and activate the web-profiler toolbar by installing the profiler module:
./bin/composer.sh require --dev profiler
You can then configure the web-profiler in the /www/config/packages/dev/web_profiler.yaml
file
and enable/disable the toolbar any time by setting web_profiler.toolbar: false
.
Install Doctrine ORM in Symfony:
./bin/composer.sh require doctrine maker
Follow the given instructions and modify the shown configuration files to connect to your database.
Adjust your MySQL server_version in /www/config/packages/doctrine.yaml
and
change the DATABASE_URL
in the file /www/.env
to something like:
DATABASE_URL=mysql://user:password@db:3306/database
The default hostname of the server is db
(same as the service-name defined in /docker-compose.yml
).
Username, password and name of the database should match the MYSQL_… environment variables in the /.env
file
(the one which can be found in project's main folder).
List available doctrine commands (e. g. create entities, update schema, create migrations):
./bin/console-sf.sh list doctrine
Example to create/update/validate database schema:
./bin/console-sf.sh doctrine:schema:create
./bin/console-sf.sh doctrine:schema:update --force
./bin/console-sf.sh doctrine:schema:update --dump-sql
./bin/console-sf.sh doctrine:schema:validate
For further information see Databases and the Doctrine ORM in official Symfony documentation.
If you enable the developer toolbar with the following command (and after initializing the skeleton),
make sure to choose config/development.config.php.dist
as file to inject the ZendDeveloperTools into,
so they will stay disabled later in production.
./bin/composer.sh require --dev zendframework/zend-developer-tools
Install Doctrine ORM in Zend:
./bin/composer.sh require doctrine/doctrine-orm-module
Choose the config/modules.config.php
as config file for injecting the new modules.
It's necessary to provide at least a small and rudimentary doctrine configuration file, before you can
use doctrine commands on your database.
Create a new file /www/config/autoload/doctrine.global.php
with following content:
<?php
use ContainerInteropDoctrine\EntityManagerFactory;
return [
'dependencies' => [
'factories' => [
'doctrine.entity_manager.orm_default' => EntityManagerFactory::class,
],
],
/**
* For full configuration options, see
* https://github.com/DASPRiD/container-interop-doctrine/blob/master/example/full-config.php
*/
'doctrine' => [
'connection' => [
'orm_default' => [
'params' => [
'url' => 'mysql://user:password@db/database',
],
],
],
'driver' => [
'orm_default' => [
'class' => \Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain::class,
'drivers' => [
//'App\Entity' => 'my_entity',
],
],
/*'my_entity' => [
'class' => \Doctrine\ORM\Mapping\Driver\AnnotationDriver::class,
'cache' => 'array',
'paths' => 'src/App/Entity/',
],*/
],
],
];
Most configuration lines are taken from the Stack Overflow post about installing doctrine orm module with ZF3 skeleton app.
The hostname of the server connection url is again db
and username, password and name of the database
should match the MYSQL_… environment variables in the /.env
file,
same as in the Doctrine ORM section in Symfony.
There is also a wrapper for executing commands with the doctrine-module
of Zend.
List available doctrine commands (e. g. create entities, update and validate schema):
./bin/doctrine-zf.sh list
Show basic information about all mapped entities:
./bin/doctrine-zf.sh orm:info
Example to create/update/validate database schema:
./bin/doctrine-zf.sh orm:schema-tool:create
./bin/doctrine-zf.sh orm:schema-tool:update --force
./bin/doctrine-zf.sh orm:schema-tool:update --dump-sql
./bin/doctrine-zf.sh orm:validate-schema
- The
/conf/conf.d/vhost.conf
shares some configuration lines which can also be found in the official symfony documentation. Initializing and running a new Zend skeleton as described above was successful too. Though you should keep in mind some additions/adaptions may be needed if you choose another framework or add some new modules. - You probably want to remove the
.env
file after initializing your database. At least it's advisable to never commit the altered.env
file with login credentials for an application in production, so delete it from the cloned repository after you are done with this example and before officially working on it.