Is it possible to share ports between NGINX and Docker Container? - docker

I have Ubuntu 18:04/NGINX VPS where I have a bunch of Laravel project blocks, all use ssl (certbot).
I wanted to deploy Nextcloud via Docker Compose on the same VPS:
version: "3"
services:
proxy:
image: jwilder/nginx-proxy:alpine
labels:
# labels needed by lets encrypt to identify container to generate certs in
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
container_name: nextcloud-proxy
networks:
- nextcloud_network
ports:
- 80:80
- 443:443
volumes:
- ./proxy/conf.d:/etc/nginx/conf.d:rw
- ./proxy/vhost.d:/etc/nginx/vhost.d:rw
- ./proxy/html:/usr/share/nginx/html:rw
- ./proxy/certs:/etc/nginx/certs:ro
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/tmp/docker.sock:ro
restart: unless-stopped
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion:v1.12.1
container_name: nextcloud-letsencrypt
depends_on:
- proxy
networks:
- nextcloud_network
volumes:
- ./proxy/certs:/etc/nginx/certs:rw
- ./proxy/vhost.d:/etc/nginx/vhost.d:rw
- ./proxy/html:/usr/share/nginx/html:rw
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
db:
image: mariadb:10.5.1
container_name: nextcloud-mariadb
networks:
- nextcloud_network
volumes:
- ./db:/var/lib/mysql
- ./dbdumps:/var/dbdumps
- /etc/localtime:/etc/localtime:ro
environment:
- MYSQL_ROOT_PASSWORD=... # set me
- MYSQL_PASSWORD=... # set me
- MYSQL_DATABASE=... # set me
- MYSQL_USER=... # set me
restart: unless-stopped
redis:
container_name: nextcloud-redis
image: redis:5.0.8
restart: unless-stopped
networks:
- nextcloud_network
volumes:
- ./redis/data:/data
command: ["redis-server", "--appendonly yes"]
app:
image: nextcloud:18.0.2
container_name: nextcloud-app
networks:
- nextcloud_network
depends_on:
- letsencrypt
- proxy
- redis
- db
volumes:
- ./nextcloud:/var/www/html
- ./app/config:/var/www/html/config
- ./app/custom_apps:/var/www/html/custom_apps
- ./app/data:/var/www/html/data
- ./app/themes:/var/www/html/themes
- /etc/localtime:/etc/localtime:ro
environment:
- VIRTUAL_HOST=YOURDOMAINHERE # set me
- LETSENCRYPT_HOST=YOURDOMAINHERE # set me
- LETSENCRYPT_EMAIL=you#example.com # set me
restart: unless-stopped
networks:
nextcloud_network:
driver: bridge
When I run this I get:
ERROR: for 3f210d699b80_nextcloud-proxy Cannot start service proxy: driver failed programming
external connectivity on endpoint nextcloud-proxy
(2d76e425c94abb95da70a7d903bf8830d4e9192a512e17db1b39f76da85c7b97): Error starting userland proxy:
listen tcp 0.0.0.0:443: bind: address already in use
ERROR: for proxy Cannot start service proxy: driver failed programming external connectivity on
endpoint nextcloud-proxy (2d76e425c94abb95da70a7d903bf8830d4e9192a512e17db1b39f76da85c7b97): Error
starting userland proxy: listen tcp 0.0.0.0:443: bind: address already in use
ERROR: Encountered errors while bringing up the project.
Because this port is already in use.
If I stop NGINX on VPS and run docker-compose up -d again, everything is ok and Nextcloud service is accessible via URL.
I tried to change outside ports to
- 8080:80
- 4444:443
And rebuild it. Then I don't see the above error but everything is messed up - the url point to wrong domain...
Is it possible to tweak the proxy container settings somehow to resolve this?

2 services are unable to listen to the same port as you have found. Your laravel applications are already listening on ports 80/443, so when start your nextcloud containers, it won't be able to bind to those ports.
You'll have to have your jwilder/nginx-proxy:alpine act as a proxy to both the nextcloud container and the laravel servers. This can be done via your nginx configurations and mount it to your container (which you seem to be using the ./proxy/ directory):
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
Although, if your VPS is able to have 2 IP addresses, then you are able to bind the laravel applications to one interface and your nextcloud proxy to the other which will also solve your problem. The first method is better practice as would allow you to scale your server better without having to add another IP address per-application.
https://docs.docker.com/config/containers/container-networking/

Related

ioBroker with Node-RED behind traefik on Synlogy NAS with Docker

