# phpList 4 base distribution

[![Build Status](https://github.com/phpList/base-distribution/workflows/phpList%20Base%20Dist%20Build/badge.svg)](https://github.com/phpList/base-distribution/actions)
[![Latest Stable Version](https://poser.pugx.org/phplist/base-distribution/v/stable.svg)](https://packagist.org/packages/phpList/base-distribution)
[![Total Downloads](https://poser.pugx.org/phplist/base-distribution/downloads.svg)](https://packagist.org/packages/phpList/base-distribution)
[![Latest Unstable Version](https://poser.pugx.org/phplist/base-distribution/v/unstable.svg)](https://packagist.org/packages/phpList/base-distribution)
[![License](https://poser.pugx.org/phplist/base-distribution/license.svg)](https://packagist.org/packages/phpList/base-distribution)

## About phpList

phpList is an open source newsletter manager. This project is a rewrite of the
[original phpList](https://github.com/phpList/phplist3).


## About this package

This module is the basis for a phpList 4 installation. It will pull in the
`phplist/core` module (the phpList 4 core) and by default also the
`phplist/rest-api` module (the new REST API package). The rest-api dependency
is optional.

This package is intended to be cloned and then modified. It is not intended to
be updated via Composer after the initial install (although updating the
dependencies via composer update is fine).

This (i.e., the downloaded package) is also the place where configuration files
will be stored (or symlinked to).


## Installation

1. Download and install [composer](https://getcomposer.org/download/).
2. Run `composer create-project -s dev --no-dev phplist/base-distribution your-project`
   (use any name you like for the `your-project` directory).
3. Switch to the `your-project` directory.
4. If you would like to not have the REST API, edit the `composer.json`,
   remove the corresponding `phplist/rest-api` requirement, and run
   `composer update`.


## Configuring and running phpList on a web server

The phpList application is configured so that the built-in PHP web server can
run in development and testing mode, while Apache can run in production mode.

### Production on Apache

1. In the Apache virtual host configuration, set the directory `public/` as the
   document root.
2. Set a random 40-character hex secret and the phpList database credentials
   in the Apache virtual host configuration. Your Apache 2.4 configuration
   then could look like this:

```
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

    DocumentRoot /var/www/project/public
    <Directory /var/www/project/public>
        AllowOverride All
        Require all granted
    </Directory>

    # uncomment the following lines if you install assets as symlinks
    # or run into problems when compiling LESS/Sass/CoffeeScript assets
    # <Directory /var/www/project>
    #     Options FollowSymlinks
    # </Directory>

    SetEnv PHPLIST_SECRET f75365ecb07c725ba05d5361e415a328880360e5
    SetEnv PHPLIST_DATABASE_NAME phplist
    SetEnv PHPLIST_DATABASE_USER phplist
    SetEnv PHPLIST_DATABASE_PASSWORD correctHorseBatteryStaple

    ErrorLog /var/log/apache2/project_error.log
    CustomLog /var/log/apache2/project_access.log combined
</VirtualHost>
```

Then reload or restart Apache to activate the configuration changes.

If you cannot set any environment variables in your Apache configuration, you
can also set the database credentials in `config/parameters.yml`.
However, this should only be used as a last resort as this reduces security (as an
attacker with read access to the files on the web server then could read that
file, whereas they then still would not be able to access the environment
variables).

Use the following optimized configuration to disable .htaccess support and
increase web server performance:

```
<VirtualHost *:80>
    ServerName domain.tld
    ServerAlias www.domain.tld

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

        <IfModule mod_rewrite.c>
            Options -MultiViews
            RewriteEngine On
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^(.*)$ app.php [QSA,L]
        </IfModule>
    </Directory>

    SetEnv PHPLIST_SECRET f75365ecb07c725ba05d5361e415a328880360e5
    SetEnv PHPLIST_DATABASE_NAME phplist
    SetEnv PHPLIST_DATABASE_USER phplist
    SetEnv PHPLIST_DATABASE_PASSWORD correctHorseBatteryStaple

    ErrorLog /var/log/apache2/project_error.log
    CustomLog /var/log/apache2/project_access.log combined
</VirtualHost>
```

### Development

For running the application in development mode using the built-in PHP server,
use this command:

```bash
bin/console server:run -d public/
```

The server will then listen on `http://127.0.0.1:8000` (or, if port 8000 is
already in use, on the next free port after 8000).

You can stop the server with CTRL + C.

### Testing

To run the server in testing mode (which normally will only be needed for the
automated tests, provide the `--env` option:

```bash
bin/console server:run -d public/ --env=test
```


## Useful Composer scripts

You can get a list of all installed phpList modules with this command:

```bash
composer run-script list-modules
```

To compile and publish the `phplist/web-frontend` assets into
`public/build` (used by the web frontend Twig templates),
run:

```bash
composer run-script build-web-frontend-assets
```


## Creating a .tar.gz package of this distribution

These are the steps to create a package for version 4.0.x-dev with the file
name `phplist-base-distribution-4.0.x-dev.tar.gz`:

```bash
composer create-project phplist/base-distribution phplist 4.0.x-dev --prefer-dist --no-dev -s dev
tar -cvzf phplist-base-distribution-4.0.x-dev.tar.gz phplist
```

These steps assume that `tar` and `composer` are installed on your machine, and that `composer` is [in your path](https://getcomposer.org/doc/00-intro.md#globally)
(and that it is named `composer`, not `composer.phar`).


## Contributing to this package

Please read the [contribution guide](.github/CONTRIBUTING.md) on how to
contribute and how to run the unit tests and style checks locally.

### Code of Conduct

This project adheres to a [Contributor Code of Conduct](CODE_OF_CONDUCT.md).
By participating in this project and its community, you are expected to uphold
this code.


## Docker deployment

The project includes a Docker setup to run phpList with Apache and MySQL.

Quick start (development/test):

- Build and start the stack: `docker compose up --build`
- Open [http://localhost:8081](http://localhost:8081)

The app container is configured to read database settings from environment variables that match config/parameters.yml defaults. The provided docker-compose.yml sets:

- PHPLIST_DATABASE_HOST=db
- PHPLIST_DATABASE_PORT=3306
- PHPLIST_DATABASE_NAME=phplistdb
- PHPLIST_DATABASE_USER=phplist
- PHPLIST_DATABASE_PASSWORD=phplist

Notes:

- For production deployments, build and push the image, then run it behind a reverse proxy or load balancer. Example:
  - `docker build -t your-registry/phplist-base:latest .`
  - `docker run -p 8080:80 --env PHPLIST_DATABASE_HOST=... --env PHPLIST_DATABASE_NAME=... --env PHPLIST_DATABASE_USER=... --env PHPLIST_DATABASE_PASSWORD=... your-registry/phplist-base:latest`
- Persist the MySQL data using the db_data volume defined in docker-compose.yml, or bind mount your own volume.
- You can also mount ./var to persist logs/cache between restarts. See commented volume in docker-compose.yml.
- The container uses Apache with DocumentRoot set to /var/www/html/public and mod_rewrite enabled.
- The base image uses PHP 8.1 (php:8.1-apache-bullseye) to match the Composer constraint (^8.1) and to ensure the IMAP build dependencies are available. You can bump to a newer 8.x tag (e.g., 8.3) if your deployment prefers it, but ensure IMAP build deps are present for that base.


```bash
docker exec -it base-distribution-app bash
```
