I have docker compose web app:
version: '3.3'
services:
app:
image: xxxxxxxxxxxxx
restart: always
network_mode: 'host'
image is hidden because of private code
After startup I can call wget http://localhost:4004 on server but once I call PUBLICIP:4004 it doesnt wor, looks like port is not accesable. Firawall is disabled. I am using ubuntu.
Is there any wrong with docker compose?
I tried to google and SO
If you want to publish only port add ports key:
version: '3.3'
services:
app:
image: xxxxxxxxxxxxx
ports:
- "4004:4004"
You can read more here:
https://docs.docker.com/compose/networking/
Probably you will be interested in connecting it to domain and securing by ssl. I recommend you check nginx-proxy-automation.
https://github.com/evertramos/nginx-proxy-automation
I appending below example from my production that works with this library
version: '3'
services:
gql:
image: registry.digitalocean.com/main/xue-gql
ports:
- ${DOCKER_PORT}:4000
env_file:
- .env
environment:
- VIRTUAL_HOST=${HOST}
- LETSENCRYPT_HOST=${HOST}
- VIRTUAL_PORT=${DOCKER_PORT}
command: node ./src/index.js
redis:
image: 'redis:alpine'
networks:
default:
external:
name: ${NETWORK:-proxy}
Related
Problem:
When having two docker-compose files / projects with the same services, under the same network, when you spin up t he second compose project, the DNS name for the service gets overwritten.
eg:
App 1
version: "3.1"
services:
db:
image: mysql:8.0
container_name: monolith-db
networks:
- my-network-name
webserver:
image: nginx:alpine
container_name: monolith-webserver
networks:
- my-network-name
phpfpm:
container_name: monolith-phpfpm
networks:
- my-network-name
networks:
my-network-name:
external: true
App 2
version: "3.1"
services:
db:
image: mysql:8.0
container_name: ms-auth-db
networks:
- my-network-name
webserver:
image: nginx:alpine
container_name: ms-auth-webserver
networks:
- my-network-name
phpfpm:
container_name: ms-auth-phpfpm
networks:
- my-network-name
networks:
my-network-name:
external: true
If you start App 1, the services inside can connect to their declared services by service name as hostname, for example, in my config I have database-host: db
However, when I do docker-compose -p ms-auth --env-file .env -f infra/local/docker-compose.yml up -d then db hostname now points to App 2's db service.
The solution is to use the container_name as hostname
e.g. instead of connecting to db, configure App 1' config files to use the hostname monolith-db, and for pointing from App 1 to App 2, also use container name as hostname, e.g. ms-auth-host: ms-auth-webserver
I have two containers defined in a docker-compose yaml file that need to talk to each other, but they can't.
version: "3.9"
networks:
localdev:
driver: 'bridge'
services:
master-db:
image: mysql:8.0
container_name: master-db
hostname: master-db
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- "4000:3306"
networks:
- localdev
page-store:
hostname: page-store
build:
context: .
dockerfile: Dockerfile.page_store
container_name: page-store
ports:
- "2020:2020"
networks:
- localdev
links:
- master-db
In the page-store Python Flask microservice, I try to access the MySQL database by using its hostname of master-db, but the name cannot resolve.
You should be able to connect each other using respective service names. master-db and page-store removing hostname
As per Official guide you may have to define master-db,page-store in container's /etc/hosts, if you want to use hostname: page-store etc.
Please refer this SO thread.
Also using --links may not be the best option.
This is necessary as Traefik doesn't support php-fpm.
This docker-compose.yml doesn't work:
version: '3'
services:
#php
...
#Nginx Service
webserver:
image: nginx:alpine
container_name: webserver
restart: unless-stopped
tty: true
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
- traefik
labels:
- traefik.http.routers.webserver.rule=Host(`nginx.your_domain`)
- traefik.http.routers.webserver.tls=true
- traefik.http.routers.webserver.tls.certresolver=lets-encrypt
- traefik.port=80
#Docker Networks
networks:
app-network:
driver: bridge
traefik:
external: true
However, if I make an innocuous edit like change the version number to 3.7 (or change back to 3, from 3.7) it suddenly works, but isn't consistent.
How do I successfully route Traefik to an Nginx container?
#1. Docker compose file version is related to the engine, so please make sure you match that:
https://docs.docker.com/compose/compose-file/
#2. You could try to run the basic example from Traefik:
https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/
I'm assuming this is traefik latest (2.4)
I have two docker containers running - one has a websocket and the other is an nginx container. Setup using docker-compose.yml as follows:
version: "3.5"
websocket:
build:
context: .
dockerfile: Dockerfile
ports:
- "6000:7000"
nginx:
image: nginx:alpine
restart: always
ports:
- "120:80"
In my index.html in the nginx container, I currently have to set socketUrl: "http://192.168.X.X:6000",i.e. the local IP address for the websocket container.
Is there a way of setting up nginx so that socketUrl: "http://websocket:7000"? Either using nginx or traefik?
If I run on different machines I have to manually edit the socketUrl for the new machine. I'd like the setup to be standard across machines so that I can access the websocket via html at http://192.168.X.X:120
Use links to access the other container via hostname:
version: "3.5"
services:
websocket:
build:
context: .
dockerfile: Dockerfile
container_name: websocket
ports:
- "6000:7000"
nginx:
image: dperson/nginx
container_name: nginx
ports:
- "120:80"
environment:
- STREAM=0.0.0.0:80;websocket:7000
links:
- websocket
if this doesn't work, force them to be on the same network:
version: "3.5"
services:
websocket:
build:
context: .
dockerfile: Dockerfile
container_name: websocket
ports:
- "6000:7000"
networks:
- default
nginx:
image: dperson/nginx
container_name: nginx
ports:
- "120:80"
environment:
- STREAM=0.0.0.0:80;websocket:7000
links:
- websocket
networks:
- default
networks:
default:
I have a docker compose container that runs Nginx. The site hosted is just a .test domain, like example.test.
Also in the container Nginx runs a location proxy and redirects it to example.test:8000. But it's not able to connect to that because that's actually being hosted from a different container on the same system (all bridged networks).
How can I let the containers communicate using example.test domain?
Or if I can't get them to communicate via example.test then how can I link them so they can use their docker-compose service name such as api or frontend?
Docker compose:
version: '3'
services:
db:
image: postgres
ports:
- "5432:5432"
django:
build: ./api
command: ["./docker_up.sh"]
restart: always
volumes:
- ./api:/app/api
- api-static:/app/api/staticfiles
ports:
- "8000:8000"
depends_on:
- db
environment:
- MODE=DEV
volumes:
frontend-build:
api-static:
certificates:
2nd compose file (run together):
version: '3'
services:
django:
environment:
- MODE=PROD
#links:
# - hosting
hosting:
build: ./hosting
restart: always
network_mode: bridge
volumes:
- frontend-build:/var/www
ports:
- "80:80"
- "443:443"
environment:
- MODE=PROD
#links:
# - django
volumes:
frontend-build:
With these current settings I get an error when I run it
ERROR: for 92b89f848637_opensrd_hosting_1 Cannot start service hosting: Cannot link to /opensrd_django_1, as it does not belong to the default network
Edit: Altered docker-compose.prod.yml:
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
-
subnet: 172.16.238.0/24
services:
django:
environment:
- MODE=PROD
networks:
app_net:
ipv4_address: 172.16.238.10
But this gives me an error.
ERROR: The Compose file './docker-compose.prod.yml' is invalid because:
networks.app_net value Additional properties are not allowed ('config' was unexpected)
networks.app_net.ipam contains an invalid type, it should be an object
So I tried the options given by #trust512 and #DimaL, and those didn't work.
However after deleting the network and links from my compose files, and removing the existing default network and built containers, it worked, and I can not refer between container using db, django, and hosting.
The only thing different is I changed the composer version from 3 to 3.5.
These are the final files for anyone interested:
version: '3.5'
services:
db:
image: postgres
ports:
- "5432:5432"
django:
build: ./api
command: ["./docker_up.sh"]
restart: always
volumes:
- ./api:/app/api
- api-static:/app/api/staticfiles
ports:
- "8000:8000"
depends_on:
- db
environment:
- MODE=DEV
volumes:
frontend-build:
api-static:
docker-compose.prod.yml:
version: '3.5'
services:
django:
environment:
- MODE=PROD
hosting:
build: ./hosting
restart: always
volumes:
- frontend-build:/var/www
ports:
- "80:80"
- "443:443"
environment:
- MODE=PROD
volumes:
frontend-build:
You can use external_links (https://docs.docker.com/compose/compose-file/#external_links) or try to put all containers on the same virtual network.
As far as I understand you just want them (django and nginx) to be linked across composes?
Then a native solution would be to use external_links exampled here
And use it like this:
services:
[...]
hosting:
[...]
external_links:
- django_1:example
[...]
Where django_1 stands for the container name created by the compose you provided and example is the alias that the container will be visible inside Django container.
Other way round you can just point a example.test domain to a specific address by editing your /etc/hosts (provided you work on linux/mac)
for example by adding a record like
172.16.238.10 example.test
Where the address above would point to your django application (container).
The above can be achieved without altering your /etc/hosts by using native solution from compose (extra_hosts) documented here
Additionally if you prefer a static ip address for your django/nginx containers in case you stick to the /etc/hosts od extra_hosts solution you can utilize another native solution provided by compose that sets up a static ip for a chosen services, properly exampled here
A adjusted listing from the linked documentation:
services:
[...]
django:
[...]
networks:
app_net:
ipv4_address: 172.16.238.10
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
-
subnet: 172.16.238.0/24