diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ed4085 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Devenv +nixpress/.devenv* +nixpress/devenv.local.nix + +# direnv +nixpress/.direnv + +# pre-commit +nixpress/.pre-commit-config.yaml + +# WordPress site +/html/ +/vendor/ +# Devenv +nixpress/.devenv* +nixpress/devenv.local.nix + +# direnv +nixpress/.direnv + +# pre-commit +nixpress/.pre-commit-config.yaml diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 3b1ad5d..0000000 --- a/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -MIT License - -Copyright (c) 2025 kenny - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO -EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 1eee613..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# nixos-shells - -Dev shells ready to rumble \ No newline at end of file diff --git a/nixpress/.gitignore b/nixpress/.gitignore new file mode 100644 index 0000000..ba5a6e3 --- /dev/null +++ b/nixpress/.gitignore @@ -0,0 +1,22 @@ +# Devenv +.devenv* +devenv.local.nix + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml + +# WordPress site +/html/ +/vendor/ +# Devenv +.devenv* +devenv.local.nix + +# direnv +.direnv + +# pre-commit +.pre-commit-config.yaml diff --git a/nixpress/README.md b/nixpress/README.md new file mode 100644 index 0000000..9e11f4f --- /dev/null +++ b/nixpress/README.md @@ -0,0 +1,45 @@ +# nixpress + +> 🌀 Reproducible WordPress + PHP + Nginx development environment powered by Nix Flakes + +![Wordpress Home Screen](./screenshots/wordpress.png) + + +**nixpress** is a Nix-based development stack for WordPress and PHP applications, designed with NixOS users in mind. It provides a declarative, reproducible setup using Nix Flakes, making it easy to spin up a complete local environment with: + +- ✅ WordPress +- ✅ PHP (with extensions) +- ✅ Nginx +- ✅ MariaDB (MySQL-compatible) +- ✅ Redis +- ✅ TLS via Caddy (optional) + +--- + +## 🚀 Features + +- 📦 **Fully reproducible** using Nix flakes +- 🐘 PHP + Nginx with FastCGI support +- 📚 WordPress auto-installable setup +- 🧠 Redis for caching support +- 🔒 Optionally supports TLS using mkcert & Caddy +- 🔧 Easy to extend and customize + +--- + +## 🛠 Requirements + +- [Nix](https://nixos.org/download.html) with flakes enabled +- NixOS (recommended) +- `git`, `mkcert` (optional for TLS) + +--- + +## 🔧 Getting Started + +Clone the repo and enter the dev shell: + +```bash +git clone https://github.com/SoftEng-Islam/nixpress +cd nixpress +devenv up diff --git a/nixpress/composer.json b/nixpress/composer.json new file mode 100644 index 0000000..f201e81 --- /dev/null +++ b/nixpress/composer.json @@ -0,0 +1,21 @@ +{ + "type": "project", + "repositories": [ + { + "type": "composer", + "url": "https://wpackagist.org" + } + ], + "config": { + "allow-plugins": { + "composer/installers": true + } + }, + "extra": { + "installer-paths": { + "html/wp-content/mu-plugins/{$name}": ["type:wordpress-muplugin", "wpackagist-plugin/more-privacy-options"], + "html/wp-content/plugins/{$name}": ["type:wordpress-plugin"], + "html/wp-content/themes/{$name}": ["type:wordpress-theme"] + } + } +} \ No newline at end of file diff --git a/nixpress/composer.lock b/nixpress/composer.lock new file mode 100644 index 0000000..001b84b --- /dev/null +++ b/nixpress/composer.lock @@ -0,0 +1,18 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "265c7497cc8040f3cc44e561abd226ab", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/nixpress/conf/nginx/locations b/nixpress/conf/nginx/locations new file mode 100644 index 0000000..59a3200 --- /dev/null +++ b/nixpress/conf/nginx/locations @@ -0,0 +1,23 @@ +location / { + try_files $uri $uri/ /index.php?$args ; +} + +location ~ /\.ht { + deny all; +} + +location = /favicon.ico { + log_not_found off; + access_log off; +} + +location = /robots.txt { + allow all; + log_not_found off; + access_log off; +} + +location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + expires max; + log_not_found off; +} \ No newline at end of file diff --git a/nixpress/devenv.lock b/nixpress/devenv.lock new file mode 100644 index 0000000..19b569e --- /dev/null +++ b/nixpress/devenv.lock @@ -0,0 +1,100 @@ +{ + "nodes": { + "devenv": { + "locked": { + "dir": "src/modules", + "lastModified": 1733525154, + "owner": "cachix", + "repo": "devenv", + "rev": "d74232153d60ccdeba6f41eec8ce8b2be0b33ac6", + "type": "github" + }, + "original": { + "dir": "src/modules", + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1733328505, + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1733477122, + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "7bd9e84d0452f6d2e63b6e6da29fe73fac951857", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1746537231, + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "fa466640195d38ec97cf0493d6d6882bc4d14969", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/nixpress/devenv.nix b/nixpress/devenv.nix new file mode 100644 index 0000000..b816497 --- /dev/null +++ b/nixpress/devenv.nix @@ -0,0 +1,129 @@ +{ pkgs, lib, config, inputs, ... }: +let + listen_port = 8012; + server_name = "localhost"; +in { + # https://devenv.sh/basics/ + env.WORDPRESS_VERSION = "6.8.1"; + env.WORDPRESS_REPO = "https://github.com/WordPress/WordPress"; + env.GREET = "devenv"; + + # https://devenv.sh/packages/ + packages = [ pkgs.git pkgs.wp-cli ]; + + # https://devenv.sh/languages/ + # Configure PHP + languages.php.package = pkgs.php83.buildEnv { + extensions = ({ enabled, all }: enabled ++ (with all; [ yaml ])); + extraConfig = '' + sendmail_path = ${config.services.mailpit.package}/bin/mailpit sendmail + smtp_port = 1025 + upload_max_filesize = 64M + post_max_size = 64M + max_execution_time = 300 + ''; + }; + languages.php.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; + }; + }; + languages.php.enable = true; + + # https://devenv.sh/processes/ + # processes.cargo-watch.exec = "cargo-watch"; + + # https://devenv.sh/services/ + # MySQL + services.mysql = { + enable = true; + initialDatabases = [{ name = "wordpress"; }]; + ensureUsers = [{ + name = "wordpress"; + password = "wordpress"; + ensurePermissions = { "wordpress.*" = "ALL PRIVILEGES"; }; + }]; + }; + + # NGINX + services.nginx = { + enable = true; + httpConfig = '' + server { + listen ${toString listen_port}; + root ${config.devenv.root}/html; + index index.php index.html; + server_name ${server_name}; + + # ✅ Increase max upload size + client_max_body_size 64M; + + # Rewrite rules + if (!-e $request_filename) { + rewrite /wp-admin$ $scheme://$host$request_uri/ permanent; + rewrite ^(/[^/]+)?(/wp-.*) $2 last; + rewrite ^(/[^/]+)?(/.*\.php) $2 last; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_pass unix:${config.languages.php.fpm.pools.web.socket}; + include ${pkgs.nginx}/conf/fastcgi.conf; + } + '' + (builtins.readFile ./conf/nginx/locations) + "}"; + }; + + # Mailpit + services.mailpit = { enable = true; }; + + # https://devenv.sh/scripts/ + scripts.hello.exec = '' + echo hello from $GREET + ''; + + # Sets up local WordPress core + enterShell = '' + test -d html || git clone --depth 1 --branch ${config.env.WORDPRESS_VERSION} ${config.env.WORDPRESS_REPO} html + composer install + php --version + ''; + + processes.open-url.exec = '' + echo "🚀 WordPress is running at: http://${server_name}:${ + toString listen_port + }" + + if command -v xdg-open > /dev/null; then + xdg-open http://${server_name}:${toString listen_port} + elif command -v open > /dev/null; then + open http://${server_name}:${toString listen_port} + else + echo "⚠️ Could not auto-open browser." + fi + + # Prevent the process from exiting immediately so it's visible in logs + sleep 600 + ''; + + # https://devenv.sh/tasks/ + # tasks = { + # "myproj:setup".exec = "mytool build"; + # "devenv:enterShell".after = [ "myproj:setup" ]; + # }; + + # https://devenv.sh/tests/ + enterTest = '' + echo "Running tests" + git --version | grep --color=auto "${pkgs.git.version}" + ''; + + # https://devenv.sh/pre-commit-hooks/ + # pre-commit.hooks.shellcheck.enable = true; + + # See full reference at https://devenv.sh/reference/options/ +} diff --git a/nixpress/devenv.yaml b/nixpress/devenv.yaml new file mode 100644 index 0000000..116a2ad --- /dev/null +++ b/nixpress/devenv.yaml @@ -0,0 +1,15 @@ +# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json +inputs: + nixpkgs: + url: github:cachix/devenv-nixpkgs/rolling + +# If you're using non-OSS software, you can set allowUnfree to true. +# allowUnfree: true + +# If you're willing to use a package that's vulnerable +# permittedInsecurePackages: +# - "openssl-1.1.1w" + +# If you have more than one devenv you can merge them +#imports: +# - ./backend diff --git a/nixpress/screenshots/wordpress.png b/nixpress/screenshots/wordpress.png new file mode 100644 index 0000000..a620d6a Binary files /dev/null and b/nixpress/screenshots/wordpress.png differ diff --git a/nixpress/testdev.nix b/nixpress/testdev.nix new file mode 100644 index 0000000..9bd4fa7 --- /dev/null +++ b/nixpress/testdev.nix @@ -0,0 +1,62 @@ +{ pkgs, config, ... }: + +{ + packages = with pkgs; [ git wp-cli ]; + + languages.php.enable = true; + languages.php.package = pkgs.php82.buildEnv { + extensions = { all, enabled }: + with all; + enabled ++ [ redis pdo_mysql xdebug ]; + extraConfig = '' + memory_limit = -1 + xdebug.mode = debug + xdebug.start_with_request = yes + xdebug.idekey = vscode + xdebug.log_level = 0 + max_execution_time = 0 + ''; + }; + + languages.php.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; + }; + }; + + certificates = [ "wp.localhost" ]; + + # This lets Caddy bind to 443 + scripts.caddy-setcap.exec = '' + sudo setcap 'cap_net_bind_service=+ep' ${pkgs.caddy}/bin/caddy + ''; + services.redis.enable = true; + + # Links to MariaDB internally + services.mysql = { + enable = true; + settings.mysqld = { max_allowed_packet = "512M"; }; + }; + + services.mysql.initialDatabases = [{ name = "wp"; }]; + services.mysql.ensureUsers = [{ + name = "wordpress"; + password = "YourSecretSauceHere"; + ensurePermissions = { "wp.*" = "ALL PRIVILEGES"; }; + }]; + + services.caddy.enable = true; + services.caddy.virtualHosts."wp.localhost" = { + extraConfig = '' + tls ${config.env.DEVENV_STATE}/mkcert/wp.localhost.pem ${config.env.DEVENV_STATE}/mkcert/wp.localhost-key.pem + root * . + php_fastcgi unix/${config.languages.php.fpm.pools.web.socket} + file_server + ''; + }; +} diff --git a/rust.nix b/rust.nix index ca0f09d..71d44fa 100644 --- a/rust.nix +++ b/rust.nix @@ -1,12 +1,12 @@ let # Pinned nixpkgs, deterministic. Last updated: 2/12/21. #pkgs = import (fetchTarball("https://github.com/NixOS/nixpkgs/archive/a58a0b5098f0c2a389ee70eb69422a052982d990.tar.gz")) {}; - # Rolling updates, not deterministic. - pkgs = import (fetchTarball("channel:nixpkgs-unstable")) {}; -in pkgs.mkShell { - buildInputs = [ pkgs.cargo pkgs.rustc pkgs.zsh pkgs.bacon ]; - shellHook = '' - exec zsh - ''; -} + pkgs = import (fetchTarball "channel:nixpkgs-unstable") {}; +in + pkgs.mkShell { + buildInputs = [pkgs.cargo pkgs.rustc pkgs.zsh pkgs.bacon]; + shellHook = '' + exec zsh + ''; + }