Dockeritzant NGINX
A classe hem utilitzat docker-compose
per a desplegar 3 aplicacions web diferents: app1
, app2
i app3
en una instancia EC2 d'AWS.
Configurant de l'entorn multi-aplicació
En primer lloc, hem creat les aplicacions web amb Flask
. Aquí teniu un exemple del codi per a app1:
```python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Hello from App 1!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
```
A continuació, hem creat el fitxer Dockerfile
per cada aplicació:
FROM python:3.9
WORKDIR /app
COPY app.py .
RUN pip install flask
CMD ["python", "app.py"]
Per app2 i app3, hem fet el mateix, simplement modificant el missatge de retorn. L'estructura de les aplicacions és la següent:
app1/
├── app.py
└── Dockerfile
app2/
├── app.py
└── Dockerfile
app3/
├── app.py
└── Dockerfile
Un cop preparades les aplicacions, hem creat un fitxer docker-compose.yml
per orquestrar els nostres serveis:
version: '3.9'
services:
app1:
build: ./app1
container_name: app1
ports:
- "5001:5000"
app2:
build: ./app2
container_name: app2
ports:
- "5002:5000"
app3:
build: ./app3
container_name: app3
ports:
- "5003:5000"
Amb aquest fitxer, hem desplegat els serveis mitjançant docker-compose up -d
. Per accedir a les aplicacions, hem utilitzat la IP pública de la instància EC2 i el port corresponent de cada aplicació.
Nota 1: Recordeu d'obrir els ports corresponents a les aplicacions a la instància EC2 (5001, 5002 i 5003).
Nota 2: Recordeu que si feu modificacions als contenidors, heu de fer
docker-compose up --build -d
per aplicar els canvis.
Amb aquesta configuració, hem pogut accedir a les aplicacions a través de http://ip:5001
, http://ip:5002
i http://ip:5003
. Per aconseguir-ho, hem afegit nginx com a proxy invers al nostre docker-compose.yml
:
Configurant NGINX com a proxy invers
Per evitar accedir a diferents ports per a cada aplicació, l'Alberto ens va suggerir utilitzar un únic punt d'entrada. Així, podem accedir a les aplicacions a través de http://ip/app1
, http://ip/app2
i http://ip/app3
.
- Actualitzeu el vostre
docker-compose.yml
amb el següent contingut:
version: '3.9'
services:
app1:
build: ./app1
container_name: app1
ports:
- "5001:5000"
app2:
build: ./app2
container_name: app2
ports:
- "5002:5000"
app3:
build: ./app3
container_name: app3
ports:
- "5003:5000"
nginx:
image: nginx:latest
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
- Inicialment hem configurat
nginx
de la següent manera:
events {}
http {
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:5001;
}
location /app1/ {
proxy_pass http://127.0.0.1:5001;
}
location /app2/ {
proxy_pass http://127.0.0.1:5002;
}
location /app3/{
proxy_pass http://127.0.0.1:5003;
}
}
}
No obstant això, després de desplegar-ho, vam observar que les aplicacions no funcionaven i apareixien errors de connection refused. Consultant els logs a través de docker logs nginx
, vam veure que nginx
no podia connectar-se als contenidors de les aplicacions.
El problema rau en el fet que nginx, al ser un contenidor, no pot utilitzar 127.0.0.1 per connectar-se als altres serveis, ja que aquest localhost és específic del contenidor nginx i no de la instància EC2. Si el servidor nginx
fos a la instància EC2, aquesta configuració hauria estat correcta.
Per solucionar-ho, hem actualitzat la configuració de nginx per utilitzar els noms dels serveis definits a docker-compose.yml, que són accessibles dins de la xarxa de contenidors:
events {}
http {
server {
listen 80;
location / {
proxy_pass http://app1:5000/;
}
location /app1/ {
proxy_pass http://app1:5000/;
}
location /app2/ {
proxy_pass http://app2:5000/;
}
location /app3/{
proxy_pass http://app3:5000/;
}
}
}
Amb aquesta configuració, nginx utilitza la xarxa interna de Docker per comunicar-se amb els serveis. Un cop implementats els canvis, podem accedir a les aplicacions a través de:
http://ip/app1
http://ip/app2
http://ip/app3
Nota: Ara només cal obrir el port 80 a la instància EC2, ja que nginx redirigeix les peticions al port correcte dins de la xarxa de contenidors. Els ports 5001, 5002 i 5003 ja no són necessaris a AWS.
Amb aquesta configuració, hem aconseguit desplegar 3 aplicacions web diferents amb un únic punt d'entrada, gràcies a nginx com a proxy invers.