diff --git a/.gitignore b/.gitignore index d303c376..9f8d27e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # Byte-compiled / optimized / DLL files +.DS_Store __pycache__/ *.py[cod] *$py.class diff --git a/docker/DOCKER.md b/docker/DOCKER.md new file mode 100644 index 00000000..8dfdb702 --- /dev/null +++ b/docker/DOCKER.md @@ -0,0 +1,233 @@ +# Apprendre Docker + +- [Apprendre Docker](#apprendre-docker) + - [Dockerfile et image](#dockerfile-et-image) + - [Docker container](#docker-container) + - [Docker Compose](#docker-compose) + - [Commandes de base](#commandes-de-base) + - [Communication entre les conteneurs](#communication-entre-les-conteneurs) +- [Aller plus loin](#aller-plus-loin) + - [Images de base](#images-de-base) + - [Multi-stage builds](#multi-stage-builds) + - [Docker registry](#docker-registry) + - [Développer depuis un conteneur](#développer-depuis-un-conteneur) + - [Kubernetes](#kubernetes) + +## Dockerfile et image + +Le Dockerfile définit l'environnement de l'application: +- l'image de base avec le nom puis le tag/la variante: `FROM ubuntu:latest`, `FROM python:3.8`, `FROM node:alpine` +- la préparation de l'environnement avec des commandes à exécuter: `RUN pip install -r requirements.txt`, `RUN npm install`, `RUN apt install`, `RUN rm -rf` +- la choix du répertoire de travail: `WORKDIR /app`, `WORKDIR /home` +- la copie de fichiers locaux vers le futur conteneur: pour copier tout le répertoire local dans le répertoire `WORKDIR` on peut utiliser `COPY . .`, `COPY requirements.txt /app` +- les variables d'environnement: `ENV NODE_ENV=production`, `ENV PORT=8080` +- l'exposition de ports: `EXPOSE 8080`, `EXPOSE 5000 4000 3000` +- les commandes à lancer lors du démarrage du conteneur: + 1. la commande par défaut: `ENTRYPOINT ["python"]` + 2. les arguments par défaut: `CMD ["file.py"]` + +Pour build l'image, on utilise la commande `docker build`. Le paramètre `-t` spécifie le nom de l'image puis `:` de son tag, qui peut être la version de l'image, ou sa variante selon l'OS (debian, ubuntu, alpine, windowsservercore). Le paramètre `.` spécifie le context du build, c'est-à-dire le répertoire context qui est nécessaire aux instructions de `COPY`. Le paramètre `-f` permet de spécifier un Dockerfile avec un nom et dans un répertoire spécifique. + +Exemple de Dockerfile: +``` +FROM python:3.8 + +WORKDIR /app + +COPY . . + +RUN apt update && apt install -y ca-certificates +RUN pip install -r requirements.txt + +ENV PORT=8080 + +EXPOSE 8080 + +ENTRYPOINT ["python"] +CMD ["file.py] +``` + +Exemples de commandes de build: +``` +docker build -t python_app . +docker build -t python_app:2.0 . +docker build -t python_app -f ../Dockerfile.different.name . +``` + +Pour lister les images: +``` +docker images +docker image ls +``` + +Pour supprimer une image: +``` +docker rmi image_name +docker image rm image_name +``` + +## Docker container + +Une fois l'image du conteneur créée, on peut instancier un conteneur basé sur cette image. On utilise pour cela la commande `docker run`. +Les paramètres les plus répandus sont: +- `-it`: interactive + tty permet apres le lancement du conteneur d'y ouvrir un terminal. En utilisant `-idt`, `-d` signifiant 'detached', il est possible de lancer un conteneur sans terminal, et qui passe directement en arrière-plan. +- `--name`: nom du conteneur. Plusieurs conteneurs ne peuvent pas partager un même nom. +- `-v`: volume(s) à partager. `$PWD:/app` veut dire que le répertoire local est monté sur le répertoire `/app` du conteneur. Créer, modifier et supprimer un fichier dans un des répertoires entraîne la même action dans l'autre. Par défaut, les conteneurs sont totalement isolés du système local, et leur stockage est éphémère et n'est pas conservé lorsque le conteneur est supprimé. +- `-p`: port(s) à forward. Le conteneur est isolé et pour pouvoir accéder à une application du conteneur tournant sur un certain port, il faut le rediriger vers le port de la machine locale. `8080:80` signifie que le port `80` du conteneur est redirigé vers le port `8080` de la machine locale. +- `--env`: une variable d'environnement qui sera exportée par le conteneur à son lancement. Par exemple `--env VAR1=value1`. +- `--env-file`: un fichier de variables d'environnement. Par exemple `--env-file .env`. +- l'image du conteneur doit être spécifiée en avant-dernier ou dernier argument +- une commande peut être spécifiée pour le lancement du conteneur. Par exemple, utiliser `/bin/sh` devrait toujours fonctionner et permettre d'ouvrir un terminal. + +Exemple: +``` +docker run --name python_app -it -p 8080:8080 python_app +docker run --name python_app -it -p 8080:8080 python_app /bin/sh +docker run --name python_app -it -v $PWD:/home -p 8080:8080 -p 5000:5000 python_app +``` + +Pour lister les conteneurs actifs: +``` +docker ps +docker container ls +``` + +Pour lister les conteneurs actifs et inactifs: +``` +docker ps -a +docker container ls -a +``` + +Pour checker les logs du conteneur: `docker logs container_name` + +Pour checker les logs continus du conteneur: `docker logs -f container_name` + +Pour stopper un conteneur: `docker stop container_name` + +Pour supprimer un conteneur: `docker rm container_name` + +Pour supprimer un conteneur avec force, sans qu'il ait besoin d'être stoppé avant: `docker rm -f container_name` + +Pour se rattacher à un conteneur, par exemple lorsque l'on a quitté le terminal du conteneur: +`docker attach container_name` + +## Docker Compose + +Docker Compose est un outil de Docker permettant d'orchestrer, de manager plusieurs conteneurs à la fois. C'est utile lorsque ces conteneurs forment ensemble une application et nécessitent de communiquer entre eux. + +On peut citer deux méchanismes importants: +- facilement lancer et stopper les conteneurs qui forment l'application +- permettre la communication entre des conteneurs isolés + +### Commandes de base + +D'abord, voici un exemple d'une configuraiton `docker-compose.yml`: +``` +version: "3.8" +services: + api: + build: + context: ./api-example + volumes: + - ./api-example/:/app + ports: + - "5000:5000" + frontend: + build: + context: ./frontend-example + volumes: + - ./frontend-example/:/app + ports: + - "8080:8080" +``` + +Paramètres de configuration: +- version: il existe plusieurs [versions de Docker Compose](https://docs.docker.com/compose/compose-file/compose-versioning/) que l'on peut spécifier. Certaines acceptent des paramètres de configuration, d'autres non. +- services: sous ce paramètre, on a une liste de conteneurs. Par défaut, ce sont les noms des conteneurs. +- par service: on retrouve des paramètres similaires au Dockerfile comme le port, le volume, les variables d'environnement. En plus de cela, le paramètre `build` permet de spécifier comment cette image doit être buildée; avec quel contexte, quel nom de Dockerfile. Si l'on utilise une image prébuildée, il est possible de spécifier `image` à la place de `build`. + +Pour lancer le Docker Compose: `docker-compose up` +Pour lister les conteneurs du Docker Compose: `docker-compose ps` +Pour lancer le Docker Compose en arrière-plan: `docker-compose up -d` +Pour lancer le Docker Compose et rebuild les images: `docker-compose up --build` +Pour lancer le Docker Compose et rebuild l'image d'un conteneur en particulier: `docker-compose up --build api` +Pour stopper le Docker Compose: `docker-compose down` +Pour suivre les logs du Docker Compose: `docker-compose logs -f` +Pour relancer le Docker Compose: `docker-compose restart` +Pour ouvrir un terminal dans le container du Docker Compose: `docker-compose exec api /bin/sh` + +### Communication entre les conteneurs + +Comme les conteneurs sont tous isolés les uns des autres, il n'est pas possible de communiquer depuis une API avec une database comme on le fait en développement local, comme par exemple avec l'adresse `localhost:5432`. Docker Compose propose une fonctionnalité de DNS, Domain Name System, qui associe l'IP + le port d'un conteneur avec son nom. Ainsi, communiquer depuis le frontend avec la database se fait tout simplement avec `db`. + +Il y a un exception pour le frontend client-side. Comme il est côté client, le navigateur ne peut par exemple pas comprendre `api` dont l'adresse est résolue par Docker Compose, mais pas par la machine locale. Du point de vue du navigateur, l'API est donc `localhost:5000`, et c'est cette adresse qu'il faut utiliser lors d'une requête faite depuis le frontend. + +# Aller plus loin + +## Images de base + +La première ligne du Dockerfile est l'image de base. Elle peut indiquer le langage de programmation utilisé: Python, Golang, Java, Ruby. Elle peut spécifier la version de ce langage: python:3.8, python:3.7, python:3. Elle peut spécifier le système d'exploitation: buster, bullseye (deux versions de Debian), windowsservercore, alpine. + +En particulier, [Alpine Linux](https://alpinelinux.org/about/) tourne exclusivement sur conteneur et est très populaire pour son poids léger (moins de 6 MB), sa simplicité et sa sécurité sans sacrifier sa capacité à être la base de la majorité des conteneurs livrés en production. + +## Multi-stage builds + +Chaque ligne d'un Dockerfile ajoute une couche à l'image. Il est possible de composer un Dockerfile avec plusieurs stages ou couches avec l'objectif de se débarrasser de couches temporaires, par exemple de dépendances, qui ne sont pas nécessaires à l'image finale. Typiquement, on distingue deux Dockerfiles; un pour une image en phase de développement contenant tous les outils nécessaires, un deuxième pour l'image de production livrée avec le strict minimum pour l'application de prod. + +Exemple: +``` +# first stage +FROM python:3.8 AS builder +COPY requirements.txt . + +# Install dependencies required to compile Python packages +RUN apk add --no-cache libffi-dev musl-dev gcc + +# install dependencies to the local user directory (eg. /root/.local) +RUN pip install --user -r requirements.txt + +# second unnamed stage +FROM python:3.8-slim + +# copy only the dependencies installation from the 1st stage image +COPY --from=builder /root/.local /root/.local +COPY ./src . + +CMD [ "python", "./server.py" ] +``` + +https://docs.docker.com/develop/develop-images/multistage-build/ + +## Docker registry + +Pour le moment, après avoir build nos images, nous avons simplement créé des conteneurs basés sur ces images. C'est tout à fait normal en phase de développement de build les images dans son environnement local afin de pouvoir ajuster le Dockerfile si besoin, ou encore build des images qui contiennent tous les outils de développement requis. + +En revanche, dans un contexte de production, une fois que l'image a été optimisée et que son fonctionnement a été validé grâce aux tests d'intégration, la pratique la plus courante est de push cette image dans un registre d'images, puis de lancer des conteneurs à partir de ces images depuis l'environnement de production. Cela permet d'économiser du temps, des ressources pour build les images, et des mauvaises surprises dus à des build ratés. + +Un des principaux registre d'images est [Dockerhub](https://hub.docker.com/), qui est pour la plus grande partie gratuit au "pull" et hôte la plupart des images les plus connues. Il existe des registres ciblant les professionnels tels que Artifactory, Nexus, AWS Elastic Container Registry, Google Container Registry ou il est encore possible de host son propre registre en utilisant Docker. + +## Développer depuis un conteneur + +Dans le but de développer les applications que l'on puisse faire tourner sur tous les environnements comme ceux de nos collègues ou ceux de production, il est possible, voire même recommandé, de développer directement depuis les conteneurs. + +Cela est possible grâce principalement au partage de volume, qui permet de travailler sur des fichiers locaux rendus directement accessibles au conteneur dans le répertoire spécifié. +``` +docker run -it --name python_dev -v $PWD:/app python:3.8-alpine /bin/sh +``` + +Développer directement depuis un conteneur est avantageux, car on ne va pas polluer son ordinateur avec des dépendances. Si l'on rate la configuration de son conteneur, on peut simplement le supprimer et recommencer. + +Un tip supplémentaire est d'utiliser l'extension de Visual Studio Code qui s'appelle Remote - Containers. Elle permet d'ouvrir une fenêtre de l'IDE avec les fichiers du conteneur et des terminaux intégrés directement depuis son intérieur. + +## Kubernetes + +Kubernetes est une technologie open-source de la CNCF - Cloud Native Computing Foundation - originellement créée par Google et dont la première release a été sortie en Juin 2014. C'est une technologie phare du cloud grâce à ces caractéristiques suivantes: + +- Resource pooling: la mise en commun des ressources et leur management à partir d'un point central permet de mettre à disposition sa flotte de serveurs pour son grand nombre de conteneurs. +- Resource packing: la capacité d'attribuer les ressources nécessaires aux conteneurs selon leurs besoins +- Elasticité et ténacité (self-healing): la capacité de mettre en échelle, scaler le nombre de conteneurs, détecter lesquels sont unhealthy et défaillants et les remplacer +- Rollout et rollbacks et automatiques: de manière progressive et contrôlée, les nouveaux conteneurs avec une plus récente version du code peuvent être deployés tandis que les existants sont mis hors service puis supprimés. S'il s'avère que les nouveaux conteneurs ne fonctionnent pas, les anciens sont remis en service. + +C'est une technologie extrêmement puissante et complexe à implémenter. Il est primordial d'en évaluer les avantages et désavantages en raison des barrières à l'entrée et au maintien. + +https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/ \ No newline at end of file diff --git a/docker/OPS.md b/docker/OPS.md index fc6449b5..1359648d 100644 --- a/docker/OPS.md +++ b/docker/OPS.md @@ -65,7 +65,9 @@ Les conteneurs permettent de packager les applications dans des environnements i ## Mutable and immutable infrastructures -Les infrastructures mutable et immuable sont aussi connues sous l'expression 'pets vs cattle' - animaux vs troupeau. +Les infrastructures mutable et immuable sont aussi connues sous l'expression 'pets vs cattle' - animaux vs troupeau. + + ### Infrastructure mutable @@ -85,6 +87,8 @@ Les conteneurs sont simples et rapides à livrer, lancer et disposer. Combinés ## Horizontal and vertical scaling + + ### Scaling vertical Cela signifie que pour répondre à une augmentation croissante du trafic d'une application, en terme de nombre d'utilisateurs, la réponse est d'augmenter les ressources de la machine qui héberge l'application. Par exemple, en augmentant le nombre de CPUs, en ajoutant de la RAM et du stockage. C'est une solution simple, en particulier avec une architecture muable. Un défaut majeur est que les ressources nouvellement attribuées ne sont pas simples à récupérer tant que la machine est en marche, et selon l'application, il n'est pas garanti qu'ajouter des ressources aide. diff --git a/docker/Ops.pdf b/docker/Ops.pdf new file mode 100644 index 00000000..b1b844f2 Binary files /dev/null and b/docker/Ops.pdf differ diff --git a/docker/README.md b/docker/README.md index 1d5e16bf..47f86c38 100644 --- a/docker/README.md +++ b/docker/README.md @@ -7,12 +7,6 @@ - [Exec](#exec) - [Docker compose](#docker-compose) - [Exercices](#exercices) -- [Aller plus loin](#aller-plus-loin) - - [Images de base](#images-de-base) - - [Multi-stage builds](#multi-stage-builds) - - [Docker registry](#docker-registry) - - [Développer depuis un conteneur](#développer-depuis-un-conteneur) - - [Kubernetes](#kubernetes) Afin de pouvoir travailler dans les meilleurs conditions, nous allons travailler à partir de la technologie Docker. Docker est une technologie de conteneurs utilisés par les DevOps pour permettre un déploiement plus simple et plus rapide. Par rapport à des machines virtuelles, Docker est plus léger. @@ -83,74 +77,4 @@ Le fichier `docker-compose.yml` permet de définir, l'ensemble des services et l ## Exercices -Réaliser les commandes vu précédemment pour lancer flask directement dans Docker. - -# Aller plus loin - -## Images de base - -La première ligne du Dockerfile est l'image de base. Elle peut indiquer le langage de programmation utilisé: Python, Golang, Java, Ruby. Elle peut spécifier la version de ce langage: python:3.8, python:3.7, python:3. Elle peut spécifier le système d'exploitation: buster, bullseye (deux versions de Debian), windowsservercore, alpine. - -En particulier, [Alpine Linux](https://alpinelinux.org/about/) tourne exclusivement sur conteneur et est très populaire pour son poids léger (moins de 6 MB), sa simplicité et sa sécurité sans sacrifier sa capacité à être la base de la majorité des conteneurs livrés en production. - -## Multi-stage builds - -Chaque ligne d'un Dockerfile ajoute une couche à l'image. Il est possible de composer un Dockerfile avec plusieurs stages ou couches avec l'objectif de se débarrasser de couches temporaires, par exemple de dépendances, qui ne sont pas nécessaires à l'image finale. Typiquement, on distingue deux Dockerfiles; un pour une image en phase de développement contenant tous les outils nécessaires, un deuxième pour l'image de production livrée avec le strict minimum pour l'application de prod. - -Exemple: -``` -# first stage -FROM python:3.8 AS builder -COPY requirements.txt . - -# Install dependencies required to compile Python packages -RUN apk add --no-cache libffi-dev musl-dev gcc - -# install dependencies to the local user directory (eg. /root/.local) -RUN pip install --user -r requirements.txt - -# second unnamed stage -FROM python:3.8-slim - -# copy only the dependencies installation from the 1st stage image -COPY --from=builder /root/.local /root/.local -COPY ./src . - -CMD [ "python", "./server.py" ] -``` - -https://docs.docker.com/develop/develop-images/multistage-build/ - -## Docker registry - -Pour le moment, après avoir build nos images, nous avons simplement créé des conteneurs basés sur ces images. C'est tout à fait normal en phase de développement de build les images dans son environnement local afin de pouvoir ajuster le Dockerfile si besoin, ou encore build des images qui contiennent tous les outils de développement requis. - -En revanche, dans un contexte de production, une fois que l'image a été optimisée et que son fonctionnement a été validé grâce aux tests d'intégration, la pratique la plus courante est de push cette image dans un registre d'images, puis de lancer des conteneurs à partir de ces images depuis l'environnement de production. Cela permet d'économiser du temps, des ressources pour build les images, et des mauvaises surprises dus à des build ratés. - -Un des principaux registre d'images est [Dockerhub](https://hub.docker.com/), qui est pour la plus grande partie gratuit au "pull" et hôte la plupart des images les plus connues. Il existe des registres ciblant les professionnels tels que Artifactory, Nexus, AWS Elastic Container Registry, Google Container Registry ou il est encore possible de host son propre registre en utilisant Docker. - -## Développer depuis un conteneur - -Dans le but de développer les applications que l'on puisse faire tourner sur tous les environnements comme ceux de nos collègues ou ceux de production, il est possible, voire même recommandé, de développer directement depuis les conteneurs. - -Cela est possible grâce principalement au partage de volume, qui permet de travailler sur des fichiers locaux rendus directement accessibles au conteneur dans le répertoire spécifié. -``` -docker run -it --name python_dev -v $PWD:/app python:3.8-alpine /bin/sh -``` - -Développer directement depuis un conteneur est avantageux, car on ne va pas polluer son ordinateur avec des dépendances. Si l'on rate la configuration de son conteneur, on peut simplement le supprimer et recommencer. - -Un tip supplémentaire est d'utiliser l'extension de Visual Studio Code qui s'appelle Remote - Containers. Elle permet d'ouvrir une fenêtre de l'IDE avec les fichiers du conteneur et des terminaux intégrés directement depuis son intérieur. - -## Kubernetes - -Kubernetes est une technologie open-source de la CNCF - Cloud Native Computing Foundation - originellement créée par Google et dont la première release a été sortie en Juin 2014. C'est une technologie phare du cloud grâce à ces caractéristiques suivantes: - -- Resource pooling: la mise en commun des ressources et leur management à partir d'un point central permet de mettre à disposition sa flotte de serveurs pour son grand nombre de conteneurs. -- Resource packing: la capacité d'attribuer les ressources nécessaires aux conteneurs selon leurs besoins -- Elasticité et ténacité (self-healing): la capacité de mettre en échelle, scaler le nombre de conteneurs, détecter lesquels sont unhealthy et défaillants et les remplacer -- Rollout et rollbacks et automatiques: de manière progressive et contrôlée, les nouveaux conteneurs avec une plus récente version du code peuvent être deployés tandis que les existants sont mis hors service puis supprimés. S'il s'avère que les nouveaux conteneurs ne fonctionnent pas, les anciens sont remis en service. - -C'est une technologie extrêmement puissante et complexe à implémenter. Il est primordial d'en évaluer les avantages et désavantages en raison des barrières à l'entrée et au maintien. - -https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/ \ No newline at end of file +Réaliser les commandes vu précédemment pour lancer flask directement dans Docker. \ No newline at end of file diff --git a/docker/docker-compose-example/.env b/docker/docker-compose-example/.env new file mode 100644 index 00000000..220539aa --- /dev/null +++ b/docker/docker-compose-example/.env @@ -0,0 +1,3 @@ +POSTGRES_USER=userpd +POSTGRES_PASSWORD=postgrespassword +POSTGRES_DB=dbesiee diff --git a/docker/docker-compose-example/README.md b/docker/docker-compose-example/README.md new file mode 100644 index 00000000..508c8119 --- /dev/null +++ b/docker/docker-compose-example/README.md @@ -0,0 +1,11 @@ +# Exemple de Docker Compose + +- Se placer dans ce répertoire `fullstack-data-application/docker/docker-compose-example` contenant le `docker-compose.yml` +- Lancer les instances: `docker-compose up -d` +- Checker le status des conteneurs: `docker-compose ps -a` +- Checker les logs des conteneurs: `docker-compose logs -f` +- Checker les logs du conteneur API: `docker-compose logs -f api` +- Aller sur `localhost:8080` et cliquer sur le bouton +- Aller sur `localhost:5000` +- Aller sur `localhost:5000/db` +- Stopper le Docker Compose: `docker-compose down` \ No newline at end of file diff --git a/docker/docker-compose-example/api-example/Dockerfile b/docker/docker-compose-example/api-example/Dockerfile new file mode 100644 index 00000000..0520ec98 --- /dev/null +++ b/docker/docker-compose-example/api-example/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.8 + +WORKDIR /app + +COPY requirements.txt requirements.txt +RUN pip3 install -r requirements.txt + +COPY . . + +ENV FLASK_ENV=development + +CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"] diff --git a/docker/docker-compose-example/api-example/app.py b/docker/docker-compose-example/api-example/app.py new file mode 100644 index 00000000..a587351a --- /dev/null +++ b/docker/docker-compose-example/api-example/app.py @@ -0,0 +1,34 @@ +from flask import Flask, jsonify +from flask_cors import CORS +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +import os + +app = Flask(__name__) +CORS(app) + +@app.route('/', methods=['GET']) +def hello_world(): + response = jsonify({'data': 'Hello, Docker!'}) + return response + +@app.route('/db', methods=['GET']) +def hello_db(): + POSTGRES_USER = os.environ.get("POSTGRES_USER") + POSTGRES_PASSWORD = os.environ.get("POSTGRES_PASSWORD") + POSTGRES_DB = os.environ.get("POSTGRES_DB") + + SQLALCHEMY_DATABASE_URL = f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@db/{POSTGRES_DB}" + + engine = create_engine( + SQLALCHEMY_DATABASE_URL + ) + SessionLocal = sessionmaker(autocommit=False, autoflush=True, bind=engine) + + BaseSQL = declarative_base() + query = engine.execute('SELECT datname FROM pg_database;') + available_tables = query.fetchall() + available_tables = [tup[0] for tup in available_tables] + response = jsonify({'data': available_tables}) + return response diff --git a/docker/docker-compose-example/api-example/requirements.txt b/docker/docker-compose-example/api-example/requirements.txt new file mode 100644 index 00000000..ab8f729b --- /dev/null +++ b/docker/docker-compose-example/api-example/requirements.txt @@ -0,0 +1,4 @@ +Flask +flask-cors +sqlalchemy +psycopg2 diff --git a/docker/docker-compose-example/docker-compose.yml b/docker/docker-compose-example/docker-compose.yml new file mode 100644 index 00000000..70f19d1d --- /dev/null +++ b/docker/docker-compose-example/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.8" +services: + api: + build: + context: ./api-example + volumes: + - ./api-example/:/app + ports: + - "5000:5000" + env_file: + - .env + frontend: + build: + context: ./frontend-example + volumes: + - ./frontend-example/:/app + - /app/node_modules + ports: + - "8080:8080" + db: + image: postgres + restart: always + env_file: + - .env + ports: + - "5432:5432" + diff --git a/docker/docker-compose-example/frontend-example/.gitignore b/docker/docker-compose-example/frontend-example/.gitignore new file mode 100644 index 00000000..ff62b675 --- /dev/null +++ b/docker/docker-compose-example/frontend-example/.gitignore @@ -0,0 +1,25 @@ +yarn.lock + +.DS_Store +node_modules +/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/docker/docker-compose-example/frontend-example/Dockerfile b/docker/docker-compose-example/frontend-example/Dockerfile new file mode 100644 index 00000000..88939c29 --- /dev/null +++ b/docker/docker-compose-example/frontend-example/Dockerfile @@ -0,0 +1,10 @@ +FROM node:alpine + +WORKDIR /app + +COPY . . + +RUN yarn install + +ENTRYPOINT ["yarn"] +CMD ["serve"] diff --git a/docker/docker-compose-example/frontend-example/README.md b/docker/docker-compose-example/frontend-example/README.md new file mode 100644 index 00000000..050175d5 --- /dev/null +++ b/docker/docker-compose-example/frontend-example/README.md @@ -0,0 +1,24 @@ +# frontend-example + +## Project setup +``` +yarn install +``` + +### Compiles and hot-reloads for development +``` +yarn serve +``` + +### Compiles and minifies for production +``` +yarn build +``` + +### Lints and fixes files +``` +yarn lint +``` + +### Customize configuration +See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/docker/docker-compose-example/frontend-example/babel.config.js b/docker/docker-compose-example/frontend-example/babel.config.js new file mode 100644 index 00000000..e9558405 --- /dev/null +++ b/docker/docker-compose-example/frontend-example/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset' + ] +} diff --git a/docker/docker-compose-example/frontend-example/package.json b/docker/docker-compose-example/frontend-example/package.json new file mode 100644 index 00000000..37e9da05 --- /dev/null +++ b/docker/docker-compose-example/frontend-example/package.json @@ -0,0 +1,43 @@ +{ + "name": "frontend-example", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint" + }, + "dependencies": { + "axios": "^0.21.4", + "core-js": "^3.6.5", + "vue": "^3.0.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "~4.5.0", + "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "@vue/compiler-sfc": "^3.0.0", + "babel-eslint": "^10.1.0", + "eslint": "^6.7.2", + "eslint-plugin-vue": "^7.0.0" + }, + "eslintConfig": { + "root": true, + "env": { + "node": true + }, + "extends": [ + "plugin:vue/vue3-essential", + "eslint:recommended" + ], + "parserOptions": { + "parser": "babel-eslint" + }, + "rules": {} + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/docker/docker-compose-example/frontend-example/public/favicon.ico b/docker/docker-compose-example/frontend-example/public/favicon.ico new file mode 100644 index 00000000..df36fcfb Binary files /dev/null and b/docker/docker-compose-example/frontend-example/public/favicon.ico differ diff --git a/docker/docker-compose-example/frontend-example/public/index.html b/docker/docker-compose-example/frontend-example/public/index.html new file mode 100644 index 00000000..3e5a1396 --- /dev/null +++ b/docker/docker-compose-example/frontend-example/public/index.html @@ -0,0 +1,17 @@ + + +
+ + + + +
+ {{ apiResponse }}
+