Con este artículo voy a empezar una pequeña serie de artículos sobre cómo desarrollar una aplicación utilizando Docker como nuestro entorno de desarrollo en local. En este primer post nos enfocaremos en crear, configurar y levantar nuestro entorno Docker.
¿Por qué Docker?
Según la tipología de nuestros proyectos y las necesidades de nuestros clientes, necesitamos disponer de entornos de desarrollo rápidos de configurar, levantar y escalar, en definitiva, entornos ágiles.
En los últimos 15 años la evolución en el mundo del desarrollo de aplicaciones web ha sido vertiginosa y con ella multitud de herramientas llegaron para facilitarnos la vida. Y la verdad es que hay multitud de opciones para todos los gustos. Entornos en local utilizando herramientas como XAMPP, WAMP o MAMP, utilizar VirtualBox o VMWare para crear máquinas virtuales de desarrollo, utilizar Vagrant para facilitar la configuración y el despliegues de nuestros entornos virtuales y el uso de entornos basados en contenedores, concretamente Docker.
Pero ¿Qué nos ofrece Docker?
Hasta ahora veníamos utilizando Vagrant con Virtualbox como nuestro entorno de desarrollo, pero con el tiempo han ido surgiendo carencias que necesitábamos resolver y se traducían en utilizar una herramienta que utilice eficientemente los recursos de nuestros equipos aportándonos agilidad y una mayor productividad en nuestros desarrollos.
Docker nos ofrece:
- Uso de los recursos nativos del sistema
- Rapidez de despliegues de entornos
- Entornos escalables
- Alta portabilidad de los entornos de desarrollo
- Entornos enfocados a proyectos
Crear un entorno de desarrollo local con Docker
A continuación vamos a crear una aplicación desde cero con un entorno de desarrollo portable. Para ello solamente es necesario tener Docker instalado en nuestro sistema anfitrión, tu PC o portátil, sea Windows, Linux o MacOS.
Arquitectura de nuestro entorno
Nuestro proyecto va a tener la siguiente estructura:

Definición del entorno con Docker Compose
En el archivo docker-compose.yml vamos a declarar y definir nuestros servicios, uno dedicado para la base de datos y otro para el servidor web.
version: '3'
services:
db:
container_name: ${APP_NAME}-database
image: ${DB_PROVIDER}:${DB_VERSION}
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- db_volume:/var/lib/mysql
ports:
- ${DB_PORT}:3306
networks:
net:
ipv4_address: 172.21.1.2
www:
build:
context: .docker/www
args:
- PHP_VERSION=${PHP_VERSION}
container_name: ${APP_NAME}-www
command: ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
tty: true
links:
- db:${DB_PROVIDER}
volumes:
- ${APP_DIR}:/var/www/html:cached
ports:
- ${HTTP_PORT}:80
- ${HTTPS_PORT}:443
networks:
net:
ipv4_address: 172.21.1.3
networks:
net:
driver: bridge
ipam:
config:
- subnet: 172.21.1.0/24
volumes:
db_volume:
Creando nuestro propio Dockerfile
Nuestro servicio dedicado para el servidor web utilizará un archivo Dockerfile, en el que ampliaremos una imagen Docker ya predefinida.
# Base image
FROM ubuntu:18.04
ARG PHP_VERSION
# Update repositories index
RUN apt update --fix-missing && apt upgrade -y
# Install util tools
RUN ln -snf /usr/share/zoneinfo/UTC /etc/localtime && echo "UTC" > /etc/timezone
RUN apt install -y apt-utils git rsync nano vim unzip curl wget software-properties-common mysql-client
# Install Ondrej PHP Multiversions
RUN add-apt-repository ppa:ondrej/php
RUN add-apt-repository ppa:ondrej/apache2
RUN apt-get update
RUN apt-get install -y php$PHP_VERSION
# Install Apache
RUN apt-get install -y apache2
# Install PHP extensions
RUN apt-get install -y -m php$PHP_VERSION-cli \
php$PHP_VERSION-dev \
php$PHP_VERSION-common \
php$PHP_VERSION-json \
php$PHP_VERSION-intl \
php$PHP_VERSION-curl \
php$PHP_VERSION-mysql \
php$PHP_VERSION-gd \
php$PHP_VERSION-imagick \
php$PHP_VERSION-ldap \
php$PHP_VERSION-soap\
php$PHP_VERSION-zip \
php$PHP_VERSION-mbstring \
php$PHP_VERSION-bcmath \
php$PHP_VERSION-xml \
php$PHP_VERSION-imap \
php$PHP_VERSION-bz2
# Install NodeJS and NPM
RUN apt-get install -y nodejs npm
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer
# Config Apache
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
RUN chown www-data:www-data -R /var/www
RUN chmod -R 755 /var/www
COPY config/000-default.conf /etc/apache2/sites-available/000-default.conf
COPY config/php.ini /etc/php/$PHP_VERSION/apache2/php.ini
RUN a2enmod rewrite headers
RUN service apache2 start
WORKDIR /var/www/html
EXPOSE 80
EXPOSE 443
Configurando nuestro entorno Docker
En el archivo .env definiremos las variables de configuración para nuestro entorno Docker. Este paso puede omitirse si queremos introducir todos estos valores directamente en el archivo docker-compose.yml, pero de esta forma si queremos alojar nuestro proyecto en algún repositorio tendremos expuestas variables de tipo credencial.
APP_NAME=app APP_DIR=. HTTP_PORT=80 HTTPS_PORT=443 DB_PORT=3306 PMA_PORT=8080 DB_PROVIDER=mariadb DB_VERSION=10.2 DB_ROOT_PASSWORD=root DB_USER=developer DB_PASSWORD=developer DB_NAME=appdb PHP_VERSION=7.1
Levantando nuestro nuestro entorno Docker
Una vez tenemos ya configurado nuestro entorno, abrimos la terminal y situándonos en la raíz de nuestro proyecto ejecutamos el siguiente comando:
docker-compose up --build -d
Este comando levanta nuestro entorno de trabajo, construyendo si fuera necesario y en segundo plano. Equivale a ejecutar los comandos:
docker-compose build && docker-compose up -d