To control some Tasmota driven WiFi Sockets and some other stuff I want to install a Docker based SmartHome central on my Synology DS218+.
This installation is to be reachable only from inside my LAN while some other Docker containers on my NAS are accessible from the Internet.
So I decided to use a docker-compose Setup based on a Traefik-script with one single Traefik-container and a SmartHome-script with some SmartHome related containers (both scripts see below).
During a step-wise installation I first implemented the ioBroker container, finished the initial Setup and installed the Node-RED adapter.
After that I added a Mosquitto container to my SmartHome-script and a dependency to let the ioBroker container start after Mosquitto.
All containers of the above setup come up without any problems but ioBroker is the only Service that's accessible.
Whether my Tasmota-deices nor ioBroker seem to have access to Mosquitto and when I try to start the Node-RED-instance, I get an Error "404 page not found"
Traefik-script:
version: "3.9"
services:
traefik:
image: traefik:v2.4
command:
- --log.level=ERROR
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=web-secure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web-secure.address=:443
- --entrypoints.web-secure.http.tls.certresolver=lets-encrypt
- --entrypoints.something.address=:1234
...
- --entrypoints.node-red.address=:1880
- --entrypoints.mosquitto.address=:1883
- --entrypoints.iobroker.address=:8081
...
- --entrypoints.something-different.address=:23456
- --entrypoints.something-different.http.redirections.entrypoint.to=something-different
- --entrypoints.something-different.http.redirections.entrypoint.scheme=https
- --providers.docker=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.file.directory=/etc/traefik/dynamic/
- --providers.file.watch=true
- --certificatesresolvers.lets-encrypt.acme.email=my.email#internet.com
- --certificatesresolvers.lets-encrypt.acme.storage=/etc/traefik/acme.json
- --certificatesresolvers.lets-encrypt.acme.tlschallenge=true
restart:
- unless-stopped
ports:
- 80:80
- 443:443
- 1234:1234
...
- 1880:1880
- 1883:1883
- 8081:8081
...
- 23456:23456
volumes:
- /etc/localtime:/etc/localtime:ro
- ${PWD}/traefik:/etc/traefik
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- traefik.enable=false
networks:
- traefik
networks:
traefik:
external: false
driver: bridge
name: traefik
SmartHome-script
version: "3.9"
services:
mosquitto:
image: eclipse-mosquitto:latest
restart:
- unless-stopped
volumes:
- ${PWD}/mosquitto-config:/mosquitto/config
- ${PWD}/mosquitto-data:/mosquitto/data
- ${PWD}/mosquitto-log:/mosquitto/log
labels:
- traefik.enable=true
- traefik.tcp.routers.mosquitto.entrypoints=mosquitto
- traefik.tcp.routers.mosquitto.rule=HostSNI(`my.synology.nas.local`)
- traefik.tcp.routers.mosquitto.service=svc-mosquitto
- traefik.tcp.services.svc-mosquitto.loadbalancer.server.port=1883
networks:
- traefik
iobroker:
image: iobroker/iobroker:latest
restart:
- unless-stopped
depends_on:
- mosquitto
environment:
- LANG=de_DE.UTF‑8
- LANGUAGE=de_DE:de
- LC_ALL=de_DE.UTF-8
- TZ=Europe/Berlin
volumes:
- ${PWD}/iobroker-data:/opt/iobroker
labels:
- traefik.enable=true
- traefik.http.routers.iobroker.entrypoints=iobroker
- traefik.http.routers.iobroker.rule=Host(`my.synology.nas.local`)
networks:
- traefik
networks:
traefik:
external: true
I suspect that the inaccessible Mosquitto-server is related to the "labels" section of the Mosquitto-container, because this is the first time I try to use TCP routing.
The inaccessible Node-RED instance within ioBroker might be related to using more than one HTTP-port with this container but I have no idea, where to begin troubleshooting.
What's the "correct way" to handle such use cases in docker-compose scripts respectively in Traefik?
Thanx in advance for your hints!
Lanzi

Traefik - 502 Bad Gateway

