Docker LEMP · 7 min read · Sep 24, 2025
Dockerizando el Stack LEMP con Docker-Compose en Ubuntu
Docker-Compose es una herramienta de línea de comandos para definir y gestionar aplicaciones docker de múltiples contenedores. Compose es un script de Python, se puede instalar fácilmente con el comando pip (pip es el comando para instalar software de Python desde el repositorio de paquetes de Python). Con compose, podemos ejecutar múltiples contenedores docker con un solo comando. Te permite crear un contenedor como un servicio, ideal para tu entorno de desarrollo, pruebas y preproducción.
En este tutorial, te guiaré paso a paso para usar docker-compose y crear un entorno de Stack LEMP (LEMP = Linux - Nginx - MySQL - PHP). Ejecutaremos todos los componentes en diferentes contenedores Docker, configuraremos un contenedor Nginx, un contenedor PHP, un contenedor PHPMyAdmin y un contenedor MySQL/MariaDB.
Requisitos previos
- Servidor Ubuntu 16.04 -64bit
- Privilegios de root
Paso 1 - Instalar Docker
En este paso, instalaremos Docker. Docker está disponible en el repositorio de Ubuntu, solo actualiza tu repositorio y luego instálalo.
Actualizar el repositorio de ubuntu y actualizar:
sudo apt-get update
sudo apt-get upgradeInstalar la última versión de Docker desde el repositorio de ubuntu.
sudo apt-get install -y docker.ioIniciar docker y habilitarlo para que se inicie al arrancar:
systemctl start docker
systemctl enable dockerLos servicios de Docker están en funcionamiento.
A continuación, puedes intentar usar docker con el comando a continuación para probarlo:
docker run hello-worldHola mundo desde docker.

