commit 6b55ae7c707fb4e54b2a8561e38196ccf58e946b Author: Evann Regnault Date: Fri Jun 7 20:27:58 2024 +0000 [Initial Commit] diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..7c94014 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea +.DS_Store +.env +vendor +public +composer.lock \ No newline at end of file diff --git a/README.md b/README.md new file mode 100755 index 0000000..3625a1c --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ + +# Docker PHP Development Environment + +This repository allows you to quickly get a development environment up and running using Docker, including a MySQL database and some debugging tools. + +This environment includes the latest versions of the following software: + +- `nginx:alpine` +- `php:8.3-fpm` +- `mysql:latest` +- `xdebug` + +## Prerequisites + + - Docker - https://www.docker.com/products/docker-desktop + - Tested and confirmed working on: + - macOS 12.3 (Monterey) + - Windows 10 Version 21H1 build 19043.1165 + +## Project Setup + +Run `composer create-project jlucki/docker-php-dev-env "project_name"` + +Alternatively, download the files from this repo and copy them to your project directory. + +## Running the Container + +1. Run `docker compose up` from the project directory + - Note: the above command will only work on versions newer than 3.6. If you are using Docker 3.6 or older, use `docker-compose up` +2. Visit `localhost` in your browser + +## Setting up Xdebug in Your IDE + +_The following instructions are for PHPStorm._ + +1. Click on Run > Edit Configurations +2. Click the `+` and add a new PHP Remote Debug configuration +3. Give the configuration a name +4. Tick _Filter debug connection by IDE key_ +5. Add `PHPSTORM` in the session id +6. Click the `...` next to Server +7. Click the `+` to add a new server +8. Give the server a name, and set the host to `localhost` +9. Tick _Use path mappings_ +10. Under the `Project files` file/directory, next to your project folder, for the `Absolute path on the server` column add `/var/www/html` +11. Hit Apply and OK until you've returned to the IDE +12. Click the _Start Listening for PHP Debug Connections_ icon +13. Set a breakpoint in your code +14. Refresh the page in your browser +15. Accept _Incoming Connection From Xdebug_ +16. Happy debugging! + +See https://xdebug.org/docs/remote for how to enable xdebug sessions. + +## Additional Notes + +For database connections, use `mysql` as the hostname. If you would like a different hostname, change the service name in the `docker-compose.yml` file. + +## Windows 10 Troubleshooting + +If you are having problems and can't seem to fix the issue, try one or both of these fixes: + +### Solution 1 +Try switching to **Windows containers**: + +Right-click the Docker icon in the system tray and click **Switch to Windows containers** as seen below: + +![Context Menu](https://i.imgur.com/enYmIPH.png) + +### Solution 2 +If the **Use the WSL 2 based engine** setting is checked: + +Uncheck the setting, then enable file sharing located under the **Resources** section, then the **File Sharing** section as seen below: + +![Docker Settings](https://i.imgur.com/maub2Wh.png) + +If the **Use the WSL 2 based engine** setting is unchecked: +Enable/check the setting (file sharing is automatically configured) diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..5b63333 --- /dev/null +++ b/composer.json @@ -0,0 +1,31 @@ +{ + "name": "jlucki/docker-php-dev-env", + "description": "A simple web development environment using Docker with NGINX, PHP, MySQL and Xdebug.", + "type": "project", + "keywords": [ + "docker", + "development", + "environment", + "php", + "xdebug", + "nginx" + ], + "license": "MIT", + "authors": [ + { + "name": "Jan Lucki", + "email": "jan@lucki.dev" + } + ], + "require": { + "sabre/dav": "^4.6", + "ext-curl": "*" + }, + "autoload": { + "psr-0": { + "Keycloak": "src", + "Collections": "src", + "Principal": "src" + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..112064f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +version: '3.7' +services: + web: + image: nginx:alpine + ports: + - "80:80" + volumes: + - ./:/var/www/html + - ./docker/conf/default.conf:/etc/nginx/conf.d/default.conf + php: + build: + context: ./docker + volumes: + - ./:/var/www/html + - ./docker/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini + mysql: + image: mysql:latest + ports: + - "3306:3306" + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: webapp + MYSQL_USER: webapp + MYSQL_PASSWORD: root diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100755 index 0000000..cbc0ff5 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,15 @@ +FROM php:8.3-fpm + +ARG WITH_XDEBUG=true + +RUN apt-get update && apt-get install -y \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) gd \ + && docker-php-ext-install mysqli \ + && docker-php-ext-install pdo pdo_mysql; \ + if [ $WITH_XDEBUG = "true" ] ; then \ + pecl install xdebug; \ + fi ; diff --git a/docker/conf/default.conf b/docker/conf/default.conf new file mode 100755 index 0000000..0735cc6 --- /dev/null +++ b/docker/conf/default.conf @@ -0,0 +1,22 @@ +server { + listen 80; + index index.php index.html; + server_name localhost; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /var/www/html/src; + + location / { + try_files $uri $uri.js /index.php$is_args$args; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass php:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + } +} diff --git a/docker/php/xdebug.ini b/docker/php/xdebug.ini new file mode 100755 index 0000000..8872bb2 --- /dev/null +++ b/docker/php/xdebug.ini @@ -0,0 +1,6 @@ +[Xdebug] +zend_extension=xdebug.so +xdebug.mode=debug +xdebug.client_port = 9000 +xdebug.client_host = host.docker.internal +xdebug.idekey=PHPSTORM diff --git a/index.php b/index.php new file mode 100755 index 0000000..62a4938 --- /dev/null +++ b/index.php @@ -0,0 +1,40 @@ +setRealm($_ENV['realm']); +$authPlugin = new DAV\Auth\Plugin($authBackend); + + +// The server object is responsible for making sense out of the WebDAV protocol +$server = new DAV\Server([new HomeCollection($authPlugin, $_ENV['users_path'])]); + +// If your server is not on your webroot, make sure the following line has the +// correct information +$server->setBaseUri($_ENV['base_uri']); + +// The lock manager is responsible for making sure users don't overwrite +// each others changes. +$lockBackend = new DAV\Locks\Backend\File('data/locks'); +$lockPlugin = new DAV\Locks\Plugin($lockBackend); +$server->addPlugin($lockPlugin); + + + +// This ensures that we get a pretty index in the browser, but it is +// optional. +$server->addPlugin(new DAV\Browser\Plugin()); +$server->addPlugin($authPlugin); +$server->addPlugin($aclPlugin); + +// All we need to do now, is to fire up the server +$server->start(); \ No newline at end of file diff --git a/src/Collections/HomeCollection.php b/src/Collections/HomeCollection.php new file mode 100644 index 0000000..daa76e9 --- /dev/null +++ b/src/Collections/HomeCollection.php @@ -0,0 +1,38 @@ +plugin = $authPlugin; + $this->userPath = $userPath; + } + + public function getChildren() + { + $principal = $this->plugin->getCurrentPrincipal(); + $username = explode("/", $principal)[1]; + $path = $this->userPath; + + if (!is_dir($path.$username)) { + mkdir($path.$username, 0777 , true); + } + + return [new Directory($path.$username, $username)]; + } + + public function getName() + { + return "Home"; + } +} \ No newline at end of file diff --git a/src/Keycloak/KeycloakAuth.php b/src/Keycloak/KeycloakAuth.php new file mode 100644 index 0000000..34e2870 --- /dev/null +++ b/src/Keycloak/KeycloakAuth.php @@ -0,0 +1,56 @@ +aclPlugin = $plugin; + $this->client_id = $client_id; + $this->client_secret = $client_secret; + $this->keycloakTokenUrl = $keycloakTokenUrl; + } + + protected function validateUserPass($username, $password) + { + $curl = curl_init(); + + curl_setopt_array($curl, [ + CURLOPT_URL => $this->keycloakTokenUrl, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_MAXREDIRS => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_CUSTOMREQUEST => "POST", + CURLOPT_POSTFIELDS => "grant_type=password&client_id=" . $this->client_id . "&client_secret=" . $this->client_secret . "&username=".$username."&password=".$password, + CURLOPT_HTTPHEADER => [ + "Content-Type: application/x-www-form-urlencoded" + ], + ]); + + curl_exec($curl); + + $err = curl_error($curl); + + $data = curl_getinfo($curl); + + curl_close($curl); + + if ($err || $data['http_code'] != 200) { + return false; + } else { + return true; + } + + } +} \ No newline at end of file diff --git a/src/Principal/CustomBackend.php b/src/Principal/CustomBackend.php new file mode 100644 index 0000000..4cc5a8d --- /dev/null +++ b/src/Principal/CustomBackend.php @@ -0,0 +1,44 @@ +