Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ jobs:
docker-library/php/config_files/xdebug \
docker-library/httpd/config_files/docker-entrypoint.sh

# `forge` exists so the common commands are one word; a README that teaches
# `docker compose up` instead is how it stayed undiscovered until someone
# installed the project and never found `forge help`. Prose about what CI
# validates may still say `docker compose config` -- that is not an instruction.
- name: the READMEs do not teach docker compose
run: |
fail=0
for pattern in 'docker compose up' 'docker compose logs' \
'docker compose stop' 'docker compose --profile' \
'docker compose build'; do
if grep -n "$pattern" README.md README.es.md; then
echo "^ use the forge command instead"; fail=1
fi
done
exit $fail

- name: the helper scripts compile
run: |
python3 -m py_compile .github/scripts/drive-install.py
Expand Down Expand Up @@ -141,6 +157,7 @@ jobs:
# unknown versions must be refused, not passed to docker
if forge use 9.9 2>/dev/null; then echo "9.9 should have been rejected"; exit 1; fi


- name: build images
# Every PHP version is built. 8.5 broke silently once: opcache became
# built-in and docker-php-ext-install started failing on it.
Expand Down Expand Up @@ -198,6 +215,29 @@ jobs:

# Hyphens in project names were broken for a long time: mi-app--sites
# resolved to sites/app/mi.
# Needs running containers, so it sits after the page is confirmed served
# rather than with the other forge checks, which run before the stack is up.
- name: forge logs reaches every container
run: |
export PATH="$HOME/.local/bin:$PATH"
# Counting distinct services, not looking for one name: compose prints
# logs for stopped containers too, so "apachedev appears" would pass even
# if the command had regressed to following a single container.
named() { grep -oE '^[a-z0-9]+ *\|' "$1" | tr -d ' |' | sort -u; }

timeout 5 forge logs > /tmp/all.log 2>&1 || true
all="$(named /tmp/all.log | wc -l)"
test "$all" -ge 3 || { echo "forge logs named $all services, expected the stack"; exit 1; }

# naming one narrows it to exactly that -- a service, not just a PHP
# version, which is what sent the README to `docker compose logs`
timeout 5 forge logs apachedev > /tmp/one.log 2>&1 || true
test "$(named /tmp/one.log)" = apachedev || {
echo "forge logs apachedev named: $(named /tmp/one.log | tr '\n' ' ')"; exit 1; }

if forge logs nope 2>/dev/null; then echo "unknown service accepted"; exit 1; fi
echo "forge logs: $all services with no argument, one when named"

- name: a hyphenated project name resolves
run: |
curl -fsS --resolve my-app--sites.phpforge.dev:443:127.0.0.1 \
Expand Down
81 changes: 57 additions & 24 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,14 @@ Y abre **https://welcome--sites.phpforge.dev**.

4. **Levanta el entorno:**
```bash
docker compose up -d
forge start
```
Comprueba que funciona: `https://welcome--sites.phpforge.dev`

## πŸ’» Uso

### ▢️ Arrancar y parar

```bash
forge start # levantar todo
forge stop
Expand All @@ -150,6 +152,11 @@ forge use 8.5 # cambiar la versiΓ³n por defecto
forge shell 8.4 # entrar a un contenedor
forge logs 8.4 # seguir sus logs

forge profile list # servicios opcionales, y cuΓ‘les estΓ‘n encendidos
forge profile on|off <nom> # encender o apagar uno
forge db list # las bases de datos entre ellos
forge mail on|off # un buzΓ³n de pruebas en mail.<dominio>

forge images build|pull # construir en local, o usar las publicadas
forge certs # regenerar los certificados
forge dns status # ver el DNS local
Expand All @@ -162,6 +169,12 @@ enlaza en `~/.local/bin`. Los argumentos de versiΓ³n aceptan `8.5` u `85`, y las
versiones disponibles salen de `docker-compose.yml` β€” aΓ±ade un servicio y
`forge use 8.6` funciona solo.

Es un envoltorio de `docker compose`, no un reemplazo: no esconde nada y los
comandos crudos siguen funcionando desde la carpeta del proyecto. Existe para que
lo que haces a diario sea una palabra, y para que lo que tiene truco β€” un enlace
relativo que los contenedores puedan seguir, nginx y Apache sin pelearse por el
puerto 80 β€” salga bien sin que tengas que acordarte de por quΓ©.

### 🌐 Tus proyectos

Viven en la carpeta que elegiste al instalar (`PROJECTS_DIR` en `.env`,
Expand Down Expand Up @@ -216,6 +229,13 @@ ln -s ../projects/mi-app/public ~/php-devforge/sites/mi-app
El enlace debe apuntar a la carpeta que contiene el `index.php` (el `public/` del
framework). El `.htaccess` funciona: `AllowOverride All` estΓ‘ activado.

### πŸ”„ DΓ­a a dΓ­a

- Edita el cΓ³digo en tu editor β€” los archivos estΓ‘n montados, los cambios son inmediatos
- No hay que reiniciar nada por un cambio de cΓ³digo
- Entra a un contenedor con `forge shell 8.4`
- Mira quΓ© estΓ‘ pasando con `forge logs`

### 🐞 Xdebug

Dentro del contenedor:
Expand All @@ -235,12 +255,15 @@ del stack; el resto de tu DNS no se toca, asΓ­ que apagar los contenedores nunca
sin internet.

```bash
./setup-local-dns.sh # aplicar
./setup-local-dns.sh --status # ver la configuraciΓ³n
./setup-local-dns.sh --test # comprobar la resoluciΓ³n
./setup-local-dns.sh --remove # deshacer: borra un archivo
forge dns setup # aplicar
forge dns status # ver la configuraciΓ³n
forge dns test # comprobar la resoluciΓ³n
forge dns remove # deshacer: borra un archivo
```

Llaman a `./setup-local-dns.sh`, que tambiΓ©n puedes ejecutar directamente con las
mismas opciones como `--banderas`.

dnsmasq escucha en `127.0.0.1:${DNS_PORT}` en vez del puerto 53, que suele estar
ocupado por systemd-resolved, Pi-hole o similar. El instalador busca uno libre y lo
escribe en `.env`.
Expand All @@ -264,7 +287,7 @@ upload_max_filesize = 100M
```

