Taula de continguts

Entorn de desenvolupament

La missió és aixecar un entorn de desenvolupament amb diversos serveis full-stack amb una sola comanda docker compose up i sense cap error.

En aquest exemple farem servir Vue (front), Laravel (back per a les APIs), NodeJS (back per habilitar sockets), Adminer (gestionar base de dades amb entorn gràfic) i MySQL (sistema de gestió de bases de dades relacional)

Per tant l'estructura de carpetes será minim

nom-projecte/
├── Back/                # Carpeta backend
│   ├── Dockerfile       # Dockerfile backend
│   ├── entrypoint.sh
    ├── node-app/
├── Front/               # Carpeta backend
│   ├── Dockerfile       # Dockerfile frontend
├── docker-compose.yml   # YAML del docker compose
└── README.md            # Documentació de projecte

Comandes necessaries per crear el projecte de 0

mkdir nom-projecte && cd nom-projecte

npm create vite@latest (nom de projecte: frontend)

composer create-project laravel/laravel backend

mkdir ./backend/node-app

touch ./backend/entrypoint.sh

touch ./docker-compose.yml


Instal·lació bàsica de Docker (Ubuntu)

Pots seguir la guía d'instal·lació en la documentació oficial de Docker.


Instalar Docker Compose V2

Docker Compose v2 és un complement integrat a Docker, però si no està habilitat, segueix aquests passos per instal·lar-lo:


Dockerfile

Un Dockerfile és un fitxer de text que conté un conjunt d'instruccions per construir una imatge. Aquestes imatges són plantilles que s'utilitzen per crear contenidors, els quals executen aplicacions de manera aïllada. Amb aixó automatitzas el procés de creació d'imatges.

FROM image:tag: Aquesta línia especifica la imatge base que es farà servir per construir la imatge Docker. En aquest cas, s'utilitza una imatge oficial de Node.js basada en la versió 18 i Alpine, que és una versió més lleugera de Linux. És ideal per mantenir el contenidor petit.

WORKDIR /app: Estableix el directori de treball dins del contenidor. Si el directori no existeix, Docker el crearà. Totes les ordres posteriors, com COPY, RUN, etc., s'executaran dins d'aquest directori.

COPY package*.json ./: Copia els fitxers package.json i package-lock.json des del directori de treball de la teva màquina al directori de treball del contenidor (/app). Això es fa abans de copiar la resta del projecte per aprofitar la cache de Docker i no haver d'instal·lar dependències cada vegada que es facin canvis en altres fitxers.

RUN npm install: Executeu l'ordre npm install dins del contenidor per instal·lar les dependències de Node.js que es van definir al fitxer package.json.

COPY . .: Copia tots els fitxers del directori actual de la teva màquina local al directori de treball dins del contenidor (/app).

EXPOSE 5173: Exposa el port 5173, que és el port per defecte utilitzat per Vite per servir l'aplicació en desenvolupament. Això fa que el contenidor estigui disponible en aquest port des de fora del contenidor.

CMD [«npm», «run», «dev», «–», «–host»]: Especifica l'ordre que s'executarà quan comenci el contenidor. En aquest cas, s'inicia el servidor de desenvolupament de Vite usant l'ordre npm run dev amb l'opció –host per permetre connexions des de fora del contenidor (útil si s'executa en un entorn de desenvolupament).

Front/Dockerfile
# Utilitzar una imatge base lleugera i estable
FROM node:18-alpine
 
# Establir el directori de treball al contenidor
WORKDIR /app
 
# Copiar només el package.json i package-lock.json
COPY package*.json ./
 
# Instal·lar les dependències
RUN npm install
 
# Copiar la resta dels arxius del projecte
COPY . .
 
# Exposar el port utilitzat per Vite
EXPOSE 5173
 
# Comanda per iniciar el servidor de desenvolupament amb hot-reload
CMD ["npm", "run", "dev", "--", "--host"]
Back/Dockerfile
#Preparem la imatge amb tot lo necessari per treballar amb php
 
RUN apt update && apt install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip
 
RUN apt clean && rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
 
# De la imatge oficial de composer agafem el binari i el posem a /usr/bin/composer
# d'aquest forma aconseguim una imatge amb php i composer i la podrem
# utilitzar per la nostra aplicació laravel
 
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

