.. _installation-production:

Install Chill for production with or without adding personal features
#####################################################################

Chill is a set of "bundles" for a symfony app.

To run Chill in production or add new features to it (without merging those features to the chill core), you must create
a symfony app, and eventually add those features into your app.

Once you are happy with the configuration, `you should follow the dedicated instructions of how to go into production for
Symfony apps <https://symfony.com/doc/current/deployment.html>`_.

Install a new app
=================

Install required dependencies:
------------------------------

- `jq`: https://jqlang.org/ (install it through your package manager);
- `php`, minimal version: 8.3;
- `composer`: https://getcomposer.org/download/
- `symfony-cli`: https://symfony.com/download
- `docker` with the plugin `compose`: https://docs.docker.com/engine/install/ and https://docs.docker.com/compose/install/


Initialize project and dependencies
-----------------------------------

.. code-block:: bash

   symfony new --version=5.4 my_chill_project
   cd my_chill_project

We strongly encourage you to initialize a git repository at this step, to track further changes.

.. code-block:: bash

   # add the flex endpoints required for custom recipes
   cat <<< "$(jq '.extra.symfony += {"endpoint": ["flex://defaults", "https://gitlab.com/api/v4/projects/57371968/repository/files/index.json/raw?ref=main"]}' composer.json)" > composer.json
   # install chill and some dependencies
   symfony composer require -W chill-project/chill-bundles ^3.7.1 champs-libres/wopi-lib dev-master@dev champs-libres/wopi-bundle dev-master@dev symfony/amqp-messenger

We encourage you to accept the inclusion of the "Docker configuration from recipes": this is the documented way to run the database.
You must also accept to configure recipes from the contrib repository, unless you want to configure the bundles manually).

.. code-block:: bash

   # fix some configuration
   ./post-install-chill.sh
   # populate the cache for the first time. This is necessary to dump some translation files, required for the assets compilation
   symfony console cache:clear
   # install node dependencies
   yarn install
   # and compile assets
   yarn run encore production

