What is the use of container_name in docker-compose.yml file? Can I use it as hostname which is nothing but the service name in docker-compose.yml file.
Also when I explicitly write hostname under services does it override the hostname represented by service name?
hostname: just sets what the container believes its own hostname is. In the unusual event you got a shell inside the container, it might show up in the prompt. It has no effect on anything outside, and there’s usually no point in setting it. (It has basically the same effect as hostname(1): that command doesn’t cause anything outside your host to know the name you set.)
container_name: sets the actual name of the container when it runs, rather than letting Docker Compose generate it. If this name is different from the name of the block in services:, both names will be usable as DNS names for inter-container communication. Unless you need to use docker to manage a container that Compose started, you usually don’t need to set this either.
If you omit both of these settings, one container can reach another (provided they’re in the same Docker Compose file and have compatible networks: settings) using the name of the services: block and the port the service inside the container is listening in.
version: '3'
services:
redis:
image: redis
db:
image: mysql
ports: [6033:3306]
app:
build: .
ports: [12345:8990]
env:
REDIS_HOST: redis
REDIS_PORT: 6379
MYSQL_HOST: db
MYSQL_PORT: 3306
The easiest answer is the following:
container_name: This is the container name that you see from the host machine when listing the running containers with the docker container ls command.
hostname: The hostname of the container. Actually, the name that you define here is going to the /etc/hosts file:
$ exec -it myserver /bin/bash
bash-4.2# cat /etc/hosts
127.0.0.1 localhost
172.18.0.2 myserver
That means you can ping machines by that names within a Docker network.
I highly suggest set these two parameters the same to avoid confusion.
An example docker-compose.yml file:
version: '3'
services:
database-server:
image: ...
container_name: database-server
hostname: database-server
ports:
- "xxxx:yyyy"
web-server:
image: ...
container_name: web-server
hostname: web-server
ports:
- "xxxx:xxxx"
- "5101:4001" # debug port
you can customize the image name to build & container name during docker-compose up for this, you need to mention like below in docker-compose.yml file.
It will create an image & container with custom names.
version: '3'
services:
frontend_dev:
stdin_open: true
environment:
- CHOKIDAR_USEPOLLING=true
build:
context: .
dockerfile: Dockerfile.dev
image: "mycustomname/sample:v1"
container_name: mycustomname_sample_v1
ports:
- '3000:3000'
volumes:
- /app/node_modules
- .:/app
Related
I have a docker-compose.yml:
services:
backend:
build:
./backend
ports:
- 8100:8100
container_name: "backend"
frontend:
build:
./frontend
ports:
- 4200:4200
container_name: "frontend"
depends_on:
- backend
And i want to get rid of the ports part. I have .env files in the folders /backend and /frontend with the portnumber set in there (e.g PORT=8100). In the dockerfile i can just do Export ${PORT}. But since i cant read the .env from the docker-compose location i am not able to expose the port in the same way. Is it possible to just have a wildcard to expose the port of the containers to the same port on my host like:
ports:
- *:*
No, there's no syntax like this. The ports: syntax always requires you to specify the container-side port, and you must have a ports: block if you want the container to be accessible from outside Docker.
If you weren't using Compose there is a docker run -P (capital P) option, but there the container ports are published on randomly-selected host ports. (This is one of the few contexts where "expose" as a Docker verb does anything useful: docker run -P publishes all exposed ports.)
However: there is no rule that the two port numbers must match. Rather than having the port number configurable in the Dockerfile (requiring a rebuild on any change) it's more common to use a fixed port number in the image and allow the host port number to be configured at deploy time.
For example, assume both images are configured to use the default Express port 3000. You can remap these when you run the containers:
version: '3.8'
services:
backend:
build: ./backend
ports: ['8100:3000']
frontend:
build: ./frontend
depends_on: [backend]
ports: ['4200:3000']
I have a java application, that connects through external database through custom docker network
and I want to connect a Redis container.
docker-redis github topic
I tried the following on the application config:
1 localhost:6379
2 app_redis://app_redis:6379
3 redis://app_redis:6379
nothing works on my setup
docker network setup:
docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 mynet
Connect to a Database Running on Your Docker Host
PS: this might be off-topic, how I can add the network on docker-compose instead of external
docker-compose:
services:
app-kotin:
build: ./app
container_name: app_server
restart: always
working_dir: /app
command: java -jar app-server.jar
ports:
- 3001:3001
links:
- app-redis
networks:
- front
app-redis:
image: redis:5.0.9-alpine
container_name: app-redis
expose:
- 6379
networks:
front:
external:
name: mynet
with the setup above how can I connect through a Redis container?
Both containers need to be on the same Docker network to communicate with each other. The app-kotin container is on the front network, but the app-redis container doesn't have a networks: block and so goes onto an automatically-created default network.
The simplest fix from what you have is to also put the app-redis container on to the same network:
app-redis:
image: redis:5.0.9-alpine
networks:
- front
The Compose service name app-redis will then be usable as a host name, from other containers on the same network.
You can simplify this setup considerably. You don't generally need to manually specify IP configuration for the Docker-private networks. Compose can create the network for you, and in fact it will create a network named default for you. (Networking in Compose discusses this further.) links: and expose: aren't used in modern Docker networking; Compose can provide a default container_name: for you; and you don't need to repeat the working_dir: or command: from the image. Removing all of that would leave you with:
version: '3'
services:
app-kotin:
build: ./app
restart: always
ports:
- '3001:3001'
app-redis:
image: redis:5.0.9-alpine
The server container will be able to use the other container's Compose service name app-redis as a host name, even with this minimal configuration.
I want to know how to connect localhost with another host name.
I tried using extra_host but it did not go well.
Is the writing style of docker-compose.yml wrong?
thanks.
docker-compose.yml
version: "3.2"
services:
od-app:
build: ./app
ports:
- 3000:3000
- 80:3000
volumes:
- ./app/src:/var/www/html
links:
- od-api:api.localhost*
extra_hosts:
- "test.example.com:127.0.0.1"
od-api:
build: ./api
ports:
- 8080:80
volumes:
- ./api/src:/var/www/html
- /var/www/html/node_modules
extra_hosts in docker-compose.yaml just add the dns mapping 127.0.0.1 test.example.com to container's /etc/hosts.
This means this dns mapping just effect inside the container, not be able to visit on host. If you want to visit container's service like using test.example.com:80 from host, you should add this mapping in host's /etc/hosts instead.
I cannot get mariadb to use another port other than 3306 when running it in a docker container using a docker-compose file.
I have already read the mariadb/docker documentation, searched online and conducted my own experiments.
docker-compose file:
version: '3.1'
services:
db:
image: mariadb
restart: always
environment:
- MYSQL_ROOT_PASSWORD=mypassword
- MYSQL_TCP_PORT=33030
- MYSQL_UNIX_PORT=33020
ports:
- "33020:33020"
Dockerfile:
FROM: mariadb: 10.3.14
COPY mydbscript.sql /docker-entrypoint-initdb.d/
EXPOSE 33020
CMD ["mysqld"]
It never uses port 33020. It still uses port 3306. How can I pass the port dynamically via the docker-compose file at run-time?
You need to replace the default my.cnf to specify a custom port for MariaDB/MySQL:
cd /where/your/docker-compose.yml/located
docker run -it mariadb cat /etc/mysql/my.cnf > my.cnf
# use any text editor your like to open my.cnf, search for "port = 3306"
# and replace it to the port you like to have.
Configure your docker-compose.yml like this:
version: '3.1'
services:
db:
image: mariadb
restart: always
volumes:
- type: bind
source: ./my.cnf
target: /etc/mysql/my.cnf
environment:
- MYSQL_ROOT_PASSWORD=mypassword
# add your other configurations here
The container image is statically bound to :3306. If you wish to change this, you'll need to build a new image and configure the database to run elsewhere.
However, Docker permits you to map (publish) this as a different port :33020.
The correct way to do this is to:
docker-compose MYSQL_TCP_PORT=3306
docker-compose ports: - "33020:3306"
Dockerfile EXPOSE 3306 (unchanged)
Containers (internally) will correctly reference :3306 but externally (from the host) the database will be exposed on :33020.
NB Within docker-compose (network), other containers must continue to reference the database on port :3306.
#DazWilkin, #philip-tzou, of course it's possible!
How to set the port without config file is even explained in the dockerhub-page of mariadb. (https://hub.docker.com/_/mariadb) #Software just did the mistake of using '=' instead of ':' in the docker-compose.yml. I did it the first time too because I copied the environment veriables from a docker run bash file.
This docker-compose.yml (with .env File) works for me to set both, internal and external port of my mariaDB service:
version: "3.9"
services:
database:
image: mariadb:10.8
container_name: ${db_containername}
environment:
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes
MARIADB_DATABASE: ${db_database}
MARIADB_USER: ${db_user}
MARIADB_PASSWORD: ${db_password}
MYSQL_TCP_PORT: ${db_port_internal}
MARIADB_AUTO_UPGRADE: 1
MYSQL_UNIX_PORT: /run/mysqld/mysqld.sock
MARIADB_MYSQL_LOCALHOST_USER: true
restart: always
ports:
- '${db_port_external}:${db_port_internal}'
expose:
- ${db_port_external}
volumes:
- 'database_data:/var/lib/mysql'
This is how you can set a different port for your mariadb inside the container
1. Create a my.cnf file inside the same directory as you dockerfile
write this inside the my.cnf file
[mysqld]
port = 33020
2. Add the cnf file to the dockerfile & edit the EXPOSE
Add this line of code to your docker file
COPY my.cnf /etc/mysql/my.cnf
And make sure to change the external exposed port to the one you want to use e.i
EXPOSE 33020
3. Make sure to change the port in the docker-compose.yml file
ports:
- "33020:33020"
You can now connect to your database in either the terminal using the docker exec -it {databasename} mysql -u root -p or in something like mysql workbench by setting the ip: localhost and the port to 33020
Hope this helps.
I can't find a real definition of what a docker-compose file is.
Is it correct to say this:
A docker-compose file is a YAML file that allows us to deploy multiples Docker containers at the same time.
I'd like to be able to explain a bit better what a docker-compose file is.
A docker-compose.yml is a config file for Docker Compose.
It allows to deploy, combine, and configure multiple docker containers at the same time. The Docker "rule" is to outsource every single process to its own Docker container.
Take for example a simple web application: You need a server, a database, and PHP. So you can set three docker containers with Apache2, PHP, and MySQL.
The advantage of Docker Compose is easy configuration. You don't have to write a big bunch of commands into Bash. You can predefine it in the docker-compose.yml:
db:
image: mysql
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: example_db
MYSQL_USER: root
MYSQL_PASSWORD: rootpw
php:
image: php
ports:
- "80:80"
- "443:443"
volumes:
- ./SRC:/var/www/
links:
- db
As you can see in my example, I define port forwarding, volumes for external data, and links to the other Docker container. It's fast, reproducible, and not that hard to understand.
The Docker Compose file format is formally specified which enables docker-compose.yml files being executed with something else than Docker, Podman for example.
Docker Compose is a tool that allows you to deploy and manage multiple containers at the same time.
A docker-compose.yml file contains instructions on how to do that.
In this file, you instruct Docker Compose for example to:
From where to take the Dockerfile to build a particular image
Which ports you want to expose
How to link containers
Which ports you want to bind to the host machine
Docker Compose reads that file and executes commands.
It is used instead of all optional parameters when building and running a single docker container.
Example:
version: '2'
services:
nginx:
build: ./nginx
links:
- django:django
- angular:angular
ports:
- "80:80"
- "8000:8000"
- "443:443"
networks:
- my_net
django:
build: ./django
expose:
- "8000"
networks:
- my_net
angular:
build: ./angular2
links:
- django:django
expose:
- "80"
networks:
- my_net
networks:
my_net:
external:
name: my_net
This example instructs Docker Compose to:
Build nginx from path ./nginx
Links angular and django containers (so their IP in the Docker network is resolved by name)
Binds ports 80, 443, 8000 to the host machine
Add it to network my_net
(so all 3 containers are in the same network and therefore accessible from each other)
Then something similar is done for the django and angular containers.
If you would use just Docker commands, it would be something like:
docker build --name nginx .
docker run --link django:django angular:angular --expose 80 443 8000 --net my_net nginx
So while you probably don't want to type all these options and commands for each image/container, you can write a docker-compose.yml file in which you write all these instructions in a human-readable format.