Paso 2 - Instalar Docker-Compose
En el primer paso, ya hemos instalado Docker. Ahora instalaremos docker-compose.
Necesitamos python-pip para la instalación de compose, instala python y python-pip con apt:
sudo apt-get install -y python python-pipCuando la instalación haya finalizado, instala docker-compose con el comando pip.
pip install docker-composeAhora verifica la versión de docker-compose:
docker-compose --versionDocker-compose ha sido instalado.
Paso 3 - Crear y Configurar el Entorno Docker
En este paso, construiremos nuestro entorno docker-compose. Usaremos un usuario no root, así que necesitamos crear ese usuario ahora.
Agrega un nuevo usuario llamado ‘ hakase ‘ (elige tu propio nombre de usuario aquí si lo deseas):
useradd -m -s /bin/bash hakase
passwd hakaseA continuación, agrega el nuevo usuario al grupo ‘ docker ‘ y reinicia docker.
usermod -a -G docker hakase
sudo systemctl restart dockerAhora el usuario ‘ hakase ‘ puede usar docker sin sudo.
A continuación, desde el usuario root, inicia sesión en el usuario ‘hakase’ con su.
su - hakaseCrea un nuevo directorio para el entorno de compose.
mkdir lemp-compose/
cd lemp-compose/Este es nuestro entorno docker-compose, todos los archivos que deben estar en el contenedor Docker deben estar en este directorio. Cuando usamos docker-compose, necesitamos un archivo .yml llamado ‘ docker-compose.yml ‘.
En el directorio ‘lemp-compose’, crea algunos nuevos directorios y un archivo docker-compose.yml:
touch docker-compose.yml
mkdir -p {logs,nginx,public,db-data}- logs: Directorio para archivos de registro de Nginx.
- nginx: contiene la configuración de Nginx como el host virtual, etc.
- public: directorio para archivos web, index.html y archivo de información PHP.
- db-data: volumen del directorio de datos de MariaDB.
Crea los archivos de registro error.log y access.log en el directorio ‘ logs ‘.
touch logs/{error,access}.logCrea un nuevo archivo de configuración de host virtual de nginx en el directorio ‘ nginx ‘:
vim nginx/app.confPega la configuración a continuación:
upstream php {
server phpfpm:9000;
}
server {
server_name 193.70.36.50;
error_log "/opt/bitnami/nginx/logs/myapp-error.log";
access_log "/opt/bitnami/nginx/logs/myapp-access.log";
root /myapps;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi.conf;
fastcgi_intercept_errors on;
fastcgi_pass php;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}Guarda el archivo y sal de vim.
Crea un nuevo archivo index.html y un archivo de información PHP en el directorio ‘ public ‘.
echo 'LEMP Docker-Compose
hakase-labs' > public/index.html
echo '' > public/info.php
Ahora puedes ver el directorio del entorno como se muestra a continuación:
tree
Paso 4 - Configuración del archivo docker-compose.yml
En el paso anterior, hemos creado los directorios y archivos necesarios para nuestros contenedores. En este paso, queremos editar el archivo ‘ docker-compose.yml ‘. En el archivo docker-compose.yml, definiremos nuestros servicios para el stack LEMP, las imágenes base para cada contenedor y los volúmenes de docker.
Inicia sesión en el usuario ‘ hakase ‘ y edita el archivo docker-compose.yml con vim:
su - hakase
cd lemp-compose/
vim docker-compose.yml- Definir servicios Nginx
Pega la configuración de nginx a continuación:
nginx:
image: 'bitnami/nginx'
ports:
- '80:80'
links:
- phpfpm
volumes:
- ./logs/access.log:/opt/bitnami/nginx/logs/myapp-access.log
- ./logs/error.log:/opt/bitnami/nginx/logs/myapp-error.log
- ./nginx/app.conf:/bitnami/nginx/conf/vhosts/app.conf
- ./public:/myappsEn esa configuración, ya hemos definido:
- nginx: nombre del servicio
- image: estamos usando imágenes docker ‘ bitnami/nginx ‘
- ports: expone el puerto del contenedor 80 al puerto del host 80
- links: vincula el contenedor del servicio ‘ nginx ‘ al contenedor ‘ phpfpm ‘
- volumes: monta directorios locales en el contenedor. Monta el directorio de archivos de registro, monta la configuración del host virtual de Nginx y monta el directorio raíz web.
- Definir servicios PHP-fpm
Pega la configuración a continuación del bloque Nginx:
phpfpm:
image: 'bitnami/php-fpm'
ports:
- '9000:9000'
volumes:
- ./public:/myappsAquí definimos:
- phpfpm: define el nombre del servicio.
- image: define la imagen base para el servicio phpfpm con la imagen ‘ bitnami/php-fpm ‘.
- ports: Estamos ejecutando PHP-fpm con el puerto TCP 9000 y exponiendo el puerto 9000 al host.
- volumes: monta el directorio raíz web ‘ public ‘ en ‘ myapps ‘ en el contenedor.
- Definir el servicio MySQL
En el tercer bloque, pega la configuración a continuación para el contenedor del servicio MariaDB:
mysql:
image: 'mariadb'
ports:
- '3306:3306'
volumes:
- ./db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=hakase-labs123Aquí puedes ver que estamos usando:
- mysql: como el nombre del servicio.
- image: el contenedor se basa en imágenes docker ‘ mariadb ‘.
- ports: el contenedor del servicio usa el puerto 3306 para la conexión MySQL, y lo expone al host en el puerto 3306.
- volumes: directorio db-data mysql
- environment: establece la variable de entorno ‘ MYSQL_ROOT_PASSWORD ‘ para la contraseña de root de mysql en las imágenes docker, ejecutada al construir el contenedor.
- Configuración de servicios PHPMyAdmin
En el último bloque, pega la configuración a continuación:
phpmyadmin:
image: 'phpmyadmin/phpmyadmin'
restart: always
ports:
- '8080:80'
links:
- mysql:mysql
environment:
MYSQL_USERNAME: root
MYSQL_ROOT_PASSWORD: hakase-labs123
PMA_HOST: mysqlEstamos usando una imagen docker ‘phpmyadmin’, mapeando el puerto del contenedor 80 al 8080 en el host, vinculando el contenedor al contenedor mariadb, configurando reinicio siempre y estableciendo algunas variables de entorno de la imagen docker, incluyendo establecer ‘ PMA_HOST ‘.
Guarda el archivo y sal de vim.
Puedes ver el ejemplo completo en github.
Paso 5 - Ejecutar Docker-Compose
Ahora estamos listos para ejecutar docker-compose. Nota: cuando quieras ejecutar docker-compose, debes estar en el directorio del proyecto docker-compose y asegurarte de que hay un archivo yml con la configuración de compose.
Ejecuta el comando a continuación para iniciar el stack LEMP:
docker-compose up -d-d: ejecutando como demonio o en segundo plano
Verás el resultado de que se han creado los nuevos contenedores, verifícalo con el comando a continuación:
docker-compose ps
Ahora tenemos cuatro contenedores ejecutando Nginx, PHP-fpm, MariaDB y PHPMyAdmin.
Paso 6 - Pruebas
Verificando los puertos que están siendo utilizados por el proxy de docker en el host.
netstat -plntu
Podemos ver el puerto 80 para el contenedor Nginx, el puerto 3306 para el contenedor MariaDB, el puerto 9000 para el contenedor php-fpm y el puerto 8080 para el contenedor PHPMyAdmin.
Accede al puerto 80 desde el navegador web, y verás nuestro archivo index.html.
Asegúrate de que PHP-fpm esté en funcionamiento, accede a él desde el navegador web.
http://serverip-address/info.php

Accede al contenedor MySQL en el shell de MySQL.
docker-compose exec mysql bash
mysql -u root -p
ESCRIBE LA CONTRASEÑA MYSQL: hakase-labs123Ahora crea una nueva base de datos:
create database hakase_db;
exitEl contenedor del shell mysql de MariaDB es accesible, y hemos creado una nueva base de datos ‘ hakase_db ‘.

A continuación, accede a PHPMyAdmin en el puerto 8080: http://serverip-address:8080/.
Verás la página de inicio de sesión de PHPMyAdmin, solo escribe el nombre de usuario ‘ root ‘ y la contraseña es ‘ hakase-labs123 ‘.

Te conectarás automáticamente al contenedor mysql que ha sido definido en la variable de entorno PMA_HOST.
Haz clic en ‘ Ir ‘ y verás el panel de phpmyadmin que está conectado al contenedor ‘ mysql ‘.

¡Éxito! El Stack LEMP está funcionando bajo una configuración de docker-compose, consistiendo en cuatro contenedores.
Referencias
- https://hub.docker.com/r/bitnami/nginx/
- https://hub.docker.com/r/bitnami/php-fpm/
- https://hub.docker.com/_/mariadb/
- https://hub.docker.com/r/phpmyadmin/phpmyadmin/
- https://docs.docker.com/compose/
- https://github.com/yuzukiseo/hakase-labs/tree/master/lemp-compose
- https://www.howtoforge.com/tutorial/how-to-create-docker-images-with-dockerfile/
Recibe nuevas publicaciones en tu bandeja de entrada.
No spam. Cancela la suscripción en cualquier momento.