```bash
docker compose up -d --force-recreate php84dev
forge restart php84dev
```

Se lee *ademΓ‘s* de la configuraciΓ³n de la imagen, asΓ­ que no pisa nada y el interruptor
Expand Down Expand Up @@ -312,7 +335,8 @@ IMAGE_MODE=build # construir siempre en local
IMAGE_MODE=always # volver a descargar, para forzar la ΓΊltima publicada
```

DespuΓ©s, `docker compose up -d`.
DespuΓ©s, `forge start`. O sΓ‘ltate la ediciΓ³n: `forge images build` y
`forge images pull` ponen esa lΓ­nea y reinician por ti.

Elige `build` si editas algo dentro de `docker-library/`: tus cambios se recogen solos,
y la cachΓ© de Docker hace que no cueste nada cuando no hay cambios.
Expand Down Expand Up @@ -360,11 +384,13 @@ Algunos no se levantan por defecto. Llevan un `profile` de compose, asΓ­ que los
cuando los quieras:

```bash
docker compose --profile search up -d # Elasticsearch + Kibana
forge profile list # quΓ© existe, y quΓ© estΓ‘ encendido
forge profile on search # Elasticsearch + Kibana
forge profile off search
```

Los perfiles son cosa de compose, asΓ­ que este sigue siendo un comando de
`docker compose`; `forge start` cubre el conjunto por defecto.
El listado lee los archivos de compose, asΓ­ que se mantiene solo: cada fila muestra
las imΓ‘genes que arranca ese perfil.

| Perfil | Servicios | Notas |
|---|---|---|
Expand Down Expand Up @@ -393,8 +419,8 @@ prefieres nginx, estΓ‘ disponible β€” como alternativa, no como aΓ±adido, porque
quieren los puertos 80 y 443:

```bash
docker compose stop apachedev
docker compose --profile nginx up -d nginxdev
forge profile on nginx # para apachedev; no pueden compartir los puertos
forge profile off nginx # y lo devuelve
```

Sirve las mismas URLs, incluidas las rutas anidadas y el sufijo `--pNN`.
Expand All @@ -420,21 +446,28 @@ dentro de un contenedor; tu editor debe escuchar en el puerto **9003**.

## πŸ› Problemas comunes

- **El DNS no resuelve**: ejecuta `./setup-local-dns.sh --status` y `--test`. Puede
hacer falta reiniciar el navegador.
- **El certificado no es de confianza**: vuelve a ejecutar `./install_cert.sh` y
reinicia el navegador. Firefox tiene su propio almacΓ©n en Linux: instala `nss` (Arch)
o `libnss3-tools` (Debian/Ubuntu) y repite.
- **El DNS no resuelve**: ejecuta `forge dns status` y `forge dns test`. Puede hacer
falta reiniciar el navegador.
- **El certificado no es de confianza**: vuelve a ejecutar `forge certs` y reinicia el
navegador. Firefox tiene su propio almacΓ©n en Linux: instala `nss` (Arch) o
`libnss3-tools` (Debian/Ubuntu) y repite.
- **Los contenedores no arrancan**: comprueba que Docker estΓ© corriendo y que los
puertos 80 y 443 estΓ©n libres.
- **Problemas de permisos**: revisa que `PUID`/`PGID` en `.env` coincidan con los tuyos
(`id -u`, `id -g`) y recrea los contenedores.
- **No cambia la versiΓ³n de PHP**: revisa `PHP_VERSION` en `.env` (83, 84 u 85), o aΓ±ade
`--p83`/`--p84`/`--p85` al host.
- **`npm` muestra un aviso sobre pnpm**: es a propΓ³sito. npm sigue funcionando.
- **Problemas de permisos bajo `public_html`**: revisa que `PUID`/`PGID` en `.env`
coincidan con los tuyos (`id -u`, `id -g`) y haz `forge restart`. Los contenedores
adoptan esos ids al arrancar, asΓ­ que lo que escriben es tuyo.
- **No cambia la versiΓ³n de PHP**: revisa `PHP_VERSION` en `.env`, o aΓ±ade
`--p83`/`--p84`/`--p85` al nombre del host. `forge status` muestra la de por defecto.
- **`npm` muestra un aviso sobre pnpm**: es a propΓ³sito. npm sigue funcionando; aquΓ­ se
prefiere pnpm.
- **Un `.ini` de `custom/php.d/` parece ignorado**: recrea el contenedor con
`docker compose up -d --force-recreate php84dev`. Reiniciar no basta.
- **Los alias no funcionan**: asegΓΊrate de haber hecho `source aliases.bash`.
`forge restart php84dev`. Reiniciar no basta.
- **`forge: command not found`**: el instalador lo enlaza en `~/.local/bin`, que
algunos shells no tienen en el `PATH`. AΓ±Γ‘delo, o haz `source aliases.bash` desde la
carpeta del proyecto.

Para mΓ‘s ayuda, mira los logs con `forge logs` β€” o `forge logs apachedev` para un
servicio β€” o abre un issue en GitHub.

## 🀝 Contribuir

Expand Down
97 changes: 68 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Then open **https://welcome--sites.phpforge.dev**.

4. **Start the containers:**
```bash
docker compose up -d
forge start
```
Or `forge start`, which works from anywhere.

Expand All @@ -151,6 +151,11 @@ forge use 8.5 # set the default PHP version
forge shell 8.4 # open a shell in a container
forge logs 8.4 # follow its logs

forge profile list # optional services, and which are on
forge profile on|off <name> # turn one on or off
forge db list # the databases among them
forge mail on|off # a mail catcher at mail.<domain>

forge images build|pull # build locally, or use the published images
forge certs # regenerate the certificates
forge dns status # inspect the local DNS
Expand All @@ -162,6 +167,12 @@ forge help
`~/.local/bin`. Version arguments accept `8.5` or `85`, and the available versions
come from `docker-compose.yml` β€” add a service and `forge use 8.6` just works.

It is a wrapper around `docker compose`, not a replacement for it: nothing is
hidden and the raw commands still work from the project directory. It exists so
the things you do daily are one word, and so the ones with a trick to them β€” a
relative symlink the containers can follow, nginx and Apache not fighting over
port 80 β€” are right without you remembering why.

### 🌐 Accessing Your Projects

1. **Create project structure:**
Expand Down Expand Up @@ -224,10 +235,22 @@ come from `docker-compose.yml` β€” add a service and `forge use 8.6` just works.

### πŸ”„ Development Workflow

- Edit code in your IDE (files are volume-mounted for live updates)
- Changes appear immediately without restarting containers
- Use Xdebug for debugging (configure your IDE to listen on port **9003**, the Xdebug 3 default)
- Edit code in your editor β€” the files are volume-mounted, so changes are live
- Nothing to restart for a code change
- Open a shell in a container with `forge shell 8.4`
- Watch what is happening with `forge logs`

### 🐞 Xdebug

Inside a container:

```bash
xdebug # toggle it on or off
xdebug --force-activate
xdebug /path/script.php # run one script with it on, then turn it back off
```

Point your editor at port **9003**, the Xdebug 3 default.

## 🌐 Local DNS

Expand All @@ -236,12 +259,15 @@ the stack's dnsmasq; the rest of your DNS is untouched, so stopping the containe
never costs you internet access.

```bash
./setup-local-dns.sh # apply
./setup-local-dns.sh --status # show what is configured
./setup-local-dns.sh --test # check resolution
./setup-local-dns.sh --remove # undo: deletes one file
forge dns setup # apply
forge dns status # show what is configured
forge dns test # check resolution
forge dns remove # undo: deletes one file
```

These call `./setup-local-dns.sh`, which you can also run directly with the same
options as `--flags`.

dnsmasq listens on `127.0.0.1:${DNS_PORT}` rather than port 53, which is usually
taken by systemd-resolved, Pi-hole or similar. The installer picks a free port and
writes it to `.env`; change it there if you need to.
Expand All @@ -266,7 +292,7 @@ upload_max_filesize = 100M
```

