diff --git a/nix-for-php-developers/.gitignore b/nix-for-php-developers/.gitignore new file mode 100644 index 0000000..9b61c8c --- /dev/null +++ b/nix-for-php-developers/.gitignore @@ -0,0 +1 @@ +/*.html diff --git a/nix-for-php-developers/NixOS.png b/nix-for-php-developers/NixOS.png new file mode 100644 index 0000000..99cdeea Binary files /dev/null and b/nix-for-php-developers/NixOS.png differ diff --git a/nix-for-php-developers/book.png b/nix-for-php-developers/book.png new file mode 100644 index 0000000..f377a7e Binary files /dev/null and b/nix-for-php-developers/book.png differ diff --git a/nix-for-php-developers/drupal-install.png b/nix-for-php-developers/drupal-install.png new file mode 100644 index 0000000..2853d58 Binary files /dev/null and b/nix-for-php-developers/drupal-install.png differ diff --git a/nix-for-php-developers/nix-logo.png b/nix-for-php-developers/nix-logo.png new file mode 100644 index 0000000..819402a Binary files /dev/null and b/nix-for-php-developers/nix-logo.png differ diff --git a/nix-for-php-developers/nix-search-php.png b/nix-for-php-developers/nix-search-php.png new file mode 100644 index 0000000..a35c2f2 Binary files /dev/null and b/nix-for-php-developers/nix-search-php.png differ diff --git a/nix-for-php-developers/nix-search-php2.png b/nix-for-php-developers/nix-search-php2.png new file mode 100644 index 0000000..74848cf Binary files /dev/null and b/nix-for-php-developers/nix-search-php2.png differ diff --git a/nix-for-php-developers/nix-search.png b/nix-for-php-developers/nix-search.png new file mode 100644 index 0000000..c5ca2b4 Binary files /dev/null and b/nix-for-php-developers/nix-search.png differ diff --git a/nix-for-php-developers/process-compose.png b/nix-for-php-developers/process-compose.png new file mode 100644 index 0000000..e886824 Binary files /dev/null and b/nix-for-php-developers/process-compose.png differ diff --git a/nix-for-php-developers/repology.png b/nix-for-php-developers/repology.png new file mode 100644 index 0000000..e68609f Binary files /dev/null and b/nix-for-php-developers/repology.png differ diff --git a/nix-for-php-developers/slides.md b/nix-for-php-developers/slides.md new file mode 100644 index 0000000..38a6e25 --- /dev/null +++ b/nix-for-php-developers/slides.md @@ -0,0 +1,803 @@ +--- +paginate: true +footer: oliverdavies.uk +--- + + + + + +# Nix for PHP Developers + +
+
+ +Oliver Davies (opdavies) + +https://www.oliverdavies.uk + + + +--- + +# About Me + +- PHP since 2007. +- Drupal since 2008. +- Full-time Linux since ~2015. +- Nix/NixOS since 2022. + + + +--- + + + +![bg fit](./book.png) + + + +--- + + + +# Who has PHP installed
on their computer? + +--- + + + +# Who has multiple versions
of PHP installed? + + + +--- + +# Installing PHP + +- WAMP (Windows), MAMP (macOS), XAMPP +- Homebrew (`brew install php`) +- `apt`, `dnf`, `yum`, `pacman` `yay` +- Laravel Herd/Sail +- Symfony CLI? +- Containers (Docker, Podman, LXC, etc) +- Virtual machines (VMWare, Virtualbox, etc) + + + +--- + + + +![](./NixOS.png) + + +--- + +# What is Nix? + +- Package manager with more than **120,000** packages (`nixpkgs`) +- Operating system with more than **20,000** packages (NixOS) +- Tool for declaratively building software reproducibly +- A functional domain-specific configuration language +- Home Manager, `nix-darwin`, `devenv` +- Started as a research project by Eelco Dolstra around 2003 + + + +--- + +![](./nix-search.png) + + + + + +--- + +![](./nix-search-php.png) + + + +--- + +![](./nix-search-php2.png) + + + +--- + +![bg fit](./repology.png) + + + + + +--- + +# Installing Nix + +https://nixos.org/download + +```sh +$ sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) \ + --daemon +``` + +Different instructions for Linux, macOS and Windows (WSL2). + +Different instructions for NixOS. + +```sh +$ nix --version + +nix (Nix) 2.28.4 +``` +--- + +``` +This installation tool will set up your computer with the Nix package +manager. This will happen in a few stages: + +1. Make sure your computer doesn't already have Nix. If it does, I + will show you instructions on how to clean up your old install. + +2. Show you what I am going to install and where. Then I will ask + if you are ready to continue. + +3. Create the system users (uids [30001..30032]) and groups (gid 30000) + that the Nix daemon uses to run builds. To create system users + in a different range, exit and run this tool again with + NIX_FIRST_BUILD_UID set. + +4. Perform the basic installation of the Nix files daemon. + +5. Configure your shell to import special Nix Profile files, so you + can use Nix. + +6. Start the Nix daemon. +``` + +--- + +# Installing PHP with Ubuntu + +```shell +$ apt update -y + +$ apt-get install php + +$ which php + +/usr/bin/php + +$ php -v + +PHP 8.3.6 (cli) (built: Jul 14 2025 18:30:55) +``` + +--- + +# Running PHP with Nix + +```shell +$ nix run nixpkgs#php \ + --extra-experimental-features 'nix-command flakes' \ + -- -v + +PHP 8.4.11 (cli) (built: Jul 29 2025 15:30:21) +``` + +```shell +$ nix shell nixpkgs#php \ + --extra-experimental-features 'nix-command flakes' + +$ which php +/nix/store/s4kv9bzqawhqcyjg9xm2hji3jap6d6kd-php-with-extensions-8.4.11/bin/php + +$ php -v + +PHP 8.4.11 (cli) (built: Jul 29 2025 15:30:21) +``` + + + +--- + +# Using a `shell.nix` file + +```nix +{ pkgs ? import {} }: + +pkgs.mkShell { + packages = with pkgs; [ + php + phpPackages.composer + phpactor + ]; +} +``` + +```shell +$ nix-shell shell.nix + +[nix-shell:~/my-project]$ composer -V + +Composer version 2.8.5 2025-01-21 15:23:40 +``` + +--- + +# Using a `flake.nix` file + +```nix +{ + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + outputs = inputs: + let + system = "x86_64-linux"; + pkgs = import inputs.nixpkgs { inherit system; }; + in { + devShells.${system}.default = (import ./shell.nix { + inherit pkgs; + }); + }; +} +``` + + + +--- + +# Using a `flake.nix` file + +```nix +{ + inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + outputs = inputs: + let + system = "x86_64-linux"; + pkgs = import inputs.nixpkgs { inherit system; }; + in { + devShells.${system}.default = pkgs.mkShell { + packages = with pkgs; [ + php + phpPackages.composer + phpactor + ]; + }; + }; +} +``` + + + +--- + +# Structure of a Flake-based project + +```shell +. +├── composer.json +├── composer.lock +├── flake.lock +├── flake.nix +├── output_dev +├── source +└── vendor +``` + +
+ +As well as **flake.nix**, we also get **flake.lock**. + +--- + +# Pinning packages + +```nix +# flake.nix + +inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11"; + nixpkgs-pinned.url = "github:nixos/nixpkgs/45570c299dc2"; +} +``` + +```nix +{ + let + pkgs-stable = import inputs.nixpkgs-stable { inherit system; }; + in { + packages = [ pkgs-stable.php ]; + }; +} +``` + + + +--- + +# Managing services + +With NixOS: + +```nix +services.mysql.enable = true; + +services.mysql.initialDatabases = [ + { name = "my_project"; } + { name = "another_project"; } +]; +``` + +
+ +Without NixOS: + + + +--- + +# Managing services + +```nix +{ + inputs = { + flake-parts.url = "github:hercules-ci/flake-parts"; + + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + + process-compose.url = "github:Platonic-Systems/process-compose-flake"; + + services.url = "github:juspay/services-flake"; + }; + + # ... +``` +--- + +# Managing services + +```nix +imports = [ + inputs.process-compose.flakeModule +]; + +perSystem = { config, lib, pkgs, ... }: { + process-compose."default" = { + imports = [ + inputs.services.processComposeModules.default + ]; + + services = { # ... }; + + settings.processes = { # ... }; +} +``` + +--- + +# Managing services + +```nix +services = { + mysql."mysql1" = { + enable = true; + + initialDatabases = [ + { name = "drupal_nix_flake_example"; } + ]; + }; +}; +``` + +--- + +# Managing services + +```nix +settings.processes = { + php = { + command = pkgs.writeShellApplication { + name = "php-local-server"; + + text = "${getExe php} -S 127.0.0.1:${toString webPort} -t web"; + }; + + depends_on."mysql1".condition = "process_healthy"; + }; +}; +``` + +--- + +# Managing services + +```nix + devShells.default = pkgs.mkShell { + inputsFrom = [ + config.process-compose."default".services.outputs.devShell + ]; + + nativeBuildInputs = with pkgs; [ + php + phpPackages.composer + ]; + }; +}; +``` + +
+ +Run `nix run .` and go to http://localhost:8000. + +--- + +![bg fit](./process-compose.png) + + + +--- + +![bg fit](./drupal-install.png) + + + +--- + +# Multiple PHPs + +- Laravel Herd/Sail +- Containers +- `phpenv`, `brew-php-switcher`, `phpbrew` +- Vagrant +- VMWare, VirtualBox +- Different physical machines? + + + +--- + + + +# Nix is like `nvm`
for everything + +--- + +# My ideal environment + +```shell +$ php -v + +The program 'php' is currently not installed. + +$ cd ~/my-project + +$ php -v + +PHP 8.4.10 (cli) (built: Jul 2 2025 02:22:42) + +$ cd ~/another-project + +$ php -v + +PHP 8.3.24 (cli) (built: Jul 29 2025 15:48:33) +``` + +--- + +# Using direnv + +https://direnv.net + +> It augments existing shells with a new feature that can load and unload environment variables depending on the current directory. + +
+ +In NixOS: + +```nix +{ + programs.direnv.enable = true; + programs.direnv.nix-direnv.enable = true; +} +``` + +--- + +# The .envrc file + +If you have a `flake.nix`: + +```bash +use flake +``` + +Using a remote Flake: + +```bash +use flake "git+https://code.oliverdavies.uk/opdavies/dev-shells#php84" +``` + +```bash +use flake "github:opdavies/dev-shells#php84" +``` + +--- + +# Packaging for Nix + +```nix +stdenv.mkDerivation (finalAttrs: { + pname = "hello"; + version = "2.12.2"; + + src = fetchurl { + url = "mirror://gnu/hello/hello-${finalAttrs.version}.tar.gz"; + hash = "sha256-WpqZbcKSzCTc9BHO6H6S9qrluNE72caBm0x6nc4IGKs="; + }; + + env = lib.optionalAttrs stdenv.hostPlatform.isDarwin { + NIX_LDFLAGS = "-liconv"; + }; + + doCheck = true; + doInstallCheck = true; + + # ... +``` + +--- + +# Packaging for Nix + +```nix +pkgs.writeShellApplication { + name = "preview"; + + runtimeInputs = with pkgs.nodePackages; [ + browser-sync + ]; + + text = '' + browser-sync start + --ignore '**/.*' \ + --no-notify \ + --no-ui \ + -sw + ''; +} +``` + + + +--- + +# Packaging PHP for Nix + +```nix +php.buildComposerProject2 (finalAttrs: { + pname = "phpactor"; + version = "2025.07.25.0"; + + src = fetchFromGitHub { + owner = "phpactor"; + repo = "phpactor"; + tag = finalAttrs.version; + hash = "sha256-9XWlWwq+xvqPgKIc7IGoMVTxajjYsrPo/ra/0JIE168="; + }; + + vendorHash = "sha256-3xkt0QjytW4BOCgZdevat7zkSuZTPPvwz3yptiq5zoo="; + + # ... +``` + +--- + +# Packaging PHP for Nix + +```nix +php.buildComposerProject2 (finalAttrs: { + pname = "pest"; + version = "3.7.4"; + + src = fetchFromGitHub { + owner = "pestphp"; + repo = "pest"; + tag = "v${finalAttrs.version}"; + hash = "sha256-ddsdVx/Vsg7GG11fGASouBU3HAJLSjs1AQGHx52TWzA="; + }; + + composerLock = ./composer.lock; + vendorHash = "sha256-rOJ6PFp4Xfe89usoH455EAT30d2Tu3zd3+C/6K/kGBw="; + + # ... +``` + +--- + +# Packaging Sculpin + +Packaging Sculpin was essentially the same: + +https://code.oliverdavies.uk/opdavies/lab/src/branch/main/nix/sculpin + +```shell +nix build + +./result/bin/sculpin generate +``` + +```shell +. +├── flake.lock +├── flake.nix +├── output_dev +│   └── index.html +└── source + └── index.md +``` + + + +--- + +# Thanks! + +- https://nixos.org +- https://github.com/nixos/nixpkgs +- https://wiki.nixos.org/wiki/PHP +- https://nixos.org/manual/nixpkgs/stable/#ssec-building-php-projects +- https://code.oliverdavies.uk/opdavies/lab +- https://code.oliverdavies.uk/opdavies/drupal-nix-flake-example +- https://code.oliverdavies.uk/opdavies/nix-config (laptop and home server) +- https://books.oliverdavies.uk/nix-for-php-developers (book, in progress)