Hello,
I'm trying to connect a Docker container to Traefik. It doesn't work.
I can't access my container through the host.
I tried several things: check the ports, check if the containers are on the same network, stop and restart the networks, check if there is an error, etc. Impossible to see where it comes from. :(
I have an another two another containers that already work with Traefik. But this container doesn't want...
I've been banging my head on it for two days now that I have a bump on my forehead the size of a horn.
My traefik docker logs :
msg="'502 Bad Gateway' caused by: dial tcp 172.23.0.6:5345: connect: connection refused"
My Docker compose file :
services:
db:
image: mariadb:10.3
env_file:
- env/mysql.env
volumes:
- database_volume:/var/lib/mysql
#ports:
#- "127.0.0.1:3306:3306"
networks:
- traefik-public
passbolt:
image: passbolt/passbolt:latest-ce
#Alternatively you can use rootless:
#image: passbolt/passbolt:latest-ce-non-root
tty: true
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.constraint-label=traefik-public
- traefik.http.routers.vault-https.rule=Host(`vault.audiowizard.fr`)
- traefik.http.routers.vault-https.entrypoints=websecure
- traefik.http.routers.vault-https.tls=true
- traefik.http.routers.vault-https.tls.certresolver=lets-encrypt
- traefik.http.services.vault-https.loadbalancer.server.port=5345
depends_on:
- db
env_file:
- env/passbolt.env
volumes:
- gpg_volume:/etc/passbolt/gpg
- images_volume:/usr/share/php/passbolt/webroot/img/public
command: ["/usr/bin/wait-for.sh", "-t", "0", "db:3306", "--", "/docker-entrypoint.sh"]
networks:
- traefik-public
#ports:
#- 5080:80
#- 5443:443
#Alternatively for non-root images:
# - 80:8080
# - 443:4433
volumes:
database_volume:
gpg_volume:
images_volume:
networks:
traefik-public:
external: true
I noticed in the commented code you have used the following ports.
#ports:
#- 5080:80
#- 5443:443
#Alternatively for non-root images:
# - 80:8080
# - 443:4433
But the port you have used in the label is 5343,
- traefik.http.services.vault-https.loadbalancer.server.port=5345
Can you please double check if this is the right port?

How to access a Docker container without specifying its HTTP port?

I set up a Docker network with a db container, a nextcloud container, and a nginx container. I can access the nextcloud website with 'ip-adress':8080, but I want to access it without specifying port 8080. How can I do that?
This is my docker-compose.yml:
version: '2'
volumes:
nextcloud:
db:
services:
db:
image: mariadb
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=
- MYSQL_PASSWORD=
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
app:
image: nextcloud:fpm
restart: always
links:
- db
volumes:
- nextcloud:/var/www/html
environment:
- MYSQL_PASSWORD=
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_HOST=db
web:
image: nginx
restart: always
ports:
- 8080:80
links:
- app
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
volumes_from:
- app
What you want is to avoid having to specify the port when you request a URI. One way to do that is to use the default port for the protocol you are using (80 for HTTP, 443 for https, 21 for FTP, etc). Then rely on your client to automatically fallback to the default port.
In a Docker Compose configuration file, the syntax for exposing a port is defined as such: <host_port>:<container_port> (see the documentation). That means 8080:80 exposes port 80 from the container on your docker host on port 8080.
In your case, the service is exposing an HTTP server, which means you have to change it to the default port 80 in order to omit it. Update web.services.ports[0] from 8080:80 to 80:80, and you will be able to access nextcloud from 'ip-adress'.

Want to run elasticsearch with Laravel app in docker, but it doesn't work

I have laravel app that lives in docker, and I want to integrate elasticsearch to my app
That is how my docker-compose.yaml looks
version: '3'
services:
laravel:
build: ./docker/build
container_name: laravel
restart: unless-stopped
privileged: true
ports:
- 8084:80
- "22:22"
volumes:
- ./docker/settings:/settings
- ../2agsapp:/var/www/html
# - vendor:/var/www/html/vendor
- ./docker/temp:/backup
- composer_cache:/root/.composer/cache
environment:
- ENABLE_XDEBUG=true
links:
- mysql
mysql:
image: mariadb:10.2
container_name: mysql
volumes:
- ./docker/db_config:/etc/mysql/conf.d
- ./db:/var/lib/mysql
ports:
- "8989:3306"
environment:
- MYSQL_USER=dev
- MYSQL_PASSWORD=dev
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=laravel
command: --innodb_use_native_aio=0
phpmyadmin:
container_name: pma_laravel
image: phpmyadmin/phpmyadmin:latest
environment:
- MYSQL_USER=dev
- MYSQL_ROOT_PASSWORD=root
- MYSQL_PASSWORD=dev
- MYSQL_DATABASE=laravel
- PMA_HOST=mysql
ports:
- 8083:80
links:
- mysql
es:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1
ports:
- "9200:9200"
- "9300:9300"
environment:
- discovery.type=single-node
volumes:
storage:
composer_cache:
I run docker-compose up -d and then got really strange issue
If I execute curl localhost:9200 inside laravel container it returns this message Failed to connect to localhost port 9200: Connection refused
But if I wull run curl localhost:9200 out of the docker it returns expected response
Maybe I don't understand how it works, hope someone will help me
when you want to access another container within some container you should use the container name, not localhost.
If you are inside laravel and want to access Elasticsearch you should:
curl es:9200
Since you mapped the 9200 port to localhost (ports section in docker-compose) this port is available from your local machine as well, that's why curling from local machine to 9200 works.

multiple docker compose files with traefik (v2.1) and database networks

I would like to build a docker landscape. I use a container with a traefik (v2. 1) image and a mysql container for multiple databases.
traefik/docker-compose.yml
version: "3.3"
services:
traefik:
image: "traefik:v2.1"
container_name: "traefik"
restart: always
command:
- "--log.level=DEBUG"
- "--api=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik-dashboard.address=:8080"
- "--certificatesresolvers.devnik-resolver.acme.httpchallenge=true"
- "--certificatesresolvers.devnik-resolver.acme.httpchallenge.entrypoint=web"
#- "--certificatesresolvers.devnik-resolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.devnik-resolver.acme.email=####"
- "--certificatesresolvers.devnik-resolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "./data:/etc/traefik"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- "proxy"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`devnik.dev`)"
- "traefik.http.routers.traefik.entrypoints=traefik-dashboard"
- "traefik.http.routers.traefik.tls.certresolver=devnik-resolver"
#basic auth
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.usersfile=/etc/traefik/.htpasswd"
#Docker Networks
networks:
proxy:
database/docker-compose.yml
version: "3.3"
services:
#MySQL Service
mysql:
image: mysql:5.7
container_name: mysql
restart: always
ports:
- "3306:3306"
volumes:
#persist data
- ./mysqldata/:/var/lib/mysql/
- ./init:/docker-entrypoint-initdb.d
networks:
- "mysql"
environment:
MYSQL_ROOT_PASSWORD: ####
TZ: Europe/Berlin
#Docker Networks
networks:
mysql:
driver: bridge
For the structure I want to control all projects via multiple docker-compose files. These containers should run on the same network as the traefik container and some with the mysql container.
This also works for the following case (but only sometimes)
dev-releases/docker-compose.yml
version: "3.3"
services:
backend:
image: "registry.gitlab.com/devnik/dev-releases-backend/master:latest"
container_name: "dev-releases-backend"
restart: always
volumes:
#laravel logs
- "./logs/backend:/app/storage/logs"
#cron logs
- "./logs/backend/cron.log:/var/log/cron.log"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dev-releases-backend.rule=Host(`dev-releases.backend.devnik.dev`)"
- "traefik.http.routers.dev-releases-backend.entrypoints=websecure"
- "traefik.http.routers.dev-releases-backend.tls.certresolver=devnik-resolver"
networks:
- proxy
- mysql
environment:
TZ: Europe/Berlin
#Docker Networks
networks:
proxy:
external:
name: "traefik_proxy"
mysql:
external:
name: "database_mysql"
As soon as I restart the containers in dev-releases/ via docker-compose up -d I get the typical error "Gateway timeout" when calling them in the browser.
As soon as I comment the network networks: #- mysql and restart the docker-compose in dev-releases/ it works again.
My guess is that I have not configured the external networks correctly. Is it not possible to use 2 external networks?
I'd like some container have access to the 'mysql' network but it should not be accessible for the whole traefik network.
Let me know if you need more information
EDIT (26.03.2020)
I make it running.
I put all my containers into one network "proxy". It seems mysql also have to be in the proxy network.
So I add following to database/docker-compose.yml
networks:
proxy:
external:
name: "traefik_proxy"
And removed the database_mysql network out of dev-releases/docker-compose.yml
based on the names of the files, your mysql network should be mysql_mysql.
you can verify this by executing
$> docker network ls
You are also missing a couple of labels for your services such as
traefik command line
- '--providers.docker.watch=true'
- '--providers.docker.swarmMode=true'
labels
- traefik.docker.network=proxy
- traefik.http.services.dev-releases-backend.loadbalancer.server.port=yourport
- traefik.http.routers.dev-releases-backend.service=mailcatcher
You can check this for more info

Resources