```bash
docker compose up -d --force-recreate php84dev
forge restart php84dev
```

It is scanned *in addition to* the image's own config, so nothing is shadowed and
Expand Down Expand Up @@ -315,12 +341,13 @@ IMAGE_MODE=build # always build locally
IMAGE_MODE=always # re-pull every time, to force the newest published image
```

Then `docker compose up -d`.
Then `forge start`. Or skip the editing: `forge images build` and `forge images pull`
set that line and restart for you.

Pick `build` if you edit anything under `docker-library/`: your changes are picked
up automatically, and Docker's layer cache makes it cheap when nothing changed.
Either way `docker compose build` still builds on demand, and compose falls back
to building if an image cannot be pulled.
Either way an image still gets built on demand, and compose falls back to building
if one cannot be pulled.

**Note:** settings baked in at build time β€” `NODE_VERSION`, for instance β€” only
apply when you build. A pulled image already has them fixed.
Expand Down Expand Up @@ -365,11 +392,13 @@ Some services are not started by default. They carry a compose `profile`, so you
ask for them when you want them:

```bash
docker compose --profile search up -d # Elasticsearch + Kibana
forge profile list # what exists, and what is on
forge profile on search # Elasticsearch + Kibana
forge profile off search
```

Profiles are a compose feature, so this one stays a `docker compose` command;
`forge start` covers the default set.
The listing reads the compose files, so it stays right on its own: each row shows
the images that profile starts.

| Profile | Services | Notes |
|---|---|---|
Expand Down Expand Up @@ -398,8 +427,8 @@ would rather run nginx, it is there β€” as an alternative, not an addition, sinc
want ports 80 and 443:

```bash
docker compose stop apachedev
docker compose --profile nginx up -d nginxdev
forge profile on nginx # stops apachedev; they cannot share the ports
forge profile off nginx # and brings it back
```

It serves the same URLs, including nested paths and the `--pNN` version suffix.
Expand All @@ -425,18 +454,28 @@ container; your IDE should listen on port **9003**.

## πŸ› Troubleshooting

### ❓ Common Issues

- **DNS resolution not working**: Ensure you ran `./setup-local-dns.sh` and restarted your browser or system. You may need to flush DNS cache.
- **PHP version not switching**: check `PHP_VERSION` in `.env` (83, 84 or 85), or append `--p83`/`--p84`/`--p85` to the host. `forge status` prints the default.
- **`npm` prints a message about pnpm**: intentional. npm still runs; pnpm is preferred here.
- **An `.ini` in `custom/php.d/` seems ignored**: recreate the container, `docker compose up -d --force-recreate php84dev`. A restart alone does not re-read it.
- **SSL certificate not trusted**: Make sure you ran `./install_cert.sh` and restart your browser afterwards. Check the CA is present with `openssl verify -CAfile .caroot/rootCA.pem certificates/php-devforge.pem`. Firefox keeps its own trust store on Linux, so install `nss` (Arch) or `libnss3-tools` (Debian/Ubuntu) and re-run the script if Firefox still complains.
- **Containers not starting**: Check that Docker and Docker Compose are installed and running. Ensure ports 80 and 443 are not in use by other services.
- **Permission issues with public_html**: Check that `PUID`/`PGID` in `.env` match your own ids (`id -u`, `id -g`), then recreate the containers with `docker compose up -d --force-recreate`. The containers adopt those ids on startup, so files they write are owned by you.
- **Aliases not working**: Ensure you sourced `aliases.bash` or added it to your `~/.bashrc`.

For more help, check the logs with `docker compose logs` or create an issue on GitHub.
- **DNS not resolving**: run `forge dns status` and `forge dns test`. You may need to
restart your browser.
- **SSL certificate not trusted**: re-run `forge certs` and restart your browser.
Firefox keeps its own trust store on Linux: install `nss` (Arch) or `libnss3-tools`
(Debian/Ubuntu) and try again.
- **Containers not starting**: check Docker is running and that ports 80 and 443 are
free.
- **Permission issues under `public_html`**: check `PUID`/`PGID` in `.env` match your
own (`id -u`, `id -g`), then `forge restart`. The containers adopt those ids on
startup, so files they write belong to you.
- **PHP version not switching**: check `PHP_VERSION` in `.env`, or append
`--p83`/`--p84`/`--p85` to the host name. `forge status` prints the default.
- **`npm` prints a notice about pnpm**: deliberate. npm still works; pnpm is preferred
here.
- **An `.ini` in `custom/php.d/` seems ignored**: recreate the container with
`forge restart php84dev`. A plain restart does not re-read it.
- **`forge: command not found`**: the installer links it into `~/.local/bin`, which
some shells do not have on `PATH`. Add it, or `source aliases.bash` from the project
directory.

For more help, check the logs with `forge logs` β€” or `forge logs apachedev` for one
service β€” or open an issue on GitHub.

## 🀝 Contributing

Expand Down
Loading