diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..990b304c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +.github +.vscode +ansible +build +docs +var +vendor diff --git a/.env b/.env index 202520da..64813b00 100644 --- a/.env +++ b/.env @@ -53,7 +53,7 @@ MAILER_DELIVERY_ADDRESS="admin@example.org" # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4" # DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=14&charset=utf8" -DATABASE_URL="mysql://mail:password@127.0.0.1:3306/mail?charset=utf8mb4" +DATABASE_URL="mysql://mail:password@mariadb:3306/mail?charset=utf8mb4" ###< doctrine/doctrine-bundle ### ### Enable retention API ### diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..1f3a6bea --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM composer:2.8.3 AS composer + + +FROM php:8.2-cli AS builder + +RUN apt-get update && \ + apt-get install -y libzip-dev nodejs npm zip +RUN docker-php-ext-install -j$(nproc) zip + +COPY . /var/www/html/ +COPY --from=composer /usr/bin/composer /usr/bin/composer + +WORKDIR /var/www/html + +RUN composer install --no-scripts && \ + npm install --global yarn && \ + yarn install && \ + yarn encore production && \ + bin/console assets:install + + +FROM php:8.2-apache-bookworm + +RUN apt-get update && \ + apt-get install -y libpng-dev libsodium-dev libsqlite3-dev libzip-dev zlib1g-dev zip +RUN docker-php-ext-install -j$(nproc) gd opcache pdo_mysql pdo_sqlite sodium zip + +COPY --from=builder /var/www/html /var/www/html +COPY contrib/apache.conf /etc/apache2/sites-available/000-default.conf diff --git a/contrib/apache.conf b/contrib/apache.conf new file mode 100644 index 00000000..7341fb14 --- /dev/null +++ b/contrib/apache.conf @@ -0,0 +1,36 @@ + + + DocumentRoot /var/www/html/public + + + AllowOverride AuthConfig FileInfo Indexes Limit Options=ExecCGI,Includes,Indexes,SymLinksIfOwnerMatch,MultiViews + Options -Indexes -MultiViews +SymLinksIfOwnerMatch + + LimitRequestBody 10485760 + + + + + Require all granted + + + SetEnv APP_ENV dev + + + AddHandler fcgid-script .php + FCGIWrapper /var/www/users.example.org/php-fcgi/php-fcgi-starter .php + + IPCConnectTimeout 20 + IPCCommTimeout 60 + FcgidBusyTimeout 60 + MaxRequestLen 10485760 + + + Options +ExecCGI + + + + ErrorLog "|/usr/bin/logger -t apache -p local0.error" + + Protocols h2 http/1.1 + diff --git a/docker-compose.yml b/docker-compose.yml index fe2532dc..63d5bd2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,28 @@ --- services: - mysql: - image: mariadb:10.11 + userli: + build: + context: . + dockerfile: Dockerfile ports: - - '3306:3306' + - 8000:80 + networks: + - userli + + mariadb: + image: mariadb:10.11 environment: MYSQL_USER: mail MYSQL_PASSWORD: password MYSQL_DATABASE: mail MARIADB_RANDOM_ROOT_PASSWORD: true volumes: - - mysql:/var/lib/mysql + - mariadb:/var/lib/mysql + networks: + - userli + +networks: + userli: volumes: - mysql: + mariadb: diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index da72d7e8..f4f2c271 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -1,29 +1,38 @@ # Getting Started -The easiest way to install Userli on a fresh Debian Buster is running these commands: +The easiest way to get started with Userli is to use podman or docker. +We provide a `docker-compose.yml` file that starts Userli and MariaDB. +This is not recommended for production use, but it is a good way to get started. - # install dependencies - sudo apt update && sudo apt install -y ansible git python3-pip - sudo pip3 install molecule # re-run in case of error +!!! info + If you don't have podman or docker installed, you can find the installation instructions on the [podman website](https://podman.io/getting-started/installation) or the [docker website](https://docs.docker.com/get-docker/). - # get code - git clone https://github.com/systemli/ansible-role-userli.git - cd ansible-role-userli +1. Start Userli and MariaDB with podman or docker: + + Using podman: - # install apache2, mariadb, php8.0 and userli - sudo molecule converge -s localhost + ```shell + podman compose up -d --build + ``` -This installs all dependencies, creates a database and database user -(name: userli, password: userli), and installs the userli code at `/var/www/userli`. -It is accessible via [http://localhost:8080](http://localhost:8080). -There, you can create the first domain and user for your instance. + Using docker: -!!! warning - Do not run this configuration in production. + ```shell + docker-compose up -d --build + ``` -Next, you would have to change the password of the database user, -[configure your instance](../installation/configuration), -and probably install Dovecot to do anything meaningful. +2. Initialize the database: -Better, do a [manual installation](../installation) to understand each part of your -configuration. + Using podman: + + ```shell + podman exec userli bin/console doctrine:schema:create + ``` + + Using docker: + + ```shell + docker exec userli bin/console doctrine:schema:create + ``` + +3. Open your browser and go to [http://localhost:8000](http://localhost:8000) diff --git a/src/Controller/TwofactorController.php b/src/Controller/TwofactorController.php index 635bb2cd..0f473d4c 100644 --- a/src/Controller/TwofactorController.php +++ b/src/Controller/TwofactorController.php @@ -312,16 +312,17 @@ public function displayTotpQrCode(TotpAuthenticatorInterface $totpAuthenticator) throw new NotFoundHttpException('Cannot display QR code'); } - $result = Builder::create() - ->writer(new PngWriter()) - ->writerOptions([]) - ->data($totpAuthenticator->getQRContent($user)) - ->encoding(new Encoding('UTF-8')) - ->errorCorrectionLevel(ErrorCorrectionLevel::High) - ->size(320) - ->margin(20) - ->roundBlockSizeMode(RoundBlockSizeMode::Margin) - ->build(); + $builder = new Builder( + writer: new PngWriter(), + writerOptions: [], + data: $totpAuthenticator->getQRContent($user), + encoding: new Encoding('UTF-8'), + errorCorrectionLevel: ErrorCorrectionLevel::High, + size: 320, + margin: 20, + roundBlockSizeMode: RoundBlockSizeMode::Margin, + ); + $result = $builder->build(); return new Response($result->getString(), Response::HTTP_OK, ['Content-Type' => 'image/png']); }