diff --git a/.editorconfig b/.editorconfig index 67f7804..f9c618f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,17 +7,10 @@ root = true [*] end_of_line = lf indent_style = space -indent_size = 4 +indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[*.yml] -indent_size = 2 - -[*.nix] -indent_size = 2 -trim_trailing_whitespace = true - [*.md] trim_trailing_whitespace = false diff --git a/.envrc b/.envrc index 5ba4e1d..dfffb56 100644 --- a/.envrc +++ b/.envrc @@ -1,8 +1,8 @@ -export NIXPKGS_ALLOW_UNFREE=1 +source_url "https://raw.githubusercontent.com/cachix/devenv/v0.6.2/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" -watch_file devenv.nix -watch_file devenv.yaml -watch_file devenv.lock -watch_file devenv.local.nix +nix_direnv_watch_file devenv.nix +nix_direnv_watch_file devenv.lock +nix_direnv_watch_file devenv.yaml +nix_direnv_watch_file devenv.local.nix -eval "$(devenv print-dev-env)" +use devenv diff --git a/.github/workflows/publish_docs_to_wiki.yml b/.github/workflows/publish_docs_to_wiki.yml index 27b7f9a..e191794 100644 --- a/.github/workflows/publish_docs_to_wiki.yml +++ b/.github/workflows/publish_docs_to_wiki.yml @@ -5,8 +5,6 @@ on: paths: - docs/** - .github/workflows/publish_docs_to_wiki.yml - branches: - - main jobs: publish_docs_to_wiki: @@ -17,10 +15,11 @@ jobs: uses: jacobtomlinson/gha-find-replace@v3 with: find: "\\.md" - replace: "" + replace: "$1" regex: true include: "docs/*.md" - name: Upload Docs to Wiki + if: github.ref_name == 'main' uses: docker://decathlon/wiki-page-creator-action:latest env: GH_PAT: ${{ secrets.WIKI_ACTION_TOKEN_ServiceUser }} diff --git a/.gitignore b/.gitignore index 6506a66..8229628 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .idea # Devenv -.devenv* +/.devenv* +/.direnv devenv.local.nix diff --git a/README.md b/README.md index daec868..bdfd1b2 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ tightly tailored to the needs of our team members working on various projects wi - Enables Xdebug without a performance impact when not using it - Easily configurable PHP Version - Inherits all default devenv features and services +- Pre-installed [shopware-cli](https://sw-cli.fos.gg/) ## Setup & Usage A description about the setup and usage can be found in the [Wiki](https://github.com/kellerkinderDE/devenv-shopware/wiki). diff --git a/devenv.lock b/devenv.lock index ea072d0..65c2874 100644 --- a/devenv.lock +++ b/devenv.lock @@ -3,11 +3,11 @@ "devenv": { "locked": { "dir": "src/modules", - "lastModified": 1677721981, - "narHash": "sha256-vIXNwm98F2u5z9CLfWP72MJxaseVDBqnGhQGAFyxbLA=", + "lastModified": 1687106808, + "narHash": "sha256-RGDvxJA0bwfh6nx5qY/5CoDGZd13R4PIFG0JT729Yl4=", "owner": "cachix", "repo": "devenv", - "rev": "8454b85158482d93dcc3f20b77fef5272313d127", + "rev": "93ee7875ff1622d496da80414724bae0263c1d23", "type": "github" }, "original": { @@ -50,12 +50,15 @@ } }, "flake-utils": { + "inputs": { + "systems": "systems_2" + }, "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { @@ -87,11 +90,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1677587185, - "narHash": "sha256-zYT66MAYwctAQqI5VBw3LbBXiSKdB8vuMAqCGG8onbE=", + "lastModified": 1686960236, + "narHash": "sha256-AYCC9rXNLpUWzD9hm+askOfpliLEC9kwAo7ITJc4HIw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "68196a61c26748d3e53a6803de3d2f8c69f27831", + "rev": "04af42f3b31dba0ef742d254456dc4c14eedac86", "type": "github" }, "original": { @@ -103,16 +106,16 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1673800717, - "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=", + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-22.11", + "ref": "nixos-23.05", "repo": "nixpkgs", "type": "github" } @@ -126,11 +129,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1677386056, - "narHash": "sha256-7zjqCeKW7YWjqR6EsUOqd2JzyCioYGVbbqmTgHTytBs=", + "lastModified": 1686690310, + "narHash": "sha256-Ps9srIZGWpfi1SfvJ3MaIG2bTPy+28eQVyTZ55A/3vE=", "owner": "fossar", "repo": "nix-phps", - "rev": "98c16af0f9c329de8d62ef4817a5356c7685fffb", + "rev": "0983b1d334561d6526a67a0919c6631e61e01b38", "type": "github" }, "original": { @@ -150,11 +153,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1677722096, - "narHash": "sha256-7mjVMvCs9InnrRybBfr5ohqcOz+pyEX8m22C1XsDilg=", + "lastModified": 1686668298, + "narHash": "sha256-AADh9NqHh6X2LOem4BvI7oCkMm+JPCSCE7iIw5nn0VA=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "61a3511668891c68ebd19d40122150b98dc2fe3b", + "rev": "5b6b54d3f722aa95cbf4ddbe35390a0af8c0015a", "type": "github" }, "original": { @@ -171,13 +174,46 @@ "pre-commit-hooks": "pre-commit-hooks" } }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1676283394, - "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { diff --git a/devenv.nix b/devenv.nix index 9e763db..163f201 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,170 +1,26 @@ { pkgs, config, inputs, lib, ... }: - let cfg = config.kellerkinder; - phpConfig = lib.strings.concatStrings [ - '' - memory_limit = 2G - pdo_mysql.default_socket = ''${MYSQL_UNIX_PORT} - mysqli.default_socket = ''${MYSQL_UNIX_PORT} - blackfire.agent_socket = "${config.services.blackfire.socket}"; - realpath_cache_ttl = 3600 - session.gc_probability = 0 - display_errors = On - display_startup_errors = true - error_reporting = E_ALL - html_errors = true - assert.active = 0 - zend.detect_unicode = 0 - opcache.memory_consumption = 256M - opcache.interned_strings_buffer = 20 - opcache.enable_file_override = 1 - opcache.enable_cli = 1 - opcache.enabled = 1 - zend.assertions = 0 - short_open_tag = 0 - xdebug.mode = "debug" - xdebug.start_with_request = "trigger" - xdebug.discover_client_host = 1 - xdebug.var_display_max_depth = -1 - xdebug.var_display_max_data = -1 - xdebug.var_display_max_children = -1 - '' - cfg.additionalPhpConfig - ]; - - phpVersion = if builtins.hasAttr "PHP_VERSION" config.env then config.env.PHP_VERSION else cfg.phpVersion; - package = inputs.phps.packages.${builtins.currentSystem}.${phpVersion}; - - phpPackage = package.buildEnv { - extensions = { all, enabled }: with all; enabled - ++ (lib.optional config.services.redis.enable redis) - ++ (lib.optional config.services.blackfire.enable blackfire) - ++ (lib.optional config.services.rabbitmq.enable amqp) - ++ lib.attrsets.attrValues (lib.attrsets.getAttrs cfg.additionalPhpExtensions package.extensions); - extraConfig = phpConfig; - }; - - phpXdebug = package.buildEnv { - extensions = { all, enabled }: with all; enabled - ++ [ xdebug ] - ++ (lib.optional config.services.redis.enable redis) - ++ (lib.optional config.services.rabbitmq.enable amqp) - ++ lib.attrsets.attrValues (lib.attrsets.getAttrs cfg.additionalPhpExtensions package.extensions); - extraConfig = phpConfig; - }; - - entryScript = pkgs.writeScript "entryScript" '' - set -euo pipefail - - if [ ! -f $DEVENV_PROFILE/bin/mysqladmin ]; then - echo -e "mysqladmin missing, skips further entryscript processing" - ${pkgs.coreutils}/bin/sleep infinity - fi - - while ! $DEVENV_PROFILE/bin/mysqladmin ping --silent; do - ${pkgs.coreutils}/bin/sleep 1 - done - - while ! [[ $($DEVENV_PROFILE/bin/mysql shopware -s -N -e 'SHOW DATABASES LIKE "shopware";') ]] ; do - ${pkgs.coreutils}/bin/sleep 1 - done - - TABLE=$(mysql shopware -s -N -e 'SHOW TABLES LIKE "system_config";') - - if [[ $TABLE == "" ]]; then - echo "Table system_config is missing. Run >updateSystemConfig< manually to ensure the dev status of your setup!" - ${pkgs.coreutils}/bin/sleep infinity - fi - - ${scriptUpdateConfig} - - echo -e "Startup completed" - ${pkgs.coreutils}/bin/sleep infinity - ''; - - systemConfigEntries = lib.mapAttrsToList (name: value: { inherit name value; }) cfg.systemConfig; - - scriptUpdateConfig = pkgs.writeScript "scriptUpdateConfig" '' - VENDOR=${config.env.DEVENV_ROOT}/vendor/autoload.php - CONSOLE=${config.env.DEVENV_ROOT}/bin/console - - echo "Updating system config" - - if [ ! -f "$VENDOR" ] || [ ! -f "$CONSOLE" ]; then - echo "Vendor folder or console not found. Please run composer install." - exit 1 - fi - - # additional config - ${lib.concatMapStrings ({ name, value }: '' - $CONSOLE system:config:set ${name} ${value} || exit 1 - echo "System config ${name} set to ${value}" - '') systemConfigEntries} - - # default config - $CONSOLE system:config:set core.mailerSettings.emailAgent "" || exit 1 - echo "System config core.mailerSettings.emailAgent set to '''" - ''; - - importDbHelper = pkgs.writeScript "importDbHelper" '' - if [[ "$1" == "" ]]; then - echo "Please set devenv configuration for kellerkinder.importDatabaseDumps" - exit - fi - - if ! $DEVENV_PROFILE/bin/mysqladmin ping > /dev/null 2>&1; then - echo "MySQL server is dead or has gone away! devenv up?" - exit - fi - - TARGETFOLDER="${config.env.DEVENV_STATE}/importdb" - - rm -rf "$TARGETFOLDER" - set -e - - if [[ "$1" == *.sql ]]; then - ${pkgs.curl}/bin/curl -s --create-dirs "$1" --output "$TARGETFOLDER/latest.sql" - elif [[ "$1" == *.gz ]]; then - ${pkgs.curl}/bin/curl -s --create-dirs "$1" --output "$TARGETFOLDER/latest.sql.gz" - ${pkgs.gzip}/bin/gunzip -q -c "$TARGETFOLDER/latest.sql.gz" > "$TARGETFOLDER/dump.sql" - elif [[ "$1" == *.zip ]]; then - ${pkgs.curl}/bin/curl -s --create-dirs "$1" --output "$TARGETFOLDER/latest.sql.zip" - ${pkgs.unzip}/bin/unzip -qq -j -o "$TARGETFOLDER/latest.sql.zip" '*.sql' -d "$TARGETFOLDER" - else - echo "Unsupported file type for file at $1" - exit - fi - - rm -f "$TARGETFOLDER/latest.sql.*" - - SQL_FILE=$(find "$TARGETFOLDER" -name "*.sql" | head -n 1) - - if [[ "$SQL_FILE" == "" ]]; then - echo "No SQL file found" - exit - fi - - LANG=C LC_CTYPE=C LC_ALL=C ${pkgs.gnused}/bin/sed -i -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' "$SQL_FILE" - LANG=C LC_CTYPE=C LC_ALL=C ${pkgs.gnused}/bin/sed -i 's/NO_AUTO_CREATE_USER//' "$SQL_FILE" - - $DEVENV_PROFILE/bin/mysql shopware -f < "$SQL_FILE" - - echo "Import $1 finished!" - ''; + listEntries = path: + map (name: path + "/${name}") (builtins.attrNames (builtins.readDir path)); in { + imports = [ + (lib.mkRenamedOptionModule [ "kellerkinder" "additionalServerAlias" ] [ "kellerkinder" "domains" ]) + (lib.mkRenamedOptionModule [ "kellerkinder" "fallbackRedirectMediaUrl" ] [ "kellerkinder" "fallbackMediaUrl" ]) + ] ++ (listEntries ./modules); + options.kellerkinder = { enable = lib.mkOption { type = lib.types.bool; - default = true; description = "Enables the Kellerkinder devenv environment"; + default = true; }; phpVersion = lib.mkOption { type = lib.types.str; - default = "php81"; description = "PHP Version"; + default = "php81"; }; systemConfig = lib.mkOption { @@ -178,8 +34,8 @@ in { additionalPhpConfig = lib.mkOption { type = lib.types.str; - default = ""; description = "Additional php.ini configuration"; + default = ""; example = '' memory_limit = 0 ''; @@ -194,8 +50,8 @@ in { additionalVhostConfig = lib.mkOption { type = lib.types.str; - default = ""; description = "Additional vhost configuration"; + default = ""; }; additionalServerAlias = lib.mkOption { @@ -207,14 +63,14 @@ in { enableElasticsearch = lib.mkOption { type = lib.types.bool; - default = false; description = "Enables Elasticsearch"; + default = false; }; enableRabbitMq = lib.mkOption { type = lib.types.bool; - default = false; description = "Enables RabbitMQ"; + default = false; }; importDatabaseDumps = lib.mkOption { @@ -229,20 +85,34 @@ in { documentRoot = lib.mkOption { type = lib.types.str; - default = "public"; description = "Sets the docroot of caddy"; + default = "public"; + }; + + projectRoot = lib.mkOption { + type = lib.types.str; + description = "Root of the project as path from the file devenv.nix"; + default = "."; + example = "project"; }; staticFilePaths = lib.mkOption { type = lib.types.str; - default = "/theme/* /media/* /thumbnail/* /bundles/* /css/* /fonts/* /js/* /recovery/* /sitemap/*"; description = ''Sets the matcher paths to be "ignored" by caddy''; + default = "/theme/* /media/* /thumbnail/* /bundles/* /css/* /fonts/* /js/* /recovery/* /sitemap/*"; }; fallbackRedirectMediaUrl = lib.mkOption { type = lib.types.str; - default = ""; description = ''Fallback redirect URL for media not found on local storage. Best for CDN purposes without downloading them.''; + default = ""; + }; + + additionalPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; + description = "Additional packages to be installed"; + default = [ ]; + example = [ pkgs.jpegoptim pkgs.optipng pkgs.gifsicle ]; }; }; @@ -250,138 +120,14 @@ in { packages = [ pkgs.jq pkgs.gnupatch - ]; + pkgs.shopware-cli + ] ++ cfg.additionalPackages; languages.javascript = { enable = lib.mkDefault true; package = lib.mkDefault pkgs.nodejs-16_x; }; - languages.php = { - enable = lib.mkDefault true; - package = lib.mkDefault phpPackage; - - fpm.pools.web = { - settings = { - "clear_env" = "no"; - "pm" = "dynamic"; - "pm.max_children" = 10; - "pm.start_servers" = 2; - "pm.min_spare_servers" = 1; - "pm.max_spare_servers" = 10; - }; - }; - fpm.pools.web.phpPackage = lib.mkDefault phpPackage; - - fpm.pools.xdebug = { - settings = { - "clear_env" = "no"; - "pm" = "dynamic"; - "pm.max_children" = 10; - "pm.start_servers" = 2; - "pm.min_spare_servers" = 1; - "pm.max_spare_servers" = 10; - }; - }; - fpm.pools.xdebug.phpPackage = lib.mkDefault phpXdebug; - }; - - services.caddy = { - enable = lib.mkDefault true; - config = '' - { - auto_https disable_redirects - } - ''; - virtualHosts."127.0.0.1:8000" = lib.mkDefault { - serverAliases = cfg.additionalServerAlias; - extraConfig = lib.strings.concatStrings [ - '' - @default { - not path ${cfg.staticFilePaths} - not expression header_regexp('xdebug', 'Cookie', 'XDEBUG_SESSION') || query({'XDEBUG_SESSION': '*'}) - } - @debugger { - not path ${cfg.staticFilePaths} - expression header_regexp('xdebug', 'Cookie', 'XDEBUG_SESSION') || query({'XDEBUG_SESSION': '*'}) - } - - tls internal - - root * ${cfg.documentRoot} - - encode zstd gzip - - handle /media/* { - ${lib.strings.optionalString (cfg.fallbackRedirectMediaUrl != "") '' - @notStatic not file - redir @notStatic ${lib.strings.removeSuffix "/" cfg.fallbackRedirectMediaUrl}{path} - ''} - file_server - } - - handle_errors { - respond "{err.status_code} {err.status_text}" - } - - handle { - php_fastcgi @default unix/${config.languages.php.fpm.pools.web.socket} { - trusted_proxies private_ranges - } - - php_fastcgi @debugger unix/${config.languages.php.fpm.pools.xdebug.socket} { - trusted_proxies private_ranges - } - - file_server - } - - log { - output stderr - format console - level ERROR - } - '' - cfg.additionalVhostConfig - ]; - }; - }; - - services.mysql = { - enable = lib.mkDefault true; - initialDatabases = lib.mkDefault [{ name = "shopware"; }]; - ensureUsers = lib.mkDefault [{ - name = "shopware"; - password = "shopware"; - ensurePermissions = { "*.*" = "ALL PRIVILEGES"; }; - }]; - settings = { - mysqld = { - group_concat_max_len = 2048; - key_buffer_size = 16777216; - max_allowed_packet = 134217728; - sync_binlog = 0; - table_open_cache = 1024; - log_bin_trust_function_creators = 1; - }; - mysql = { - user = "shopware"; - password = "shopware"; - host = "127.0.0.1"; - }; - mysqldump = { - user = "shopware"; - password = "shopware"; - host = "127.0.0.1"; - }; - mysqladmin = { - user = "shopware"; - password = "shopware"; - host = "127.0.0.1"; - }; - }; - }; - services.redis.enable = lib.mkDefault true; services.adminer.enable = lib.mkDefault true; @@ -422,48 +168,9 @@ in { (lib.mkIf config.services.rabbitmq.enable { RABBITMQ_NODENAME = "rabbit@localhost"; # 127.0.0.1 can't be used as rabbitmq can't set short node name }) + (lib.mkIf config.services.redis.enable { + REDIS_DSN = "redis://127.0.0.1:6379"; + }) ]; - - # Processes - processes.entryscript.exec = "${entryScript}"; - - # Config related scripts - scripts.updateSystemConfig.exec = '' - ${scriptUpdateConfig} - ''; - - # Symfony related scripts - scripts.cc.exec = '' - CONSOLE=${config.env.DEVENV_ROOT}/bin/console - - if test -f "$CONSOLE"; then - exec $CONSOLE cache:clear - fi - ''; - - scripts.uuid.exec = '' - ${pkgs.toybox}/bin/uuidgen | tr "[:upper:]" "[:lower:]" | sed 's/-//g' - ''; - - scripts.debug.exec = '' - XDEBUG_SESSION=1 ${phpXdebug}/bin/php "$@" - ''; - - scripts.importdb.exec = '' - echo "Are you sure you want to download SQL files and overwrite the existing database with their data (y/n)?" - read answer - - if [[ "$answer" != "y" ]]; then - echo "Alright, we will stop here." - exit - fi - - ${lib.concatMapStrings (dump: '' - echo "Importing ${dump}" - ${importDbHelper} ${dump} - '') cfg.importDatabaseDumps} - - ${scriptUpdateConfig} - ''; }; } diff --git a/devenv.yaml b/devenv.yaml index 89709c7..672f3be 100644 --- a/devenv.yaml +++ b/devenv.yaml @@ -1,3 +1,5 @@ +allowUnfree: true + inputs: nixpkgs: url: github:NixOS/nixpkgs/nixos-unstable @@ -6,4 +8,3 @@ inputs: inputs: nixpkgs: follows: nixpkgs - diff --git a/docs/Options.md b/docs/Options.md index 3172189..089e35a 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -41,7 +41,7 @@ Define additional server aliases that are added to caddy. *_Example_* ``` -kellerkinder.additionalServerAlias = [ +kellerkinder.domains = [ "example.com" ]; ``` @@ -99,6 +99,14 @@ Changes the default document root (`public`) of caddy to the specified value kellerkinder.documentRoot = "."; ``` +# kellerkinder.projectRoot +Changes the default root of the project to the specified value (no `/` as pre- or suffix required) + +*_Example for a `project` folder inside the current folder_* +``` +kellerkinder.projectRoot = "project"; +``` + # kellerkinder.staticFilePaths Adjusts the defined matcher paths for caddy. You might want to adjust those to access/handle `*.php` files. @@ -114,5 +122,13 @@ Fallback redirect URL for media not found on local storage. Best for CDN purpose *_Example_* ``` -kellerkinder.fallbackRedirectMediaUrl = "https://my-cool-cdn-in-public-staging.example-cdn.com"; +kellerkinder.fallbackMediaUrl = "https://my-cool-cdn-in-public-staging.example-cdn.com"; +``` + +# kellerkinder.additionalPackages +Define additional PHP extensions that are included in the devenv environment. + +*_Example_* +``` +kellerkinder.additionalPackages = [ pkgs.jpegoptim pkgs.optipng pkgs.gifsicle ]; ``` diff --git a/examples/sw5/.envrc b/examples/sw5/.envrc index 5ba4e1d..dfffb56 100644 --- a/examples/sw5/.envrc +++ b/examples/sw5/.envrc @@ -1,8 +1,8 @@ -export NIXPKGS_ALLOW_UNFREE=1 +source_url "https://raw.githubusercontent.com/cachix/devenv/v0.6.2/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" -watch_file devenv.nix -watch_file devenv.yaml -watch_file devenv.lock -watch_file devenv.local.nix +nix_direnv_watch_file devenv.nix +nix_direnv_watch_file devenv.lock +nix_direnv_watch_file devenv.yaml +nix_direnv_watch_file devenv.local.nix -eval "$(devenv print-dev-env)" +use devenv diff --git a/examples/sw5/devenv.yaml b/examples/sw5/devenv.yaml index abb05c5..3b2471b 100644 --- a/examples/sw5/devenv.yaml +++ b/examples/sw5/devenv.yaml @@ -1,12 +1,13 @@ -inputs: - kellerkinder: - url: git+https://github.com/kellerkinderDE/devenv-shopware - flake: false - phps: - url: github:fossar/nix-phps - inputs: - nixpkgs: - follows: nixpkgs +allowUnfree: true imports: - - kellerkinder + - kellerkinder +inputs: + kellerkinder: + url: git+https://github.com/kellerkinderDE/devenv-shopware + flake: false + phps: + url: github:fossar/nix-phps + inputs: + nixpkgs: + follows: nixpkgs diff --git a/examples/sw6/.envrc b/examples/sw6/.envrc index 5ba4e1d..dfffb56 100644 --- a/examples/sw6/.envrc +++ b/examples/sw6/.envrc @@ -1,8 +1,8 @@ -export NIXPKGS_ALLOW_UNFREE=1 +source_url "https://raw.githubusercontent.com/cachix/devenv/v0.6.2/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" -watch_file devenv.nix -watch_file devenv.yaml -watch_file devenv.lock -watch_file devenv.local.nix +nix_direnv_watch_file devenv.nix +nix_direnv_watch_file devenv.lock +nix_direnv_watch_file devenv.yaml +nix_direnv_watch_file devenv.local.nix -eval "$(devenv print-dev-env)" +use devenv diff --git a/examples/sw6/devenv.yaml b/examples/sw6/devenv.yaml index 0bef97c..2d1fee3 100644 --- a/examples/sw6/devenv.yaml +++ b/examples/sw6/devenv.yaml @@ -1,3 +1,6 @@ +allowUnfree: true +imports: + - kellerkinder inputs: kellerkinder: url: git+https://github.com/kellerkinderDE/devenv-shopware @@ -7,6 +10,3 @@ inputs: inputs: nixpkgs: follows: nixpkgs -imports: - - kellerkinder - diff --git a/modules/caddy.nix b/modules/caddy.nix new file mode 100644 index 0000000..bd4f3e4 --- /dev/null +++ b/modules/caddy.nix @@ -0,0 +1,68 @@ +{ pkgs, config, inputs, lib, ... }: + +let + cfg = config.kellerkinder; +in { + config = lib.mkIf cfg.enable { + services.caddy = { + enable = lib.mkDefault true; + config = '' + { + auto_https disable_redirects + } + ''; + virtualHosts."127.0.0.1:8000" = lib.mkDefault { + serverAliases = cfg.additionalServerAlias; + extraConfig = lib.strings.concatStrings [ + '' + @default { + not path ${cfg.staticFilePaths} + not expression header_regexp('xdebug', 'Cookie', 'XDEBUG_SESSION') || query({'XDEBUG_SESSION': '*'}) + } + @debugger { + not path ${cfg.staticFilePaths} + expression header_regexp('xdebug', 'Cookie', 'XDEBUG_SESSION') || query({'XDEBUG_SESSION': '*'}) + } + + tls internal + + root * ${cfg.projectRoot}/${cfg.documentRoot} + + encode zstd gzip + + handle /media/* { + ${lib.strings.optionalString (cfg.fallbackRedirectMediaUrl != "") '' + @notStatic not file + redir @notStatic ${lib.strings.removeSuffix "/" cfg.fallbackRedirectMediaUrl}{path} + ''} + file_server + } + + handle_errors { + respond "{err.status_code} {err.status_text}" + } + + handle { + php_fastcgi @default unix/${config.languages.php.fpm.pools.web.socket} { + trusted_proxies private_ranges + } + + php_fastcgi @debugger unix/${config.languages.php.fpm.pools.xdebug.socket} { + trusted_proxies private_ranges + } + + file_server + } + + log { + output stderr + format console + level ERROR + } + '' + cfg.additionalVhostConfig + ]; + }; + }; + }; +} diff --git a/modules/mysql.nix b/modules/mysql.nix new file mode 100644 index 0000000..38497c2 --- /dev/null +++ b/modules/mysql.nix @@ -0,0 +1,43 @@ +{ pkgs, config, inputs, lib, ... }: + +let + cfg = config.kellerkinder; +in { + config = lib.mkIf cfg.enable { + services.mysql = { + enable = lib.mkDefault true; + package = lib.mkDefault pkgs.mysql80; + initialDatabases = lib.mkDefault [{ name = "shopware"; }]; + ensureUsers = lib.mkDefault [{ + name = "shopware"; + password = "shopware"; + ensurePermissions = { "*.*" = "ALL PRIVILEGES"; }; + }]; + settings = { + mysqld = { + group_concat_max_len = 2048; + key_buffer_size = 16777216; + max_allowed_packet = 134217728; + sync_binlog = 0; + table_open_cache = 1024; + log_bin_trust_function_creators = 1; + }; + mysql = { + user = "shopware"; + password = "shopware"; + host = "127.0.0.1"; + }; + mysqldump = { + user = "shopware"; + password = "shopware"; + host = "127.0.0.1"; + }; + mysqladmin = { + user = "shopware"; + password = "shopware"; + host = "127.0.0.1"; + }; + }; + }; + }; +} diff --git a/modules/php.nix b/modules/php.nix new file mode 100644 index 0000000..7227439 --- /dev/null +++ b/modules/php.nix @@ -0,0 +1,87 @@ +{ pkgs, config, inputs, lib, ... }: + +let + cfg = config.kellerkinder; + + phpConfig = lib.strings.concatStrings [ + '' + memory_limit = 2G + pdo_mysql.default_socket = ''${MYSQL_UNIX_PORT} + mysqli.default_socket = ''${MYSQL_UNIX_PORT} + blackfire.agent_socket = "${config.services.blackfire.socket}"; + realpath_cache_ttl = 3600 + session.gc_probability = 0 + display_errors = On + display_startup_errors = true + error_reporting = E_ALL + html_errors = true + assert.active = 0 + zend.detect_unicode = 0 + opcache.memory_consumption = 256M + opcache.interned_strings_buffer = 20 + opcache.enable_cli = 1 + opcache.enabled = 1 + zend.assertions = 0 + short_open_tag = 0 + xdebug.mode = "debug" + xdebug.start_with_request = "trigger" + xdebug.discover_client_host = 1 + xdebug.var_display_max_depth = -1 + xdebug.var_display_max_data = -1 + xdebug.var_display_max_children = -1 + '' + cfg.additionalPhpConfig + ]; + + phpVersion = if builtins.hasAttr "PHP_VERSION" config.env then config.env.PHP_VERSION else cfg.phpVersion; + package = inputs.phps.packages.${builtins.currentSystem}.${phpVersion}; + + phpPackage = package.buildEnv { + extensions = { all, enabled }: with all; enabled + ++ (lib.optional config.services.redis.enable redis) + ++ (lib.optional config.services.blackfire.enable blackfire) + ++ (lib.optional config.services.rabbitmq.enable amqp) + ++ lib.attrsets.attrValues (lib.attrsets.getAttrs cfg.additionalPhpExtensions package.extensions); + extraConfig = phpConfig; + }; + + phpXdebug = package.buildEnv { + extensions = { all, enabled }: with all; enabled + ++ [ xdebug ] + ++ (lib.optional config.services.redis.enable redis) + ++ (lib.optional config.services.rabbitmq.enable amqp) + ++ lib.attrsets.attrValues (lib.attrsets.getAttrs cfg.additionalPhpExtensions package.extensions); + extraConfig = phpConfig; + }; +in { + config = lib.mkIf cfg.enable { + languages.php = { + enable = lib.mkDefault true; + package = lib.mkDefault phpPackage; + + fpm.pools.web = { + settings = { + "clear_env" = "no"; + "pm" = "dynamic"; + "pm.max_children" = 10; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 1; + "pm.max_spare_servers" = 10; + }; + }; + fpm.pools.web.phpPackage = lib.mkDefault phpPackage; + + fpm.pools.xdebug = { + settings = { + "clear_env" = "no"; + "pm" = "dynamic"; + "pm.max_children" = 10; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 1; + "pm.max_spare_servers" = 10; + }; + }; + fpm.pools.xdebug.phpPackage = lib.mkDefault phpXdebug; + }; + }; +} diff --git a/modules/scripts.nix b/modules/scripts.nix new file mode 100644 index 0000000..f71b576 --- /dev/null +++ b/modules/scripts.nix @@ -0,0 +1,146 @@ +{ pkgs, config, inputs, lib, ... }: + +let + cfg = config.kellerkinder; + + entryScript = pkgs.writeScript "entryScript" '' + set -euo pipefail + + if [ ! -f $DEVENV_PROFILE/bin/mysqladmin ]; then + echo -e "mysqladmin missing, skips further entryscript processing" + ${pkgs.coreutils}/bin/sleep infinity + fi + + while ! $DEVENV_PROFILE/bin/mysqladmin ping --silent; do + ${pkgs.coreutils}/bin/sleep 1 + done + + while ! [[ $($DEVENV_PROFILE/bin/mysql shopware -s -N -e 'SHOW DATABASES LIKE "shopware";') ]] ; do + ${pkgs.coreutils}/bin/sleep 1 + done + + TABLE=$(mysql shopware -s -N -e 'SHOW TABLES LIKE "system_config";') + + if [[ $TABLE == "" ]]; then + echo "Table system_config is missing. Run >updateSystemConfig< manually to ensure the dev status of your setup!" + ${pkgs.coreutils}/bin/sleep infinity + fi + + ${scriptUpdateConfig} + + echo -e "Startup completed" + ${pkgs.coreutils}/bin/sleep infinity + ''; + + systemConfigEntries = lib.mapAttrsToList (name: value: { inherit name value; }) cfg.systemConfig; + + scriptUpdateConfig = pkgs.writeScript "scriptUpdateConfig" '' + VENDOR=${config.env.DEVENV_ROOT}/${cfg.projectRoot}/vendor/autoload.php + CONSOLE=${config.env.DEVENV_ROOT}/${cfg.projectRoot}/bin/console + + echo "Updating system config" + + if [ ! -f "$VENDOR" ] || [ ! -f "$CONSOLE" ]; then + echo "Vendor folder or console not found. Please run composer install." + exit 1 + fi + + # additional config + ${lib.concatMapStrings ({ name, value }: '' + $CONSOLE system:config:set ${name} ${value} || exit 1 + echo "System config ${name} set to ${value}" + '') systemConfigEntries} + + # default config + $CONSOLE system:config:set core.mailerSettings.emailAgent "" || exit 1 + echo "System config core.mailerSettings.emailAgent set to '''" + ''; + + importDbHelper = pkgs.writeScript "importDbHelper" '' + if [[ "$1" == "" ]]; then + echo "Please set devenv configuration for kellerkinder.importDatabaseDumps" + exit + fi + + if ! $DEVENV_PROFILE/bin/mysqladmin ping > /dev/null 2>&1; then + echo "MySQL server is dead or has gone away! devenv up?" + exit + fi + + TARGETFOLDER="${config.env.DEVENV_STATE}/importdb" + + rm -rf "$TARGETFOLDER" + set -e + + if [[ "$1" == *.sql ]]; then + ${pkgs.curl}/bin/curl -s --create-dirs "$1" --output "$TARGETFOLDER/latest.sql" + elif [[ "$1" == *.gz ]]; then + ${pkgs.curl}/bin/curl -s --create-dirs "$1" --output "$TARGETFOLDER/latest.sql.gz" + ${pkgs.gzip}/bin/gunzip -q -c "$TARGETFOLDER/latest.sql.gz" > "$TARGETFOLDER/dump.sql" + elif [[ "$1" == *.zip ]]; then + ${pkgs.curl}/bin/curl -s --create-dirs "$1" --output "$TARGETFOLDER/latest.sql.zip" + ${pkgs.unzip}/bin/unzip -qq -j -o "$TARGETFOLDER/latest.sql.zip" '*.sql' -d "$TARGETFOLDER" + else + echo "Unsupported file type for file at $1" + exit + fi + + rm -f "$TARGETFOLDER/latest.sql.*" + + SQL_FILE=$(find "$TARGETFOLDER" -name "*.sql" | head -n 1) + + if [[ "$SQL_FILE" == "" ]]; then + echo "No SQL file found" + exit + fi + + LANG=C LC_CTYPE=C LC_ALL=C ${pkgs.gnused}/bin/sed -i -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' "$SQL_FILE" + LANG=C LC_CTYPE=C LC_ALL=C ${pkgs.gnused}/bin/sed -i 's/NO_AUTO_CREATE_USER//' "$SQL_FILE" + + $DEVENV_PROFILE/bin/mysql shopware -f < "$SQL_FILE" + + echo "Import $1 finished!" + ''; +in { + # Config related scripts + scripts.updateSystemConfig.exec = '' + ${scriptUpdateConfig} + ''; + + # Symfony related scripts + scripts.cc.exec = '' + CONSOLE=${config.env.DEVENV_ROOT}/${cfg.projectRoot}/bin/console + + if test -f "$CONSOLE"; then + exec $CONSOLE cache:clear + fi + ''; + + scripts.uuid.exec = '' + ${pkgs.toybox}/bin/uuidgen | tr "[:upper:]" "[:lower:]" | sed 's/-//g' + ''; + + scripts.importdb.exec = '' + echo "Are you sure you want to download SQL files and overwrite the existing database with their data (y/n)?" + read answer + + if [[ "$answer" != "y" ]]; then + echo "Alright, we will stop here." + exit + fi + + ${lib.concatMapStrings (dump: '' + echo "Importing ${dump}" + ${importDbHelper} ${dump} + '') cfg.importDatabaseDumps} + + ${scriptUpdateConfig} + ''; + + scripts.debug.exec = '' + XDEBUG_SESSION=1 ${phpXdebug}/bin/php "$@" + ''; + + # Processes + processes.entryscript.exec = "${entryScript}"; +}