Automated commit

Signed-off-by: Oliver Davies <oliver@oliverdavies.uk>
This commit is contained in:
Oliver Davies 2025-08-19 22:30:33 +01:00
parent 7a7604d330
commit d509e167da
11 changed files with 804 additions and 0 deletions

1
nix-for-php-developers/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/*.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View file

@ -0,0 +1,803 @@
---
paginate: true
footer: oliverdavies.uk
---
<style>
section {
place-content: start;
}
h1, a {
color: #24608a;
}
</style>
<style scoped>
section {
place-content: center;
}
h1 {
ont-size: 2rem;
}
</style>
# Nix for PHP Developers
<br>
<br>
Oliver Davies (opdavies)
https://www.oliverdavies.uk
<!-- _paginate: false -->
---
# About Me
- PHP since 2007.
- Drupal since 2008.
- Full-time Linux since ~2015.
- Nix/NixOS since 2022.
<!--
PHP and Drupal Development. Linux-based infrastructure and systems administration. Automation.
Vagrant, Puppet, Ansible.
-->
---
<style scoped>
section {
background: #021330;
}
</style>
![bg fit](./book.png)
<!--
_footer: ''
_paginate: false
-->
---
<style scoped>
section {
place-content: center;
}
h1 {
font-size: 2rem;
text-align: center;
}
</style>
# Who has PHP installed<br> on their computer?
---
<style scoped>
section {
place-content: center;
}
h1 {
font-size: 2rem;
text-align: center;
}
</style>
# Who has multiple versions<br> of PHP installed?
<!--
Who has different projects that need different versions of PHP or needs to support multiple versions of PHP?
-->
---
# 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)
<!--
There are a lot of different ways to install PHP.
Different package managers for different Linux distributions.
Any other ways?
-->
---
<style scoped>
section {
display: grid;
place-content: center;
}
</style>
![](./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 !== NixOS
Similar to Homebrew, apt, etc.
Similar to Ansible.
Ecosystem of tools. Home Manager for user home configuration, nix-darwin for managing macOS.
-->
---
![](./nix-search.png)
<!--
_footer: ''
_paginate: false
-->
<!--
Can select from a stable release or unstable.
Unstable is more recently updated.
Two major releases a year in May and November (e.g. 24.11, 25.05).
-->
---
![](./nix-search-php.png)
<!--
_footer: ''
_paginate: false
-->
---
![](./nix-search-php2.png)
<!--
_footer: ''
_paginate: false
-->
---
![bg fit](./repology.png)
<!--
Number of total packages vs fresh packages.
-->
<!--
_footer: ''
_paginate: false
-->
---
# 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)
```
<!--
Install vs run.
Applications are placed in the Nix store and added to $PATH.
Arbitrary commands and ephemeral shells.
-->
---
# Using a `shell.nix` file
```nix
{ pkgs ? import <nixpkgs> {} }:
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;
});
};
}
```
<!--
Can import shell.nix.
-->
---
# 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
];
};
};
}
```
<!--
Packages can be inlined.
-->
---
# Structure of a Flake-based project
```shell
.
├── composer.json
├── composer.lock
├── flake.lock
├── flake.nix
├── output_dev
├── source
└── vendor
```
<br>
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 ];
};
}
```
<!--
You can have multiple versions of Nix installed at once.
Pin to a stable version of nixpkgs or a specific commit.
Could even use "master", which is newer than "unstable".
-->
---
# Managing services
With NixOS:
```nix
services.mysql.enable = true;
services.mysql.initialDatabases = [
{ name = "my_project"; }
{ name = "another_project"; }
];
```
<br>
Without NixOS:
<https://github.com/juspay/services-flake>
---
# 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
];
};
};
```
<br>
Run `nix run .` and go to http://localhost:8000.
---
![bg fit](./process-compose.png)
<!--
_footer: ''
_paginate: false
-->
---
![bg fit](./drupal-install.png)
<!--
_footer: ''
_paginate: false
-->
---
# Multiple PHPs
- Laravel Herd/Sail
- Containers
- `phpenv`, `brew-php-switcher`, `phpbrew`
- Vagrant
- VMWare, VirtualBox
- Different physical machines?
<!--
Software that allows you to have multiple versions of PHP installed and the ability to switch between them.
Any other ways?
-->
---
<style scoped>
section {
display: grid;
place-content: center;
}
h1 {
font-size: 3rem;
}
</style>
# Nix is like `nvm`<br> 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.
<br>
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
'';
}
```
<!--
Explicit dependencies. More shareable and no need to remember what's installed elsewhere.
-->
---
# 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
```
<!--
---
# Building Nix packages
```shell
$ nix repl
Nix 2.28.4
Type :? for help.
nix-repl> :l .
Added 24244 variables.
nix-repl> :b phpactor
This derivation produced the following outputs:
out -> /nix/store/nhq4js2lsj8lb1cz6dj4vrf6xb2r2zbd-phpactor-2025.03.28.0
```
```shell
/nix/store/nhq4js2lsj8lb1cz6dj4vrf6xb2r2zbd-phpactor-2025.03.28.0/bin/phpactor
Phpactor 2025.03.28.0
```
-->
---
# 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)