I'm new to traefik, and I can't figure why my configuration do not work as expected.
Here is the context :
2 front-end app, builded and copy/pasted into a nginx folder using Dockerfile
1 rest api, compiled and running with node using Dockerfile
1 postgres database and pgadmin
1 mongo database and mongo-express.
All of this is setup in a docker-compose.
Frontend Dockerfile:
FROM node:lts-alpine as build
WORKDIR /app/frontend-app1 -- frontend-app2 for the other
COPY package*.json ./
RUN npm install
COPY . ./
RUN npm run build
FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/frontend-app1/build /usr/share/nginx/html/frontend-app1
EXPOSE 3001 -- 3002 from frontend-app2
CMD ["nginx", "-g", "daemon off;"]
API Dockerfile:
FROM node:14-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
ARG NODE_ENV=qual
ENV NODE_ENV=${NODE_ENV}
EXPOSE 3000
CMD ["node", "dist/main"]
Docker-compose:
version: "3.8"
networks:
backend-network:
traefik-network:
name: traefik-network
external: true
services:
mongo:
container_name: wow_mongo
image: mongo
restart: always
ports:
- 27017:27017
networks:
- backend-network
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: xxx
MONGO_INITDB_DATABASE: xxx
MONGO_INITDB_USERNAME: xxx
MONGO_INITDB_PASSWORD: xxx
volumes:
- ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh
mongo-express:
container_name: wow_mongo_express
image: mongo-express
depends_on:
- mongo
restart: always
ports:
- 8081:8081
networks:
- traefik-network
- backend-network
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: xxx
ME_CONFIG_MONGODB_ADMINPASSWORD: xxx
ME_CONFIG_MONGODB_URL: mongodb://xxx:xxx#mongo:27017/
labels:
- "traefik.enable=true"
- "traefik.http.routers.mongo-express.rule=Host(`me-qual.xxx.com`)"
- "traefik.http.routers.mongo-express.entrypoints=web"
postgres:
container_name: wow_postgres
image: postgres
restart: always
ports:
- 5432:5432
networks:
- backend-network
environment:
POSTGRES_PASSWORD: xxx
POSTGRES_USER: xxx
POSTGRES_DB: xxx
pgadmin:
container_name: wow_pgadmin
image: dpage/pgadmin4
depends_on:
- postgres
restart: always
networks:
- traefik-network
- backend-network
ports:
- 5050:80
environment:
PGADMIN_DEFAULT_EMAIL: xxx
PGADMIN_DEFAULT_PASSWORD: xxx
labels:
- "traefik.enable=true"
- "traefik.http.routers.pgadmin.rule=Host(`pgadmin-qual.xxx.com`)"
- "traefik.http.routers.pgadmin.entrypoints=web"
- "traefik.docker.network=traefik-network"
traefik:
container_name: wow_traefik
image: traefik:v2.6
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/traefik-conf/traefik.yml:/etc/traefik/traefik.yml
- $PWD/traefik-conf/acme.json:/letsencrypt/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`traefik.xxx.com`)"
- "traefik.http.routers.api.service=api#internal"
- "traefik.http.routers.api.entrypoints=web"
- "traefik.http.routers.api.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=xxx:xxx"
# - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
# - "traefik.http.middlewares.strip-www.redirectregex.regex=^https?://(www\\.)(.+)"
# - "traefik.http.middlewares.strip-www.redirectregex.replacement=https://$${2}"
# - "traefik.http.middlewares.strip-www.redirectregex.permanent=true"
api:
container_name: wow_api
depends_on:
- postgres
- mongo
restart: unless-stopped
image: wow_api:1.0.0
build:
context: ../wow-api
dockerfile: Dockerfile
ports:
- 3000:3000
networks:
- traefik-network
- backend-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wow-api.rule=Host(`api-qual.xxx.com`)"
- "traefik.http.routers.wow-api.entryPoints=web"
admin:
container_name: wow_admin
# depends_on:
# - api
restart: always
image: wow_admin:1.0.0
build:
context: ../wow-admin
dockerfile: Dockerfile
ports:
- 3002:80
networks:
- traefik-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wow-admin.rule=Host(`admin-qual.xxx.com`, `www.admin-qual.xxx.com`)"
- "traefik.http.routers.wow-admin.entrypoints=web"
# - "traefik.http.routers.blog.middlewares=strip-www"
# - "traefik.http.routers.blog.tls=true"
# - "traefik.http.routers.blog.tls.certresolver=letsencrypt"
consultant:
container_name: wow_consultant
# depends_on:
# - api
restart: always
image: wow_consultant:1.0.0
build:
context: ../wow-consultant
dockerfile: Dockerfile
ports:
- 3001:80
networks:
- traefik-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wow-consultant.rule=Host(`consultant-qual.xxx.com`, `www.admin-qual.xxx.com`)"
- "traefik.http.routers.wow-consultant.entrypoints=web"
And my traefik config is simple since I can't manage to make it work without tls.
global:
sendAnonymousUsage: false
log:
level: "INFO"
format: "common"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: true
swarmMode: false
watch: true
network: traefik-network
api:
dashboard: true
entryPoints:
web:
address: ":80"
# http:
# redirections:
# entryPoint:
# to: "websecure"
# scheme: "https"
# permanent: true
websecure:
address: ":443"
# http:
# tls:
# certResolver: "letsencrypt"
# certificatesResolvers:
# letsencrypt:
# acme:
# email: "xxx"
# storage: "/letsencrypt/acme.json"
# tlsChallenge: {}
I figure out to make traefik.my_domain.com to work and to log using basic auth.
I can also navigate throught my differents services using localhost:<PORT_BINDED>
But as soon as I want to reach, for example, a front end app, I get a Gateway timeout and can't manage to make it work if I don't specify the port.
For example, accessing to the frontend app which is related to the consultant service:
consulltant-qual.xxx.com result in a gateway timeout, but if I ask consulltant-qual.xxx.com:3001, I can access to my app.
Any help would be grateful,
Thanks
Related
Here is my docker-compose.yml, when I comment the volumes code of "khaothi-manager" my services work correctly. But when uncomment it, my Node service throw an error that it can not connect to Mongo
version: "3.8"
services:
mongo:
image: mongo
restart: always
env_file: ./.env
ports:
- $MONGO_LOCAL_PORT:$DB_PORT
volumes:
- ./data:/data/db
networks:
- hm_khaothi
khaothi-manager:
container_name: khaothi-manager
image: khaothi-manager
restart: always
volumes:
- ./admin:/app
build: ./admin
env_file: ./.env
links:
- mongo
- khaothi-resource
ports:
- $MANAGER_PORT:$MANAGER_PORT
environment:
- MANAGER_HOST=$MANAGER_HOST
- MANAGER_PORT=$MANAGER_PORT
- RESOURCE_HOST=khaothi-resource
- RESOURCE_PORT:$RESOURCE_PORT
- DB_HOST=mongo
- DB_NAME=$DB_NAME
- DB_PORT=$DB_PORT
networks:
- hm_khaothi
My Dockerfile
# syntax=docker/dockerfile:1
FROM node:14-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]
This is the error
(node:37) UnhandledPromiseRejectionWarning: MongooseServerSelectionError: connection timed out
at NativeConnection.Connection.openUri (/app/node_modules/mongoose/lib/connection.js:807:32)
at /app/node_modules/mongoose/lib/index.js:342:10
...
It worked correctly when I add another volume /app/node_modules
khaothi-manager:
container_name: khaothi-manager
image: khaothi-manager
restart: always
volumes:
- ./admin:/app
- /app/node_modules
I would like to implement a hot reloading functionality from development evinronement such that when i change anything in the source code it will reflect the changes up to the docker container by mounting the volume and hence see the changes live in my localhost.
Below is my docker-compose file
version: '3.9'
services:
server:
restart: always
build:
context: ./server
dockerfile: Dockerfile
volumes:
# don't overwrite this folder in container with the local one
- ./app/node_modules
# map current local directory to the /app inside the container
#This is a must for development in order to update our container whenever a change to the source code is made. Without this, you would have to rebuild the image each time you make a change to source code.
- ./server:/app
# ports:
# - 3001:3001
depends_on:
- mongodb
environment:
NODE_ENV: ${NODE_ENV}
MONGO_URI: mongodb://${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD}#mongodb
networks:
- anfel-network
client:
stdin_open: true
build:
context: ./client
dockerfile: Dockerfile
volumes:
- ./app/node_modules
- ./client:/app
# ports:
# - 3000:3000
depends_on:
- server
networks:
- anfel-network
mongodb:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
volumes:
# for persistence storage
- mongodb-data:/data/db
networks:
- anfel-network
# mongo express used during development
mongo-express:
image: mongo-express
depends_on:
- mongodb
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_ROOT_USERNAME}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_ROOT_PASSWORD}
ME_CONFIG_MONGODB_PORT: 27017
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_BASICAUTH_USERNAME: root
ME_CONFIG_BASICAUTH_PASSWORD: root
volumes:
- mongodb-data
networks:
- anfel-network
nginx:
restart: always
depends_on:
- server
- client
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- '8080:80'
networks:
- anfel-network
# volumes:
# - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
anfel-network:
driver: bridge
volumes:
mongodb-data:
driver: local
Any suggestions would be appreciated.
You have to create a bind mount, this can help you
I'm trying to make requests to my server container from my client app in another container. The Docker Compose docs state that the network is setup automatically, so shouldn't all ports be accessible from all containers? When I make a curl request to port 4000 from outside of the container (in a fresh terminal), it works. However when I enter the client container (selektor-client) and try the same request, it fails.
curl --request POST http://localhost:4000/api/music
What am I doing wrong?
docker-compose.yaml:
version: "3"
services:
client:
container_name: selektor-client
restart: always
build: ./client
ports:
- "3000:3000"
volumes:
- ./client/:/client/
- /client/node_modules/
command: ["yarn", "start"]
server:
container_name: selektor-server
restart: always
build: ./server
ports:
- "4000:4000"
volumes:
- ./server/:/server/
depends_on:
- mongo
command: ["yarn", "start"]
mongo:
container_name: selektor-mongo
command: mongod --noauth
build: .
restart: always
volumes:
# - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- data-volume:/data/db
ports:
- "27017:27017"
volumes:
data-volume:
When you call containers of the same stack each other, the host name is, by default, the service name, and the port is the internal port: <servicename>:<internal_port>. So, based on this part of your example:
version: "3"
server:
container_name: selektor-server
restart: always
build: ./server
ports:
- "4000:4000"
volumes:
- ./server/:/server/
depends_on:
- mongo
command: ["yarn", "start"]
The url you client have to use to reach the server is http://server:4000
I had the same problem . my solution was registering network and giving subnet mast to the network and register the static ip to each container :
version: "3"
networks:
my_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
services:
mongodb:
image: mongo:4.2.1
container_name: mongo
command: mongod --auth
hostname: mongo
networks:
my_network:
ipv4_address: 172.20.0.5
volumes:
- /data/db/mongo:/data/db
ports:
- "27017:27017"
rabitmq:
hostname: rabbitmq
container_name: rabbitmq
image: rabbitmq:latest
networks:
my_network:
ipv4_address: 172.20.0.3
volumes:
- /var/lib/rabbitmq:/data/db
ports:
- "5672:5672"
- "15672:15672"
restart: always
you can access through IP addresses
I am having the connection error with the docker-composer when I try to access a postgres database through an API in Node.
I'm using Sequelize as ORM to acess the database. But I'dont know what happened.
docker-compose.yml:
version: '3.5'
services:
api-service:
build:
context: .
dockerfile: ./api-docker.dockerfile
image: api-service
container_name: api-service
restart: always
env_file: .env
environment:
- NODE_ENV=$NODE_ENV
ports:
- ${PORT}:3000
volumes:
- .:/home/node/api
- node_modules:/home/node/api/node_modules
depends_on:
- postgres-db
networks:
- api-network
command: npm run start:dev
postgres-db:
expose:
- ${PORT_SERVICE}
ports:
- ${PORT_SERVICE}:5432
restart: always
env_file: .env
volumes:
- pgReportData:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${USER_SERVICE}
POSTGRES_PASSWORD: ${PASSWORD_SERVICE}
POSTGRES_DB: ${DATABASE_SERVICE}
networks:
- api-network
container_name: postgres-db
image: postgres:10
networks:
api-network:
driver: bridge
volumes:
pgReportData:
driver: local
node_modules:
.env:
NODE_ENV=development
PORT=30780
HOST_SERVICE=postgres-db
DATABASE_SERVICE=base
USER_SERVICE=user
PASSWORD_SERVICE=password
DIALECT=postgres
PORT_SERVICE=5444
api-docker.dockerfile:
FROM node:12
WORKDIR /src
COPY . .
COPY --chown=node:node . .
USER node
RUN npm install
EXPOSE $PORT
ENTRYPOINT ["npm", "run", "start:dev"]
And when I run:
docker-compose up
I'm getting this error:
Any ideia?
Can someone help me ??
If node is the only app that connects to postgre-db you can remove the networks, and expose the postgredb running port (5432). To connect to the db you can simply use the container name as host.
Connection String: "postgres://YourUserName:YourPassword#postgres-db:5432/YourDatabase";
version: '3.5'
services:
api-service:
build:
context: .
dockerfile: ./api-docker.dockerfile
image: api-service
container_name: api-service
restart: always
env_file: .env
environment:
- NODE_ENV=$NODE_ENV
ports:
- ${PORT}:3000
volumes:
- .:/home/node/api
- node_modules:/home/node/api/node_modules
depends_on:
- postgres-db
command: npm run start:dev
postgres-db:
expose:
- 5432
restart: always
env_file: .env
volumes:
- pgReportData:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${USER_SERVICE}
POSTGRES_PASSWORD: ${PASSWORD_SERVICE}
POSTGRES_DB: ${DATABASE_SERVICE}
container_name: postgres-db
image: postgres:10
volumes:
pgReportData:
driver: local
node_modules:
I would like to know if it's possible to use my docker container name as host instead of the IP.
Let me explain, here's my docker-compose file :
version : "3"
services:
pandacola-logger:
build: ./
networks:
- logger_db
volumes:
- "./:/app"
ports:
- 8060:8060
- 10060:10060
command: npm run dev
logger-mysql:
image: mysql
networks:
- logger_db
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: Carotte1988-
MYSQL_DATABASE: logger
MYSQL_USER: logger-user
MYSQL_PASSWORD: PandaCola-
ports:
- 3306:3306
adminer:
networks:
- logger_db
image: adminer
restart: always
ports:
- 8090:8090
networks:
logger_db: {}
Sorry the intentation is a bit messy
I would like to set the name of my logger-mysql in a the .env file of my webservice (the pandacola-logger) instead of his IP adress
here's the .env file
HOST=0.0.0.0
PORT=8060
NODE_ENV=development
APP_NAME=AdonisJs
APP_URL=http://${HOST}:${PORT}
CACHE_VIEWS=false
APP_KEY=Qs1GxZrmQf18YZ9V42FWUUnnxLfPetca
DB_CONNECTION=mysql
DB_HOST=0.0.0.0 <---- here's where I want to use my container's name
DB_PORT=3306
DB_USER=logger-user
DB_PASSWORD=PandaCola-
DB_DATABASE=logger
HASH_DRIVER=bcrypt
If you can tell me first, if it's possible, and then, how to do it, it would be lovely.
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
Reference
For Example:
version: '2.2'
services:
redis:
image: redis
container_name: cache
expose:
- 6379
app:
build: ./
volumes:
- ./:/var/www/app
ports:
- 7731:80
environment:
- REDIS_URL=redis://cache
- NODE_ENV=development
- PORT=80
command:
sh -c 'npm i && node server.js'
networks:
default:
external:
name: "tools"