Docker Compose

Un fitxer docker-compose.yml és un fitxer de configuració que descriu els serveis, xarxes i volums que componen una aplicació Docker. Aquest fitxer està escrit en format YAML, s'utilitza per organitzar la configuració dels contenidors de manera estructurada.

Podrás aixecar tots els serveis amb una sola comanda: docker compose up o docker compose down per parar els serveis.

docker-compose.yml
services:
  db:
    image: mysql:8.2.0
    restart: always
    container_name: mysql
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: testdb
      MYSQL_USER: testuser
      MYSQL_PASSWORD: testpassword
    ports:
      - "3306:3306"
 
  adminer:
    image: adminer
    restart: always
    container_name: adminer
    depends_on:
      - db
    ports:
      - "9090:8080"
 
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: laravel
    ports:
      - "8000:8000" 
    volumes:
      - ./backend:/var/www/
    working_dir: /var/www/
    depends_on:
      - db
    command: bash -c "chmod +x entrypoint.sh && ./entrypoint.sh"
 
  frontend:
    build: 
      context: ./frontend
      dockerfile: Dockerfile
    container_name: vue
    ports:
      - "5173:5173"
    volumes:
      - ./frontend:/app
    environment:
      - NODE_ENV=development
    restart: unless-stopped
    command: sh -c "npm install && npm run dev -- --host"
 
  nodejs:
    image: node:18
    container_name: nodejs-service
    working_dir: /usr/src/app
    volumes:
      - ./backend/node-app:/usr/src/app
    ports:
      - "3000:3000"
    command: bash -c "npm install && npm start"
    environment:
      - NODE_ENV=development
    depends_on:
      - db
 
# Persistencia
volumes:
  mysql_data:

Dins de services, es defineixen els diferents contenidors que s'executaran a la teva aplicació.

db

adminer

backend

frontend

nodejs

volumes:
  mysql_data:

mysql_data: Defineix un volum persistent anomenat mysql_data. Aquest volum s'utilitza per emmagatzemar les dades de la base de dades MySQL, assegurant que les dades no es perdin quan el contenidor de la base de dades es reinicia.

Exemple de fitxer entrypoint.sh

entrypoint.sh
#!/bin/bash
set -e
 
# Instalar dependencias
composer install
 
# Crear el archivo .env si no existe
if [ ! -f .env ]; then
    cp .env.example .env
    chown 1000:1000 .env # Asignar permisos correctos
    php artisan key:generate
fi
 
# Ejecutar migraciones
php artisan migrate:fresh --seed
 
# Iniciar el servidor
php artisan serve --host=0.0.0.0 --port=8000

set -e: Aquesta opció fa que el script s'aturi immediatament si alguna comanda retorna un error (estat de sortida diferent de 0). Això ajuda a evitar que el contenidor continuï executant-se si alguna acció essencial falla.

Si el fitxer .env no es troba, crea una còpia del fitxer .env.example com a .env. Aixó eviarà que s'aturi l'execució del contenidor laravel per errors.

Assigna permisos correctes al fitxer .env per tal que l'usuari amb ID 1000 pugui accedir-hi (chown 1000:1000). Docker crea els fitxers com a root, es obligatori fer-ho si després vols editar el fitxer .env

Executa php artisan key:generate per generar una nova clau d'aplicació, la qual és essencial per a la seguretat de Laravel.

php artisan serve –host=0.0.0.0 –port=8000: Aixeca laravel al port 8000.

Per crear migrations, has de modificar el fitxer .env correctament. Està dins de ./backend/.env i entrar al adminer (http://localhost:9090).

.env
DB_CONNECTION=mysql
# DB_HOST=db
# DB_PORT=3306
# DB_DATABASE=testdb
# DB_USERNAME=testuser
# DB_PASSWORD=testpassword

Resum

Aquest fitxer docker-compose.yml configura i executa una aplicació amb múltiples serveis:

Base de dades MySQL. Adminer per gestionar la base de dades a través d'una interfície web. Backend amb Laravel. Frontend amb Vue.js. Node.js per algun servei relacionat amb el backend.

Cada contenidor té configuracions específiques com ports, volums i dependències.