Automated commit
Signed-off-by: Oliver Davies <oliver@oliverdavies.uk>
1
nix-for-php-developers/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/*.html
|
BIN
nix-for-php-developers/NixOS.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
nix-for-php-developers/book.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
BIN
nix-for-php-developers/drupal-install.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
nix-for-php-developers/nix-logo.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
nix-for-php-developers/nix-search-php.png
Normal file
After Width: | Height: | Size: 230 KiB |
BIN
nix-for-php-developers/nix-search-php2.png
Normal file
After Width: | Height: | Size: 234 KiB |
BIN
nix-for-php-developers/nix-search.png
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
nix-for-php-developers/process-compose.png
Normal file
After Width: | Height: | Size: 172 KiB |
BIN
nix-for-php-developers/repology.png
Normal file
After Width: | Height: | Size: 124 KiB |
803
nix-for-php-developers/slides.md
Normal 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>
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
_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>
|
||||
|
||||

|
||||
|
||||
|
||||
---
|
||||
|
||||
# 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.
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
_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).
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
_footer: ''
|
||||
_paginate: false
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
_footer: ''
|
||||
_paginate: false
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
_footer: ''
|
||||
_paginate: false
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
_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)
|