.. note::

   If you encounter this error during assets compilation (:code:`yarn run encore production`) (repeated multiple times):

   .. code-block::

      [tsl] ERROR in /tmp/chill/v1/public/bundles/chillcalendar/types.ts(2,65)
            TS2307: Cannot find module '../../../ChillMainBundle/Resources/public/types' or its corresponding type declarations.

   run:

   .. code-block:: bash

      rm -rf public/bundles/*

   Then restart the compilation of assets (:code:```yarn run encore production```)

Configure your project
----------------------

You should read the configuration files in :code:`chill/config/packages` carefully, especially if you have
custom developments. But most of the time, this should be fine.

You have to configure some local variables, which are described in the :code:`.env` file. The secrets should not be stored
in this :code:`.env` file, but instead using the `secrets management tool <https://symfony.com/doc/current/configuration/secrets.html>`_
or in the :code:`.env.local` file, which should not be committed to the git repository.

You do not need to set variables for the smtp server, redis server and relatorio server, as they are generated automatically
by the symfony server, from the docker compose services.

The required variables are:

- the :code:`ADMIN_PASSWORD`;
- the :code:`OVHCLOUD_DSN` variable;

:code:`ADMIN_PASSWORD`
^^^^^^^^^^^^^^^^^^^^^^

You can generate a hashed and salted admin password using the command
:code:`symfony console security:hash-password <your password> 'Symfony\Component\Security\Core\User\User'`.Then,
you can either:

- add this password to the :code:`.env.local` file, you must escape the character :code:`$`: if the generated password
  is :code:`$2y$13$iyvJLuT4YEa6iWXyQV4/N.hNHpNG8kXlYDkkt5MkYy4FXcSwYAwmm`, your :code:`.env.local` file will be:

  .. code-block:: bash

     ADMIN_PASSWORD=\$2y\$13\$iyvJLuT4YEa6iWXyQV4/N.hNHpNG8kXlYDkkt5MkYy4FXcSwYAwmm
     # note: if you copy-paste the line above, the password will be "admin".

- add the generated password to the secrets manager (**note**: you must add the generated hashed password to the secrets env,
  not the password in clear text).

:code:`OVHCLOUD_DSN` and sending SMS messages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This is a temporary dependency, for ensuring compatibility for previous behaviour.

You can set it to :code:`null://null` if you do not plan to use sending SMS.

.. code-block:: bash

   OVHCLOUD_DSN=null://null

If you plan to do it, you can configure the notifier component `as described in the symfony documentation <https://symfony.com/doc/current/notifier.html#notifier-sms-channel>`_.


Some environment variables are available for the JWT authentication bundle in the :code:`.env` file.

Prepare database, messenger queue, and other configuration
----------------------------------------------------------

To continue the installation process, you will have to run migrations:

.. code-block:: bash

   # start databases and other services
   docker compose up -d
   # the first start, it may last some seconds, you can check with docker compose ps
   # run migrations
   symfony console doctrine:migrations:migrate
   # setup messenger
   symfony console messenger:setup-transports
   # prepare some views
   symfony console chill:db:sync-views
   # load languages data
   symfony console chill:main:languages:populate
   # generate jwt token, required for some api features (webdav access, ...)
   symfony console lexik:jwt:generate-keypair

.. note::

   If you encounter this error:

   .. code-block::

     No transport supports the given Messenger DSN.

   Please check that you installed the package `symfony/amqp-messenger`.



Start your web server locally
-----------------------------

At this step, Chill will be ready to be served locally, but without any configuration. You can run the project
locally using the `local symfony server <https://symfony.com/doc/current/setup/symfony_server.html>`_:

.. code-block:: bash

   # see the whole possibilities at https://symfony.com/doc/current/setup/symfony_server.html
   symfony server:start -d


If you need to test the instance with accounts and some basic configuration, please install the fixtures (see below).


Add capabilities for dev
========================

If you need to add custom bundles, you can develop them in the `src/` directory, like for any other symfony project. You
can rely on the whole chill framework, meaning there is no need to add them to the original `chill-bundles`.

You will require some bundles to have the following development tools:

- add fixtures
- add profiler and debug bundle

Install fixtures
----------------

.. code-block:: bash

   # generate fixtures for chill
   symfony composer require --dev doctrine/doctrine-fixtures-bundle nelmio/alice
   # now, you can generate fixtures (this will reset your database)
   symfony console doctrine:fixtures:load

This will generate user accounts, centers, and some basic configuration.

The accounts created are: :code:`center a_social`, :code:`center b_social`, :code:`center a_direction`, ...  The full list is
visible in the "users" table: :code:`docker compose exec database psql -U app -c "SELECT username FROM users"`.

The password is always :code:`password`.

.. warning::

   The fixtures are not fully functional. See the `corresponding issue <https://gitlab.com/Chill-Projet/chill-bundles/-/issues/280>`_.

Add web profiler and debugger
-----------------------------

.. code-block:: bash

   symfony composer require --dev symfony/web-profiler-bundle symfony/debug-bundle

Working on chill bundles
------------------------

If you plan to improve the chill-bundles repository, that's great!

It would be better :ref:`to follow the instruction about development <installation-for-dev>`. But if those features are
deeply linked to some dev you made in the app, it can be easier to develop within the :code:`vendor/` directory.

You will have to download chill-bundles as a git repository (and not as an archive, which is barely editable).

In your :code:`composer.json` file, add these lines:

.. code-block:: diff

    {
        "config": {
   +        "preferred-install": {
   +            "chill-project/chill-bundles": "source",
                "*": "dist"
   +         }
        }

Then, run :code:`symfony composer reinstall chill-project/chill-bundles` to re-install the package from source.


Update
======

In order to update your app, you must update dependencies:

- for chill-bundles, you can `set the last version <https://gitlab.com/Chill-Projet/chill-bundles/-/releases>`_ manually
  in the :code:`composer.json` file, or set the version to `^3.0.0` and run :code:`symfony composer update` regularly
- run :code:`composer update` and :code:`yarn update` to maintain your dependencies up-to-date.

After each update, you must update your database schema:

.. code-block:: bash

   symfony console doctrine:migrations:migrate
   symfony console chill:db:sync-views


Commit and share your project
=============================

If multiple developers work on a project, you can commit your symfony project and share it with other people.

When another developer clones your project, they will have to:

- run :code:`symfony composer install` and :code:`yarn install` to install the same dependencies as the initial developer;
- run :code:`yarn run encore production` to compile assets;
- copy any possible variables from the :code:`.env.local` files;
- start the docker compose stack, using :code:`docker compose`, and run migrations, set up transports, and prepare chill db views
  (see the corresponding command above)

Operations
==========

Build assets
------------

run those commands:

.. code-block:: bash

   # for production (or in dev, when you don't need to work on your assets and need some speed)
   yarn run encore production
   # in dev, when you wan't to reload the assets on each changes
   yarn run encore dev --watch

How to execute the console ?
----------------------------

.. code-block:: bash

   # start the console with all required variables
   symfony console
   # you can add your command after that:
   symfony console list

How to generate documents
-------------------------

Documents are generated asynchronously by `"consuming messages" <https://symfony.com/doc/current/messenger.html#consuming-messages-running-the-worker>`_.

You must generate them using a dedicated process:

.. code-block:: bash

   symfony console messenger:consume async priority

To avoid memory issues, we encourage you to also use the :code:`--limit` parameter of the command.

How to read emails sent by the program ?
-------------------------------------------

In development, there is a built-in "mail catcher". Open it with :code:`symfony open:local:webmail`

How to run cron-jobs ?
----------------------

Some commands must be executed in :ref:`cron jobs <cronjob>`. To execute them:

.. code-block:: bash

   symfony console chill:cron-job:execute

What about materialized views ?
-------------------------------

There are some materialized views in chill, to speed up some complex computations in the database.

In order to refresh them, run a cron job or refresh them manually in your database.


Troubleshooting
===============

Error `An exception has been thrown during the rendering of a template ("Asset manifest file "/var/www/app/web/build/manifest.json" does not exist.").` on first run
--------------------------------------------------------------------------------------------------------------------------------------------------------------------

Build assets, see above.

Go to production
================

Currently, to run this software in production, the *state of the art* is the following :

1. Run the software locally and tweak the configuration to your needs ;
2. Build the image and store it in a private container registry.

.. warning::

   In production, you **must** set these variables:

   * ``APP_ENV`` to ``prod``
   * ``APP_DEBUG`` to ``false``

   There are security issues if you keep the same variables as for production.


Going further
=============

.. toctree::
   :maxdepth: 2

   prod.rst
   document-storage.rst
   load-addresses.rst
   prod-calendar-sms-sending.rst
   msgraph-configure.rst
