I am unable to change the port that Swagger uses in docker compose. It works fine with regular docker, I simply set the -p argument on the run command. It seems that I should just need to set the ports field in the docker-compose file. But no matter what I try it just runs on 8080.
I am using the latest versions of docker and docker-compose. The docker image is called swaggerapi/swagger-ui. I have attempted setting the ports field for the container. Also tried setting the url variable in the swagger definition file. Tried changing the expose port. I tried with the docker-compose run command which lets you start an individual service and has the -p argument. Still nothing.
Ideally I should use this to build and run:
sudo docker-compose up --build --force-recreate
My compose file:
version: '3'
services:
swagger:
build: swagger
network_mode: "host"
ports:
- "8081:8080"
env_file: .env
environment:
- SWAGGER_JSON=/swagger.json
volumes:
data:
driver: "local"
And the docker file for the swagger service:
FROM swaggerapi/swagger-ui
EXPOSE 8081
COPY swagger.json /swagger.json
ENV SWAGGER_JSON "/swagger.json"
No matter what I do it wont change ports.
Just change the port in your docker-compose file
swagger:
build: swagger
network_mode: "host"
ports:
- "8081:"**Port which you want to expose**"
env_file: .env
environment:
- SWAGGER_JSON=/swagger.json
Related
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've built a Docker compose file to run database and a nodejs microservice in their own containers.
The database seems to stops working if I don't specify the EXPOSE ports, even though I've specified them in the compose file. Do we have to specify ports in both places?
database/Dockerfile
FROM mysql
ENV MYSQL_DATABASE=test
ENV MYSQL_ROOT_PASSWORD=password
EXPOSE 6603:3306
COPY ./schema.sql /docker-entrypoint-initdb.d/
docker-compose.yml
version: '3'
services:
database:
build:
./database
ports:
- "6603:3306"
image: "test-mysql"
container_name: "test-mysql"
web:
build:
./service
ports:
- "8080:8080"
depends_on:
- database
image: "test-nodejs"
container_name: "test-nodejs"
restart: on-failure
Do I've to specify ports 6603:3306 in both Database/Dockerfile and docker-compose.yml file?
On modern Docker, EXPOSE statements are almost purely documentation. You also can't un-expose a port once it's been exposed in a Dockerfile, and the standard mysql image will already EXPOSE 3306, so you don't need an EXPOSE line in your own Dockerfile.
(In any case a Dockerfile can never specify a specific host port it wants to use, only a container-side port that should be made visible.)
only EXPOSE 3306 - In dockerfile which tells inside container DB running on that port.
ports:
- "6603:3306"
This is perfect which tells outside container you can access DB with 6603 Port.
Yes it's necessary to specify the ports in file without it one will not able to expose the container port and in docker compose if you will not specify port it will not be able to make connection.
But in docker file you can do
EXPOSE 3360
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
I'm using this docker image https://github.com/moodlehq/moodle-docker and it works as advertised. Among other things it exposes web server on localhost:8000 address. What I would like is to bind it to the host's ip instead.
Using raw docker something like that is accomplished with
docker run --network=host [container]
What should be placed in the yml file for docker-compose as documentation is a bit confusing for me.
You can use network_mode in compose files -
network_mode: "host"
Sample compose -
version: '3'
services:
api:
image: 'node:6-alpine'
network_mode: host
environment:
- NODE_ENV=production
command: "tail -f /dev/null"
Ref - https://docs.docker.com/compose/compose-file/#network_mode
docker-compose.yml
version: "3"
services:
mycentos:
image: mycentos
container_name: '{{.Node.Hostname}}-rh7'
hostname: '{{.Node.Hostname}}-rh7'
env_file:
- docker_run.env
privileged: true
cap_add:
- SYS_PTRACE
- SYS_ADMIN
networks:
- testnet
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
networks:
testnet:
Running docker-compose is giving me this error:
ERROR: for mycentos-rh7 Cannot create container for service mycentos-rh7: Invalid container name ({{.Node.Hostname}}-rh7), only [a-zA-Z0-9][a-zA-Z0-9_.-] are allowed
PS I can run the above compose file without errors via "docker stack deploy" so the problem seem to be localized to docker-compose
The reason for wanting to use docker-compose instead of docker stack deploy is testing containers is easier because they stay to localhost and i can grab contianer id to exec into
docker-compose variable substitution is not very powerful and in your context there is nothing like {{.Node.Hostname}}, but you can override the values in an additional file:
docker-compose.override.yaml
version: "3"
services:
mycentos:
container_name: '${HOSTNAME}-rh7'
hostname: '${HOSTNAME}-rh7'
The environment variable HOSTNAME need to be set during start up:
HOSTNAME=$(hostname) docker-compose -f docker-compose.yaml -f docker-compose.override.yaml up -d
This should work for your use case.
Using templates is not supported for container_name. From official documentation:
You can use templates for some flags of service create, using the
syntax provided by the Go’s text/template package. The supported flags
are the following :
--hostname
--mount
--env
PS I can run the above compose file without errors via "docker stack
deploy" so the problem seem to be localized to docker-compose
This is because the container_name directive is ignored in that case:
Note: This option is ignored when deploying a stack in swarm mode with
a (version 3) Compose file.