Hola!, he vuelto a la comunidad haha, hace un tiempo llevo desarollando otro script y me dió por instalar PHPost para ver como ha evolucionado y si puedo ayudar a mejorar en mis tiempos libres, como hoy que me ha entrado las ganas de instalar el script en mi server con docker y si alguno necesita un paso a paso de como hacerlo, esta es la guía definitiva, me gustaría que si hay mejoras o correcciones de typo por ejemplo, o mejoras en cuanto a docker me escriban, por ahora, nada más que decir, solamente agradecer a los desarrolladores que siguieron aquí haciendo posible esta comunidad.Guía completa: PHPost (Risus Nova) con Docker desde cero
Te digo exactamente qué archivos crear, con qué nombre, dónde guardarlos y qué escribir dentro de cada uno. Copia, pega y listo.
Funciona igual en Windows, Linux y Mac. No necesitas instalar PHP, ni MySQL, ni Apache: Docker lo trae todo dentro.
La estructura final (esto es lo que vamos a construir)
Cuando termines, tendrás esto:
phpost/
│
├── Script/ ← el script Risus Nova
│ ├── index.php
│ ├── config.inc.php
│ ├── install/
│ ├── files/
│ └── ... (todo el contenido del script)
│
├── docker/ ← carpeta que TÚ creas
│ ├── Dockerfile
│ ├── php.ini
│ ├── vhost.conf
│ └── entrypoint.sh
│
├── docker-compose.yml ← archivo que TÚ creas
├── .env.example ← archivo que TÚ creas (plantilla)
├── .env ← copia de .env.example con tus contraseñas
└── .dockerignore ← archivo que TÚ creasEn total tienes que crear 7 archivos (más la carpeta
docker/Paso 0: prepara la carpeta base
- Crea una carpeta para el proyecto. La llamaré pero puedes ponerle el nombre que quieras.Código: ( Seleccionar Todo )
phpost/
- Descarga Risus Nova de Debes agradecer para ver el contenido... e inserta todo el contenido del script dentro de una subcarpeta llamada
.Código: ( Seleccionar Todo )Script/
- Crea una carpeta vacía llamada al lado deCódigo: ( Seleccionar Todo )
docker/
.Código: ( Seleccionar Todo )Script/
phpost/
├── Script/ ← con el script dentro
└── docker/ ← vacía de momentoArchivo 1 de 7 - docker/Dockerfile
- Nombre:
(sin extensión)Código: ( Seleccionar Todo )Dockerfile
- Dónde: dentro de la carpeta
Código: ( Seleccionar Todo )docker/ - Ruta:
Código: ( Seleccionar Todo )phpost/docker/Dockerfile
FROM php:8.2-apache
# --- Extensiones de sistema necesarias para GD y utilidades ---
RUN apt-get update && apt-get install -y --no-install-recommends \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libwebp-dev \
libonig-dev \
libzip-dev \
libssl-dev \
curl \
unzip \
&& rm -rf /var/lib/apt/lists/*
# --- Extensiones PHP obligatorias/recomendadas (REQUISITOS.txt) ---
# mysqli, mbstring, gd, json(core), session(core), fileinfo(core),
# openssl(core), curl, zip
RUN docker-php-ext-configure gd \
--with-freetype \
--with-jpeg \
--with-webp \
&& docker-php-ext-install -j"$(nproc)" \
mysqli \
mbstring \
gd \
zip
# --- Apache: mod_rewrite + mod_headers (URLs limpias y cabeceras) ---
RUN a2enmod rewrite headers
# --- Config PHP a valores recomendados ---
COPY docker/php.ini /usr/local/etc/php/conf.d/zz-phpost.ini
# --- VirtualHost con AllowOverride All para que funcione el .htaccess ---
COPY docker/vhost.conf /etc/apache2/sites-available/000-default.conf
# --- Entrypoint: fija permisos de carpetas escribibles al arrancar ---
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
CMD ["apache2-foreground"]Qué hace: parte de PHP 8.2 con Apache, instala las extensiones obligatorias (
mysqligdmbstringzipmod_rewriteCita:💡 GD se configura con
antes de instalarse, o no podrá generar miniaturas ni avatares.Código: ( Seleccionar Todo )--with-freetype --with-jpeg --with-webp
Archivo 2 de 7 - docker/php.ini
- Nombre:
Código: ( Seleccionar Todo )php.ini - Dónde: dentro de
Código: ( Seleccionar Todo )docker/ - Ruta:
Código: ( Seleccionar Todo )phpost/docker/php.ini
REQUISITOS.txt; Valores recomendados por PHPost / Risus Nova (REQUISITOS.txt)
upload_max_filesize = 8M
post_max_size = 8M
max_execution_time = 60
memory_limit = 128M
; allow_url_fopen: comprobador de versiones, login Google, Discord, StopForumSpam
allow_url_fopen = On
; Zona horaria (ajusta a tu region)
date.timezone = "Europe/Madrid"
expose_php = OffCita:El
es importante: sin él pierdes el comprobador de versiones, el login con Google, las notificaciones de Discord y Stop Forum Spam.Código: ( Seleccionar Todo )allow_url_fopen = On
Archivo 3 de 7 - docker/vhost.conf
- Nombre:
Código: ( Seleccionar Todo )vhost.conf - Dónde: dentro de
Código: ( Seleccionar Todo )docker/ - Ruta:
Código: ( Seleccionar Todo )phpost/docker/vhost.conf
AllowOverride All.htaccess<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory /var/www/html>
Options +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>Archivo 4 de 7 - docker/entrypoint.sh
- Nombre:
Código: ( Seleccionar Todo )entrypoint.sh - Dónde: dentro de
Código: ( Seleccionar Todo )docker/ - Ruta:
Código: ( Seleccionar Todo )mi-phpost/docker/entrypoint.sh
#!/bin/bash
set -e
# Carpetas que deben tener permisos de escritura (REQUISITOS.txt)
WRITABLE_DIRS=(
"cache"
"templates_c"
"files/uploads"
"files/images"
"files/avatar"
"files/posts"
"themes"
"inc/smarty/templates_c"
)
cd /var/www/html
for dir in "${WRITABLE_DIRS[@]}"; do
mkdir -p "$dir" 2>/dev/null || true
chown -R www-data:www-data "$dir" 2>/dev/null || true
chmod -R 777 "$dir" 2>/dev/null || true
done
exec "$@"Cita:⚠️ MUY IMPORTANTE en Windows: guarda este archivo con saltos de línea LF (Unix), NO CRLF (Windows). Si lo guardas en formato Windows, el contenedor no arrancará y dará un error raro tipo
. En VS Code lo cambias en la esquina inferior derecha: haz clic donde poneCódigo: ( Seleccionar Todo )exec format error
y eligeCódigo: ( Seleccionar Todo )CRLF
.Código: ( Seleccionar Todo )LF
Archivo 5 de 7 — docker-compose.yml
- Nombre:
Código: ( Seleccionar Todo )docker-compose.yml - Dónde: en la raíz del proyecto (al lado de
yCódigo: ( Seleccionar Todo )Script/
)Código: ( Seleccionar Todo )docker/
- Ruta:
Código: ( Seleccionar Todo )mi-phpost/docker-compose.yml
services:
# ---------------------------------------------------------------
# Aplicacion: PHP 8.2 + Apache (Risus Nova / PHPost)
# ---------------------------------------------------------------
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: phpost_app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "${APP_PORT:-8080}:80"
volumes:
# Codigo del script (uploads persisten en el host)
- ./Script:/var/www/html
environment:
TZ: ${TZ:-Europe/Madrid}
networks:
- phpost
# ---------------------------------------------------------------
# Base de datos: MariaDB 10.11
# ---------------------------------------------------------------
db:
image: mariadb:10.11
container_name: phpost_db
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MARIADB_DATABASE: ${DB_NAME}
MARIADB_USER: ${DB_USER}
MARIADB_PASSWORD: ${DB_PASSWORD}
TZ: ${TZ:-Europe/Madrid}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 10
networks:
- phpost
# ---------------------------------------------------------------
# Cron: llama a cron.php de forma periodica (opcional)
# Activar con: docker compose --profile cron up -d
# ---------------------------------------------------------------
cron:
image: curlimages/curl:latest
container_name: phpost_cron
restart: unless-stopped
depends_on:
- app
profiles: ["cron"]
entrypoint: >
sh -c "while true; do
curl -s -o /dev/null Registrate o inicia tu sesión para ver este contenido || true;
sleep ${CRON_INTERVAL:-300};
done"
networks:
- phpost
# ---------------------------------------------------------------
# phpMyAdmin (opcional, gestion de BD)
# Activar con: docker compose --profile tools up -d
# ---------------------------------------------------------------
phpmyadmin:
image: phpmyadmin:latest
container_name: phpost_pma
restart: unless-stopped
depends_on:
- db
profiles: ["tools"]
ports:
- "${PMA_PORT:-8081}:80"
environment:
PMA_HOST: db
UPLOAD_LIMIT: 64M
networks:
- phpost
volumes:
db_data:
driver: local
networks:
phpost:
driver: bridgeDetalles que importan:
- -> la app espera a que MySQL esté realmente listo.Código: ( Seleccionar Todo )
depends_on ... condition: service_healthy
- Los servicios yCódigo: ( Seleccionar Todo )
cron
tienenCódigo: ( Seleccionar Todo )phpmyadmin
, así que NO arrancan salvo que tú los pidas (más abajo te explico cómo).Código: ( Seleccionar Todo )profiles
Archivo 6 de 7 - .env.example
- Nombre:
Código: ( Seleccionar Todo ).env.example - Dónde: en la raíz del proyecto
- Ruta:
Código: ( Seleccionar Todo )mi-phpost/.env.example
# -------- Puertos host --------
APP_PORT=8080 # Registrate o inicia tu sesión para ver este contenido
PMA_PORT=8081 # phpMyAdmin (perfil tools)
# -------- Base de datos --------
# Estos valores son los que introduces en el instalador web.
# Hostname de BD en el instalador = db (nombre del servicio)
DB_NAME=phpost
DB_USER=phpost
DB_PASSWORD=cambia_esta_password
DB_ROOT_PASSWORD=cambia_esta_root_password
# -------- Cron (perfil cron) --------
CRON_INTERVAL=300 # segundos entre llamadas a cron.php
# -------- Zona horaria --------
TZ=America/BogotaArchivo 7 de 7 - .dockerignore
- Nombre:
Código: ( Seleccionar Todo ).dockerignore - Dónde: en la raíz del proyecto
- Ruta:
Código: ( Seleccionar Todo )mi-phpost/.dockerignore
.git
*.md
CHANGELOG.txt
LEEME.txt
REQUISITOS.txt
*.url
.envComprobación: ¿tienes todo?
Antes de arrancar, revisa que tu carpeta tiene estos archivos y esta estrucutra:
phpost/
├── Script/ ← el script (ya lo tenías)
├── docker/
│ ├── Dockerfile ✔ archivo 1
│ ├── php.ini ✔ archivo 2
│ ├── vhost.conf ✔ archivo 3
│ └── entrypoint.sh ✔ archivo 4 (¡en formato LF!)
├── docker-compose.yml ✔ archivo 5
├── .env.example ✔ archivo 6
└── .dockerignore ✔ archivo 7Ahora solamente falta arrancar el proyecto
Abre una terminal dentro de la carpeta
phpost/# 1. Crea tu .env real a partir de la plantilla
cp .env.example .envAhora edita el
.envDB_PASSWORDDB_ROOT_PASSWORDCita:🔑 Para generar una contraseña segura:
(en Linux, Mac o Git Bash de Windows).Código: ( Seleccionar Todo )openssl rand -base64 18
# 2. Construye y arranca todo
docker compose up -d --build- La web está en Debes agradecer para ver el contenido...
- La base de datos corriendo por dentro
Cita:docker compose ps
Debes ver
phpost_appphpost_dbUphealthyEl instalador web
Abre Debes agradecer para ver el contenido... y sigue el asistente.
Permisos de archivos
El instalador comprobará los permisos de las carpetas. Gracias al
entrypoint.shdocker compose restart appDatos de la base de datos
Aquí es donde falla casi todo el mundo. Pon exactamente esto:
[img]Registrate o inicia tu sesión para ver este contenido[/img]
El error nº1: poner "localhost"
En Docker cada contenedor es como un ordenador independiente. Si pones
localhostdbGrábate esto: el servidor de la base de datos es
dblocalhost¿Dónde se guardan mis datos? (volúmenes)
Un contenedor es efímero: si lo borras, se lleva todo lo de dentro. Por eso los datos importantes viven fuera, en volúmenes. En este montaje hay dos:
- Base de datos → volumen
. Todos los usuarios, posts y comentarios viven en un volumen que gestiona Docker. Aunque borres y recrees el contenedor, la BD sigue ahí. Solo se pierde conCódigo: ( Seleccionar Todo )db_data
.Código: ( Seleccionar Todo )docker compose down -v
- Código y subidas → carpeta
de tu PC (bind-mountCódigo: ( Seleccionar Todo )Script/
). Esto tiene dos ventajas:Código: ( Seleccionar Todo )./Script:/var/www/html- Editas un archivo en tu ordenador y el cambio se ve al instante en la web.
- Los avatares, imágenes y posts que suben los usuarios se guardan en tu carpeta
, no dentro del contenedor. Así que sobreviven a cualquier cosa.Código: ( Seleccionar Todo )Script/files/
- Editas un archivo en tu ordenador y el cambio se ve al instante en la web.
Comandos del día a día
docker compose ps # ver qué está corriendo
docker compose logs -f app # ver logs de PHP/Apache
docker compose exec app bash # entrar al contenedor
docker compose restart app # reiniciar solo la app
docker compose down # parar todo (conserva los datos)
docker compose down -v # parar y BORRAR la base de datos ⚠️
docker compose up -d --build # reconstruir tras cambiar el DockerfileEspero que les sirva bastante. Dudas y mejoras en los comentarios, saludos!


Facebook
Twitter
Reddit
Digg
del.icio.us
Tumblr
Pinterest
Blogger
Fark
LinkedIn
Mix
Google