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.
- Desinstal·lar paquets per evitar qualsevol conflicte
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
- 1. Configura el repositori apt de Docker
# Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
- 2. Instal·lar l'última versió
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- 3. Comproveu que la instal·lació sigui correcta executant la imatge hello-world:
sudo docker run hello-world
- 4. Per evitar fer sudo, agrega el teu usuari al grup docker
sudo usermod -aG docker $USER
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:
- 1. Crea la carpeta on anirà el plugin
mkdir -p ~/.docker/cli-plugins/
- 2. Descarrega l'última versió del binari de Docker Compose
curl -SL https://github.com/docker/compose/releases/download/v2.27.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
Nota: Canvia v2.27.2 per l'última versió disponible. Consulta Docker Compose per veure la més actual.
- 3. Donar permissos d'execució al fitxer
chmod +x ~/.docker/cli-plugins/docker-compose
- 4. Comproveu que Docker Compose v2 està funcionant
docker compose version
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
- image: Utilitza la imatge oficial de MySQL (mysql:8.2.0).
- restart: La política always reinicia el contenidor automàticament si s'atura.
- container_name: El contenidor tindrà el nom mysql.
- volumes: Crea un volum persistent (mysql_data) per emmagatzemar les dades de la base de dades de manera que no es perdin quan el contenidor es reinicia.
- ports: Exposa el port 3306 del contenidor al port 3306 de la màquina local. Permet accedir a la base de dades des de fora del contenidor.
adminer
- image: Utilitza la imatge oficial d'Adminer, una eina web per gestionar bases de dades.
- restart: Es reinicia sempre que sigui necessari.
- depends_on: Defineix que el servei adminer depèn que el servei db (la base de dades) estigui en execució primer.
- ports: Exposa el port 8080 del contenidor al port 9090 de la màquina local. Adminer serà accessible a través de localhost:9090.
backend
- build: Indica que s'ha de construir la imatge Docker per al backend des del directori ./backend utilitzant el Dockerfile especificat allà.
- container_name: El contenidor serà anomenat laravel.
- ports: Mapeja el port 8000 del contenidor al port 8000 de la màquina local, on s'executarà Laravel.
- volumes: Mapeja el directori ./backend de la màquina local al directori /var/www/ dins del contenidor. Això permet editar el codi del backend directament des de la teva màquina.
- working_dir: Defineix el directori de treball dins del contenidor (/var/www/).
- depends_on: Aquest servei depèn del contenidor db (base de dades).
- command: Executa un script anomenat entrypoint.sh per configurar el contenidor i l'entorn del backend. Abans d'executar-lo, li dona permisos d'execució a aquest script amb chmod +x.
frontend
- build: Similar al servei backend, construeix la imatge Docker per al frontend des del directori ./frontend utilitzant el Dockerfile.
- container_name: El contenidor serà anomenat vue.
- ports: Mapeja el port 5173 del contenidor al port 5173 de la màquina local. Això permet que l'aplicació Vue s'executi a localhost:5173.
- volumes: Mapeja el directori ./frontend de la màquina local al directori /app al contenidor.
- environment: Defineix una variable d'entorn NODE_ENV=development per indicar que l'entorn és de desenvolupament. (opcional)
- restart: La política unless-stopped reinicia el contenidor a menys que s'aturi manualment.
- command: Executa una comanda que instal·la les dependències amb npm install i després executa l'aplicació Vue en mode desenvolupament amb npm run dev – –host.
nodejs
- image: Utilitza la imatge oficial de Node.js (node:18).
- container_name: El contenidor serà anomenat nodejs-service.
- working_dir: Estableix el directori de treball dins del contenidor (/usr/src/app).
- volumes: Mapeja el directori ./backend/node-app de la màquina local al directori /usr/src/app al contenidor.
- ports: Exposa el port 3000 del contenidor al port 3000 de la màquina local.
- command: Executa un script que instal·la les dependències de Node.js amb npm install i després inicia l'aplicació amb npm start.
- environment: Defineix l'entorn com a desenvolupament amb la variable NODE_ENV=development. (opcional)
- depends_on: Aquest servei depèn de la base de dades (db).
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.
