Getting started as a developer
There are several ways to get started. Like using the Docker setup or use the development server, which is explained in detail below.
The code is mainly written in PHP using the Symfony framework with Twig templating and a bit of JavaScript & CSS and of course HTML.
Docker as a dev server
To save yourself much time setting up a development server, you can use our Docker setup instead of a manual configuration:
- Make sure you are currently in the root of your Mbin directory.
- Run the auto setup script with
./docker/setup.sh dev localhost
to configure.env
,compose.override.yaml
, andstorage/
.
The Docker setup uses ports 80
and 443
by default. If you'd prefer to use a different port for development on your device, then in .env
you'll need to update KBIN_DOMAIN
and KBIN_STORAGE_URL
to include the port number (e.g., localhost:8443
). Additionally, add the following to compose.dev.yaml
under the php
service:
ports: !override
- 8443:443
- Run
docker compose up
to build and start the Docker containers. Please note that the first time you start the containers, they will need an extra minute or so to install dependencies before becoming available. - From here, you should be able to access your server at https://localhost/. Any edits to the source files will automatically rebuild your server.
- Optionally, follow the Mbin first setup instructions.
- If you'd like to enable federation capabilities, then in
compose.dev.yaml
, change the two lines fromreplicas: 0
toreplicas: 1
(under themessenger
andrabbitmq
services). Make sure you've ran the containers at least once before doing this, to give thephp
service a chance to install dependencies without overlap.
If you'd prefer to manually configure your Docker environment (instead of using the setup script) then follow the manual environment setup steps in the Docker install guide, but while you're creating compose.override.yaml
, use the following:
include:
- compose.dev.yaml
Once you are done with your development server and would like to shutdown the Docker containers, hit Ctrl+C
in your terminal.
If you'd prefer a development setup without using Docker, then continue on the section Bare metal installation.
Dev Container
This project also provides a configuration to create a Dev Container which can be launched from IDEs which support it. To use it, follow these steps:
- If you are using Podman, then uncomment the lines below
Uncomment if you are using Podman
in./.devcontainer/devcontainer.json
- Adjust values in:
./.devcontainer/.env.devcontainer
:SERVER_NAME
: changembin.domain.tld
tolocalhost
KBIN_DOMAIN
: change tolocalhost
KBIN_STORAGE_URL
: changembin.domain.tld
tolocalhost:8080
(or whatever port you set indevcontainer.json
)
- Start and open the Dev Container
- Run
chmod o+rwx public/
- Check if all needed services are running:
service --status-all
; services which should have a+
:- apache2
- apache-htcacheclean
- postgresql
- rabbitmq-server
- redis-server
- If some service are not running, try:
- Start it with
sudo service <service name> start
- If postgres fails:
sudo chmod -R postgres:postgres /var/lib/postgresql/
- Start it with
- Run
php -d memory_limit=-1 bin/console doctrine:migrations:migrate
- Run
npm install && npm run dev
- Open
http://localhost:8080
in a browser; you should see some status page or the Mbin startpage - Run
sudo find public/ -type d -exec chgrp www-data '{}' \;
andsudo find public/ -type d -exec chmod g+rwx '{}' \;
- You can now follow the initial configuration guide
OAuth keys
If you want to use OAuth for the API, do the following before creating the Dev Container:
- Generate the key material by following OAuth2 keys for API credential grants in Bare Metal/VM Installation
- Configure the described env variables in:
./.devcontainer/.env.devcontainer
(they are already declared at the end of the file) - After the Dev Container is created and opened:
- Run
chgrp www-data ./config/oauth2/private.pem
- Run
chmod g+r ./config/oauth2/private.pem
- Run
Running tests
To run test inside the Dev Container, some preparation is needed. These steps have to be repeated after every recreation of the Container:
- Run:
sudo pg_createcluster 13 tests --port=5433 --start
- Run:
sudo su postgres -c 'psql -p 5433 -U postgres -d postgres'
- Inside the SQL shell, run:
CREATE USER mbin WITH PASSWORD 'ChangeThisPostgresPass' SUPERUSER;
Now the testsuite can be launched with:
SYMFONY_DEPRECATIONS_HELPER=disabled php -d memory_limit=-1 ./bin/phpunit tests/Unit
or: SYMFONY_DEPRECATIONS_HELPER=disabled php -d memory_limit=-1 ./bin/phpunit tests/Functional/<path to tests to run>
.
For more information, read the Testing section on this page.
Bare metal installation
Initial setup
Requirements:
- PHP v8.3 or higher
- NodeJS v20 or higher
- Valkey / KeyDB / Redis (pick one)
- PostgreSQL
- Optionally: Mercure
- Optionally: Symfony CLI
First install some generic packages you will need:
sudo apt update
sudo apt install lsb-release ca-certificates curl wget unzip gnupg apt-transport-https software-properties-common git valkey-server
Clone the code
With an account on GitHub you will be able to fork this repository.
Once you forked the GitHub repository you can clone it locally (our advice is to use SSH to clone repositories from GitHub):
git clone git-repository-url
For example:
git clone git@github.com:MbinOrg/mbin.git
You do not need to fork the GitHub repository if you are member of our Mbin Organisation on GitHub. Just create a new branch right away.
Prepare PHP
- Install PHP + additional PHP extensions:
sudo apt install php8.4 php8.4-common php8.4-fpm php8.4-cli php8.4-amqp php8.4-bcmath php8.4-pgsql php8.4-gd php8.4-curl php8.4-xml php8.4-redis php8.4-mbstring php8.4-zip php8.4-bz2 php8.4-intl php8.4-bcmath -y
- Fine-tune PHP settings:
- Increase execution time in PHP config file:
/etc/php/8.4/fpm/php.ini
:
max_execution_time = 120
- Optional: Increase/set max_nesting_level in
/etc/php/8.4/fpm/conf.d/20-xdebug.ini
(in case you have thexdebug
extension installed):
xdebug.max_nesting_level=512
- Restart the PHP-FPM service:
sudo systemctl restart php8.4-fpm.service
Prepare PostgreSQL DB
- Install PostgreSQL:
sudo apt-get install postgresql postgresql-contrib
- Connect to PostgreSQL using the postgres user:
sudo -u postgres psql
- Create a new
mbin
database user with database:
sudo -u postgres createuser --createdb --createrole --pwprompt mbin
- If you are using
127.0.0.1
to connect to the PostgreSQL server, edit the following file:/etc/postgresql/<VERSION>/main/pg_hba.conf
and add:
local mbin mbin md5
- Finally, restart the PostgreSQL server:
sudo systemctl restart postgresql
Prepare dotenv file
- Change to the
mbin
git repository directory (if you weren't there already). - Copy the dot env file:
cp .env.example .env
. And let's configure the.env
file to your needs. Pay attention to the following changes:
# Set domain to 127.0.0.1:8000
SERVER_NAME=127.0.0.1:8000
KBIN_DOMAIN=127.0.0.1:8000
KBIN_STORAGE_URL=http://127.0.0.1:8000/media
# Valkey/Redis (without password)
REDIS_DNS=redis://127.0.0.1:6379
# Set App configs
APP_ENV=dev
APP_SECRET=427f5e2940e5b2472c1b44b2d06e0525
# Configure PostgreSQL
POSTGRES_DB=mbin
POSTGRES_USER=mbin
# Change your PostgreSQL password for Mbin user
POSTGRES_PASSWORD=<password>
# Set messenger to Doctrine (= PostgresQL DB)
MESSENGER_TRANSPORT_DSN=doctrine://default
Install Symfony CLI tool
- Install Symfony CLI:
wget https://get.symfony.com/cli/installer -O - | bash
- Check the requirements:
symfony check:requirements
Fill Database
- Assuming you are still in the
mbin
directory. - Create the database:
php bin/console doctrine:database:create
- Create tables and database structure:
php bin/console doctrine:migrations:migrate
Fixtures
This fixtures section is optional. Feel free to skip this section.
You might want to load random data to database instead of manually adding magazines, users, posts, comments etc. To do so, execute:
php bin/console doctrine:fixtures:load --append --no-debug
If you have messenger jobs configured, be sure to stop them:
- Docker:
docker compose stop messenger
- Bare Metal:
supervisorctl stop messenger:*
If you are using the Docker setup and want to load the fixture, execute:
docker compose exec php bin/console doctrine:fixtures:load --append --no-debug
Please note, that the command may take some time and data will not be visible during the process, but only after the finish.
- Omit
--append
flag to override data currently stored in the database - Customize inserted data by editing files inside
src/DataFixtures
directory
Starting the development server
Prepare the server:
- Build frontend assets:
npm install && npm run dev
- Install dependencies:
composer install
- Dump
.env
into.env.local.php
via:composer dump-env dev
- Optionally: Increase verbosity log level in:
config/packages/monolog.yaml
in thewhen@dev
section:level: debug
(instead oflevel: info
), - Important: clear Symfony cache:
APP_ENV=dev APP_DEBUG=1 php bin/console cache:clear -n
- Optionally: clear the Composer cache:
composer clear-cache
Start the development server:
- Start Mbin:
symfony server:start
- Go to: http://127.0.0.1:8000
Once you are done with your development server and would like to shut it down, hit Ctrl+C
in your terminal.
You might want to also follow the Mbin first setup. This explains how to create a user.
This will give you a minimal working frontend with PostgreSQL setup. Keep in mind: this will not start federating.
Optionally: If you want to start federating, you will also need to messenger jobs + RabbitMQ and host your server behind a reverse proxy with valid SSL certificate. Generally speaking, it's not required to setup federation for development purposes.
More info: Contributing guide, Admin guide and Symfony Local Web Server
Testing
When fixing a bug or implementing a new feature or improvement, we expect that test code will also be included with every delivery of production code. There are three levels of tests that we distinguish between:
- Unit Tests: test a specific unit (SUT), mock external functions/classes/database calls, etc. Unit-tests are fast, isolated and repeatable
- Integration Tests: test larger part of the code, combining multiple units together (classes, services or alike).
- Application Tests: test high-level functionality, APIs or web calls.
For more info read: Symfony Testing guide.
Prepare testing
- First increase execution time in your PHP config file:
/etc/php/8.4/fpm/php.ini
:
max_execution_time = 120
- Optional: Increase/set max_nesting_level in
/etc/php/8.4/fpm/conf.d/20-xdebug.ini
(in case you have thexdebug
extension installed):
xdebug.max_nesting_level=512
- Restart the PHP-FPM service:
sudo systemctl restart php8.4-fpm.service
- Copy the dot env file (if you haven't already):
cp .env.example .env
- Install composer packages:
composer install --no-scripts
Running unit tests
Running the unit tests can be done by executing:
SYMFONY_DEPRECATIONS_HELPER=disabled ./bin/phpunit tests/Unit
Running integration tests
Our integration tests depend on a database and a caching server (Valkey / KeyDB / Redis). The database and cache are cleared / dumped every test run.
To start the services in the background:
docker compose -f docker/tests/compose.yaml up -d
Then run the integration test(s):
SYMFONY_DEPRECATIONS_HELPER=disabled ./bin/phpunit tests/Functional
Linting
For linting see the linting documentation page.