diff --git a/.docker/README.md b/.docker/README.md new file mode 100644 index 000000000..b4bc641ae --- /dev/null +++ b/.docker/README.md @@ -0,0 +1,110 @@ +# DOCKER + +Docker stuff has been moved to the [infra repo](https://github.com/neontribe/ARCVInfra) for now. + +## Running the whole stack in containers + +This command will pull and build the service/store and start it. The files in this project are mounted in the container, changes on the host files system will be reflected in the container. + +```bash +echo "127.0.0.1 arcv-service.test arcv-store.test sqldb" | sudo tee -a /etc/hosts +docker compose -f .docker/docker-compose.yml up --build --force-recreate +``` + + * Arc service is now available at http://arcv-service.test:8000/login + * Mysql is available at ``mysql -ulamp -plamp -h127.0.0.1 -P3336 lamp` + * Phpmyadmin is available at [http://arcv-service.test:8880/login](http://arcv-service.test:8800/index.php?route=/database/structure&db=lamp) + * Mail catcher is available at http://arcv-service.test:1080/ + +### Using artisan + +To use `artisan` you need to execute the command in the container: e.g. + +```bash +docker compose -f .docker/docker-compose.yml exec service /opt/project/artisan tinker +``` + +Or you can open an interactive shell: + +```bash +docker compose -f .docker/docker-compose.yml exec service bash +``` + +## Attach a debugger (PHPStorm) + +Start the docker compose [as above](#running-the-whole-stack-in-containers) + +### Set up your browser extension + + * Chrome: https://chromewebstore.google.com/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc + * Firefox: https://addons.mozilla.org/en-US/firefox/addon/xdebug-helper-for-firefox/ + +The firefox extension defaults to eclipse as it's IDE, in the preferences, switch it to PHP Storm + +### In PHPStorm + +#### Set the project PHP interpreter to be lifted from the container + +* Alt+Ctrl+s +* Search - PHP +* Click three dots next to "CLI Interpreter" (...) +* Click "+" +* Choose "From Docker, Vagrant, VM, WSL, Remote..." +* Choose "Docker" +* Choose New on the sever line, click OK +* Click OK +* Click OK + +#### Create a run config + +Wait for indexes to build in phpstorm, when PHP starts it takes a few seconds/minutes to build them, without the indexes it create a run config. The **server** created in this section can be re-used in later run configs. + +* Edit configurations (Run menu) +* Click "+" (Add new configuration) +* Choose "PHP Web page" +* Give it a name +* Click three dots next to "Server" (...) +* Click "+" (Add) +* Give it a name +* Set host to "arcv-service.test" and port to 8080 +* Tick "Use path mappings" +* Set the "Absolute path on the server" that matches local project root to be "/opt/project" +* Click OK +* Click Run, see the service login page + +#### Set a break point and run the debgger + +* Open public/index.php +* Add a break point (Click next to the line numbers, see a red dot) +* Enable the debug browser extension, there's bug somewhere that needs to go green +* Turn on debug listener (Bug left of the run config) +* Click "debug" the run config + +#### Example images + +Enabling browser extension
+![xdebug-helper.png](images/xdebug-helper.png) + +Php Storm run dialog, disabled
+![phpstorm-debugger-inactive.png](images/phpstorm-debugger-inactive.png) + +Php Storm run dialog, enabled
+![phpstorm-debugger-active.png](images/phpstorm-debugger-active.png) + +## Docker for just the DB + +If you have a native PHP you can use a docker to provide your mysql DB. This is a transient docker, content will not persist between container restarts. + +```bash +cp .env.example .env # <-- Only if you're a new install +docker run --rm -d --name arcv-mysql \ + -e MYSQL_DATABASE=$DB_DATABASE \ + -e MYSQL_USER=$DB_USERNAME \ + -e MYSQL_PASSWORD=$DB_PASSWORD \ + -e MYSQL_ROOT_PASSWORD=changemeplease \ + -p $DB_PORT:3306 \ + mysql:8 +``` + + + diff --git a/.docker/docker-compose.yml b/.docker/docker-compose.yml index 6294304e4..694170d56 100644 --- a/.docker/docker-compose.yml +++ b/.docker/docker-compose.yml @@ -1,15 +1,18 @@ -version: '3.5' services: sqldb: image: mysql:5.7 environment: - - MYSQL_DATABASE=arcv + - MYSQL_DATABASE=arcv_service - MYSQL_USER=arcvuser - MYSQL_PASSWORD=arcvpassword - MYSQL_ROOT_PASSWORD=changemeplease + volumes: + - ./initdb.d:/docker-entrypoint-initdb.d command: --default-storage-engine innodb restart: unless-stopped + ports: + - 3336:3306 healthcheck: test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost interval: 20s @@ -24,6 +27,8 @@ services: volumes: - ./nginx_default.conf:/etc/nginx/conf.d/default.conf - ../:/opt/project:ro + restart: unless-stopped + depends_on: [service] service: image: arc-service:dev @@ -37,7 +42,7 @@ services: - DB_CONNECTION=mysql - DB_HOST=sqldb - DB_PORT=3306 - - DB_DATABASE=arcv + - DB_DATABASE=arcv_service - DB_USERNAME=arcvuser - DB_PASSWORD=arcvpassword - LOG_CHANNEL=stderr @@ -52,11 +57,20 @@ services: - "arcv-service.test:host-gateway" - "arcv-store.test:host-gateway" - "arcv-market.test:host-gateway" + restart: unless-stopped + depends_on: [sqldb] mailer: image: schickling/mailcatcher ports: - "${MAILER_ADMIN_PORT:-2080}:1080" + restart: unless-stopped volumes: - service_public: \ No newline at end of file + service_public: + +# docker compose -f .docker/docker-compose.yml up -d +# docker compose -f .docker/docker-compose.yml logs -f +# docker compose -f .docker/docker-compose.yml exec service bash +# docker compose -f .docker/docker-compose.yml exec service /opt/project/artisan +# docker compose -f .docker/docker-compose.yml exec sqldb mysql -uarcvuser -parcvpassword arcv_service diff --git a/.docker/entry-point.sh b/.docker/entry-point.sh index 723edf7ef..1659c0348 100755 --- a/.docker/entry-point.sh +++ b/.docker/entry-point.sh @@ -10,6 +10,12 @@ function checkDatabase() { echo " ✅ Connection established" } +function checkVendor() { + # the repo is cloned and just run the project folder has been mounted from the host and composer has not installed the deps. In this case we assume we will be a dev image: + composer --no-ansi install --working-dir=/opt/project --no-dev --optimize-autoloader + composer --no-ansi clearcache +} + function handleStartup() { # in production we will have a .env mounted into the container, this will have (at least) a # APP_KEY, if we don't have a .env we will create one @@ -24,11 +30,12 @@ function handleStartup() { fi fi - grep APP_KEY .env - # shellcheck disable=SC2181 - if [ "$?" != 0 ]; then - echo "APP_KEY=''" > .env + $_APP_KEY=$(grep -E '^\s*APP_KEY\s*=' .env | sed -E "s/.*=\s*'([^']*)'.*/\1/") + if [[ -z "$APP_KEY" ]]; then + echo "APP_KEY is empty." php /opt/project/artisan key:generate + else + echo "APP_KEY set not overwriting" fi # These are idempotent, run them anyway @@ -52,10 +59,12 @@ function handleStartup() { fi done fi + yarn yarn production } checkDatabase +checkVendor handleStartup if [ -n "$RUN_AS" ]; then @@ -84,3 +93,4 @@ env | sort exec php-fpm exit + diff --git a/.docker/images/phpstorm-debugger-active.png b/.docker/images/phpstorm-debugger-active.png new file mode 100644 index 000000000..f5022a55e Binary files /dev/null and b/.docker/images/phpstorm-debugger-active.png differ diff --git a/.docker/images/phpstorm-debugger-inactive.png b/.docker/images/phpstorm-debugger-inactive.png new file mode 100644 index 000000000..aab833b67 Binary files /dev/null and b/.docker/images/phpstorm-debugger-inactive.png differ diff --git a/.docker/images/run-config.png b/.docker/images/run-config.png new file mode 100644 index 000000000..39e14f003 Binary files /dev/null and b/.docker/images/run-config.png differ diff --git a/.docker/images/servers.png b/.docker/images/servers.png new file mode 100644 index 000000000..866a83933 Binary files /dev/null and b/.docker/images/servers.png differ diff --git a/.docker/images/xdebug-helper.png b/.docker/images/xdebug-helper.png new file mode 100644 index 000000000..749e98a77 Binary files /dev/null and b/.docker/images/xdebug-helper.png differ diff --git a/.docker/initdb.d/.keep b/.docker/initdb.d/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/.docker/passport-install.php b/.docker/passport-install.php index 046728efb..182f217b3 100644 --- a/.docker/passport-install.php +++ b/.docker/passport-install.php @@ -1,18 +1,11 @@ 1) { - // The first param is the project hme - $projectHome = $argv[1]; -} - -if (! is_writeable($projectHome . "/.env")) { +if (! is_writeable("/opt/project/.env")) { echo "Can't write to .env file\n"; exit(1); } -$contents = file_get_contents($projectHome . "/.env"); +$contents = file_get_contents("/opt/project/.env"); if (getenv("APP_ENV") == "prod" && strpos($contents, "PASSWORD_CLIENT_SECRET")) { echo "PASSWORD_CLIENT_SECRET exists and env is production, not overwriting\n"; exit(0); @@ -20,6 +13,7 @@ $lines = explode("\n", $contents); $cleaned = []; +print_r($lines); foreach ($lines as $line) { if (!strpos($line, "PASSWORD_CLIENT") || !strpos($line, "PASSWORD_CLIENT_SECRET")) { $cleaned[] = $line; @@ -41,6 +35,6 @@ $cleaned[] = "PASSWORD_CLIENT_SECRET=" . $elements[2]; } } -exec("chmod 600 " . $projectHome . "/storage/*.key"); +exec("chmod 600 /opt/project/storage/*.key"); -file_put_contents($projectHome . "/.env", implode("\n", $lines + $cleaned)); +file_put_contents("/opt/project/.env", implode("\n", $lines + $cleaned)); \ No newline at end of file diff --git a/.docker/xdebug.ini b/.docker/xdebug.ini index 9c37b9c13..81986c2c6 100644 --- a/.docker/xdebug.ini +++ b/.docker/xdebug.ini @@ -1,6 +1,6 @@ -zend_extension=xdebug - -[xdebug] -xdebug.mode=develop,debug -xdebug.client_host=host.docker.internal -xdebug.start_with_request=yes +xdebug.remote_enable=on +xdebug.remote_autostart=on +xdebug.remote_port = 9000 +xdebug.mode=debug +xdebug.discover_client_host=true +xdebug.remote_host = host.docker.internal \ No newline at end of file diff --git a/.gitignore b/.gitignore index 66ac083c8..599f7578d 100644 --- a/.gitignore +++ b/.gitignore @@ -32,9 +32,13 @@ tests/Browser/screenshots/ .docker-installed passport.install coverage +<<<<<<< HEAD +.docker/initdb.d/ +======= .php-cs-fixer.cache *.swp app/local .env.local arc_test_file_* build +>>>>>>> develop diff --git a/Dockerfile b/Dockerfile index 60880a088..b174321d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -117,7 +117,8 @@ ENV TIMEZONE=${TIMEZONE} RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone && \ # make composer home dir mkdir /composer && \ - chown -R www-data:www-data /composer + chown -R www-data:www-data /composer && \ + touch /opt/project/.env COPY ./.docker/entry-point.sh /entry-point.sh COPY ./.docker/dbtest.php /dbtest.php COPY ./.docker/passport-install.php /passport-install.php @@ -186,9 +187,9 @@ ENTRYPOINT /entry-point.sh FROM base AS dev # copy kimai develop source COPY --from=git-dev --chown=www-data:www-data /opt/project /opt/project -COPY ./.docker/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini COPY --from=php-ext-xdebug /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini COPY --from=php-ext-xdebug /usr/local/lib/php/extensions/no-debug-non-zts-20210902/xdebug.so /usr/local/lib/php/extensions/no-debug-non-zts-20210902/xdebug.so +COPY ./.docker/xdebug.ini /usr/local/etc/php/conf.d/zz_xdebug-config.ini RUN \ export COMPOSER_HOME=/composer && \ composer --no-ansi install --working-dir=/opt/project --optimize-autoloader && \ diff --git a/README.md b/README.md index aca984e8c..7e9720f90 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,69 @@ * [Voucher state transition](./VOUCHER_STATE_TRANSITIONS.md); reference for the voucher state machine that are enforces valid voucher state flow * [Database schema](./DATABASE_SCHEMA.md); reference diagram of the current database schema +<<<<<<< HEAD +1. Clone the repo +2. Create a database and user (homestead, sqlite or mysql) +3. If not using [Homestead](https://laravel.com/docs/6.x/homestead) or Valet - you will need to configure permissions on `storage` and `bootstrap/cache`. See [Laravel 6.x Installation](https://laravel.com/docs/6.x) for more info. +4. Copy `.env.example` to `.env` and edit to local settings +5. `composer install` +6. `php artisan key:generate` +7. `php artisan migrate --seed` +8. `php artisan passport:install` to create keys and client +9. `chmod 600 ./storage/*.key` to set permissions correctly +10. Add the "password grant client" id and secret to your `.env` +11. Install npm packages for webpack (JS and Sass) builds: `yarn install` +12. Run `yarn watch` in the background during development to automatically compile assets when modifying code or changing commit + +We suggest that you use the TLD `.test` as others, like `.app` may now be in the public domain and you will experience difficulty with respect to browser behavior over HTTP/HTTPS. + +## Docker + +There is a self building docker file in the root of the repo. Full docker instruction are [here](DOCKER.md). Environment variables that can be ovvrriden can be found in the [Dockerfile](Dockerfile). + +## Setting up reporting + +This project can run reports at set times using the Artisan scheduler. This requires some means of periodic triggering. Add to crontab the following: + +`*/20 * * * * /usr/bin/php /var/www/{path_to_install}/artisan schedule:run >> /dev/null 2>&1` + +We will also need a directory at `storage/app/enc` set to `chmod 770` permissions for {appropriate_user}:{webserver_group} + +where + +- {path_to_install} with the deploy location. +- {appropriate_user} with an appropriately qualified local user +- {webserver_group} with the webserver's group. + +It also requires PHP's `zip` extension installed and enabled. + +### To use the Reset data buttton on the dashboard: + - chown `env` to the console user and web user group e.g. `chown neontribe:www-data .env` + - And `chmod 775 .env` + + - Reseed with `php artisan migrate:refresh --seed` + - Run tests with `phpunit` + +### Styling + +#### Service + +- Service styling is in `resources/assets/sass/app.scss` +- When amending the styles in development, switching to a new branch or pulling code, run `yarn watch` to watch for changes +- Service is compiled from Sass with `yarn prod` +#### Store +- Store styling is in `public/store/css/main.css` +- Run `yarn dev` to make sure packages Store shares with Service have been included. + +## Deployment + +1. `./makedeploy.sh ARCVService_v(-[beta|RC]X)` +2. copy the tgz file up to the server +3. login and move to the correct folder +4. `./deploy-service ARCVService_v(-[beta|RC]X).tgz service_v(-[beta|RC]X)` +5. update the `.env` file +======= +>>>>>>> develop # Copyright This project was developed by : diff --git a/package.json b/package.json index fe1ff33b1..8d3a756e7 100644 --- a/package.json +++ b/package.json @@ -29,5 +29,6 @@ ">2%", "ie 11", "last 3 versions" - ] + ], + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" }