Create a new Symfony 6 project and install the necessary dependencies

May 9, 2023 MrAnyx 8 min to read

Our API will be based on the MVC (Models, Views and Controllers) structure or rather MC. Indeed, in the case of an API, we will not need to create and return HTML views. The returned results will all be in JSON format.

Let's start by creating the structure of our project. Since we are going to use the MVC structure, we will have to differentiate between Models and Controllers. First of all, let's create a first folder that we will name models as well as another one that we will call controllers.

Let's stop this bad joke right now. Of course we are not going to create the structure of our project by hand. It would take way too much time, plus it will be simply useless because there are other tools that can do this same task automatically. To do this, we will use Composer.

Creating the Docker container

As we mentioned in the prerequisites, you can use Docker to encapsulate the application in a container. This allows you not to pollute your system with language versions that would be specific for this course. You will also have more freedom in the development.

If you want to use Docker, here is a configuration you can use.

As a reminder, if you already have PHP, MySQL (or another database system) and Composer, you can skip this step. In the same way, if you use a turnkey software like Laragon or Xampp, you can skip this step.


At the root of your project (in the api folder we created earlier) start by creating a Dockerfile with the following content.

# Dockerfile

FROM php:8.1.17-apache

WORKDIR /var/www

ADD /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions
RUN install-php-extensions pdo_mysql intl opcache zip

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

COPY ./.apache/vhosts.conf /etc/apache2/sites-available/000-default.conf


This file is used to define a custom Docker image. Let's review what this configuration file will do.

  • FROM php:8.1.17-apache is used to define the image that we will use as a base. Here, it will be the image of PHP version 8.1.17 with the Apache module.
  • WORKDIR /var/www allows you to define the working directory. In other words, all the following commands will be executed from this directory. Here we choose /var/www as this is the default directory for Apache.
  • The following 3 lines allow you to install docker-php-extension-installer, a utility tool that makes it easy to install and configure extensions for PHP within a Docker image. For our api, we will only need the following extensions: pdo_mysql, intl, opcache et zip.
  • The following line allows to install Composer from the last Docker image
  • Then we copy the contents of the file .apache/vhosts.conf of the host machine in the /etc/apache2/sites-available/000-default.conf of our Docker image.
  • Finally, CMD apachectl -D FOREGROUND allows you to launch Apache.


Concerning the file .apache/vhosts.conf, it allows you to specify the entry path for our application. Since we are going to use Symfony, the entry path will be the public folder.

# .apache/vhosts.conf

<VirtualHost *:80>
    ServerName localhost

    DocumentRoot /var/www/public
    DirectoryIndex /index.php

    <Directory /var/www/public>
        AllowOverride None
        Order Allow,Deny
        Allow from All

        FallbackResource /index.php

    ErrorLog /var/log/apache2/app.log
    CustomLog /var/log/apache2/app.log combined

Docker compose

In addition to our custom Docker image, we will need several other services. For example, we will need a database as well as a tool to visualize the data in our database.

Here is a configuration for the docker-compose.yaml file in which we find the different services needed.

# docker-compose.yaml

version: "3.8"

        command: --max-allowed-packet=64MB
        container_name: api-database
        image: mariadb
            MYSQL_ROOT_PASSWORD: password
            - data:/var/lib/mariadb
            - dev

        container_name: api-adminer
        image: adminer
            - 8081:8080
            - dev
            - database

        container_name: api-web
            context: .
            dockerfile: Dockerfile
            - 8080:80
            - ./:/var/www
            - dev
            - database



Creation of the Symfony project

Indeed, we are not going to create the structure by hand, we will rather use the Composer commands to facilitate our work.

Creating a Symfony project can be done in two different ways depending on the type of project you want:

  • Full
  • Minimal

The full version of a Symfony project will install all the packages needed to run any kind of project. This version will allow to create websites, command line interfaces or APIs. Unfortunately, in the case of an API, many packages will be useless and will increase the size of our project without really adding any utility.

The minimal version, on the other hand, will leave the field free on the installation of the desired packages. We will only be able to install what is necessary and not end up with useless packages. At the same time we will optimize the size of our project.

In our case, to create an API, we prefer to use the minimal version so that we don't end up with useless packages.

To create a Symfony project, start by opening a terminal and navigate to the location where you want to place the project.

Then run the following command:

composer create-project symfony/skeleton:6.2.* ./

This command will create the architecture of the project in minimal version (skeleton) using the version 6.2 of Symfony. Here we enter the current directory (./) as the destination.

Several new folders should have appeared at the place where you wanted to position the project.

Understanding the architecture of a Symfony project

A Symfony project is divided into different folders and subfolders. Indeed, as in any project, it's important to have a well ordered logic in order not to get lost or simply to collaborate on a project.

A Symfony application is broken down into 5 major folders:

  • bin : Gathers utility executables to launch Symfony commands or to run unit tests with PHPUnit.
  • config : As its name indicates, this folder allows you to group together the configuration files of the different libraries that we may have to install.
  • public : Corresponds to the entry point of our application. This is where we will store the public files that people can see. In the case of an API, we will have only one file index.php.
  • src : Gathers all the logic of our application. We will find for example entities, controllers, repositories, ... This is where we will spend most of our time.
  • var : Allows you to store various temporary files such as cache files or log files.

Of course, other folders may appear during the development, like the migration folder. Here is the basic structure of a Symfony project in its minimal version. Actually, there is one last folder, which is common to PHP projects. It is the vendor folder which gathers all the packages we have installed.

Project configuration

Now that we know how a Symfony project is organized, we'll have to configure it. This configuration will be done by modifying the .env folder located at the root of the project as well as the installation of several packages thanks to Symfony Flex.

Installation of global packages

To make our API work, we will have to install different libraries to configure the Doctrine ORM for example or to have at our disposal utility commands to easily create our future controllers, entities and migrations.

To do this, simply run the following dial command.

composer require orm
composer require --dev maker-bundle

The installation of the package orm actually allows you to install multiple packages at once:

  • doctrine/doctrine-bundle
  • doctrine/doctrine-migration-bundle
  • doctrine-orm

Also, the migrations folder at the root of the project should be visible as well as the two folders src/Entity and src/Repository.

Finally, the file .env has been updated to include the Doctrine configuration. We will see later how to finish the configuration of the latter.

Modification of environment variables

We are not going to directly modify the .env file because it will contain the default variables of our application. Instead, we will use a .env.local file which will contain only the variables that will differ from the.env file.

Thus in the .env.local file, we will only have to fill in the variableDATABASE_URL.

# .env.local


You will only have to change the fields db_user, db_password, db_host, db_port and db_name by the values of your choice or by the one of your database.

  • db_user will have to match the username of your database with which you want to connect.
  • db_password is simply the word for that user.
  • db_host is the url of your database. If the database is running locally, you can enter the ip or localhost.
  • db_port : By default, it is port 3306.
  • db_name is the name of the database we are going to create. You can choose the name of your database. For the example, we will use the name api.

You should end up with something like this.

# .env.local


If you are using the Docker configuration, you should have the following line:

# .env.local


Creation of the database

Now that the whole project is configured, we only have to create the database before starting the development.

To do this, simply run the following command.

php bin/console doctrine:database:create


php bin/console d:d:c

We can now start developing the first bricks of our API.

In summary

In this lesson, we had the opportunity to see how to create a Symfony project thanks to the Compose commands. At the same time, we configured a Docker image so that we could get our API working properly. Finally, we installed various libraries global to the project thanks to Symfony Flex.

This work is made available under the terms of the license Licence Creative Commons