Docker - port prevents listening - networking

I am trying to setup xdebug integration on my docker-based setup.
I am using Docker for Mac 1.12.0-rc2-beta17 with the "native" docker machine
I have a container, with xdebug installed, exposing port 9000 and mapping it to the port 9000:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6950c2a2b05d app "/usr/bin/supervisord" 9 minutes ago Up 9 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:2222->22/tcp app_1
When I'm trying to use PhpStorm to listen to the port 9000 for debug connections, I'm getting an error "Cannot listen: port 9000 is busy".
I must precise that I'm a newbie in networks..

It dependent how you want to connect via Xdebug
xdebug.remote_connect_back=1 said that PHP will wait until a HTTP request with GET parameter XDEBUG_SESSION_START=<IDE_key>. Then will PHP within the server try to connect back via port 9000 where your PHPStorm is listing. Classic don't call us, we will call you situation.
Now your situation with docker say simple, your container is responsible for port 9000. So PHP will get a loopback and PHPStorm isn't able to use port 9000 because its already used by your docker container.
So skip the assignment of port 9000 to docker, that will fix this situation.

You must bind 9000 port with --expose option.
This is the reference
if you are using docker compose sample docker-compose.yml file is here:
version: '2'
services:
your_app:
ports:
- "80:80"
expose:
- "9000"
image: "your-image:tag"

Firstly check your container logs to debug:
docker logs 6950c2a2b05d
or
docker logs app_1
Add -f flags for tail-like behavior:
docker logs -f app_1

Two things I discovered:
There is no need to expose the port 9000 on a container with xdebug (that seems rather counter-intuitive for me, as I do not exactly understand how my IDE connects to xdebug then).
I was able to use xdebug using the workaround described in https://forums.docker.com/t/ip-address-for-xdebug/10460/4.

Related

Can't expose port with podman

I am trying to walk through a tutorial that brings up an application in a docker/podman container instance.
I have attempted to use -p port:port and --expose port but neither seems to work.
I've ensured that I see the port in a listen state with ss -an.
I've made sure there isn't anything else trying to bind to that port.
No matter what I do, I can never hit localhost:port or ip_address:port.
I feel like I am fundamentally missing something but don't know where to look next.
Any suggestions for things to try or documentation to review would be appreciated.
Thanks,
Shawn
Expose: (Reference)
Expose tells Podman that the container requests that port be open, but
does not forward it. All exposed ports will be forwarded to random
ports on the host if and only if --publish-all is also specified
As per Redhat documentation for Containerfile,
EXPOSE indicates that the container listens on the specified network
port at runtime. The EXPOSE instruction defines metadata only; it does
not make ports accessible from the host. The -p option in the podman
run command exposes container ports from the host.
To specify Port Number,
The -p option in the podman run command exposes container ports from
the host.
Example:
podman run -d -p 8080:80 --name httpd-basic quay.io/httpd-parent:2.4
In above example, Port # 80 is the port number which Container listens/exposes and we can access this from outside the container via Port # 8080

Add new port in running docker compose

I am trying to add a SSL certificate to a wordpress container but the default compose configuration only redirects port 80.
How can I add a new port in the running container? I tried to modify the docker-compose.yml file and restart the container but this doesn't solve the problem.
Thank you.
You should re-create container, when listening new port, like this
docker-compose up -d --force-recreate {CONTAINER}
Expose ports.
Either specify both ports (HOST:CONTAINER), or just the container port (an ephemeral host port is chosen).
Note: When mapping ports in the HOST:CONTAINER format, you may experience erroneous results when using a container port lower than 60, because YAML parses numbers in the format xx:yy as a base-60 value. For this reason, we recommend always explicitly specifying your port mappings as strings.
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
https://docs.docker.com/compose/compose-file/#pid
After you add the new port to the docker-compose file, what I did that works is:
Stop the container
docker-compose stop <service name>
Run the docker-compose up command (NOTE: docker-compose start did not work)
docker-compose up -d
According to the documentation the 'docker-compose' command:
Builds, (re)creates, starts, and attaches to containers for a service
... Unless they are already running
That started up the stopped service, WITH the exposed ports I had configured.
Have you tried like in this example:
https://docs.docker.com/compose/compose-file/#ports
Should work like this:
my-services:
ports:
- "80:80"
- "443:443"
you just add the new port in the port section of the docker-compose.yml and then you must do
docker-compose up -d
because it will read the .yml file again and recreate the container. If you do just restart it will not read the new config from the .yml and just restart the same container.

Local Wordpress env with Docker Compose - cURL error 7: Failed to connect to localhost port 8080: Connection refused

I am trying to set up a local Wordpress environment using Docker Compose for the first time. I am currently able to access my Wordpress instance on localhost:8080 and have the files mapped locally.
I purchased a theme, added it to wp-content/themes, and was then prompted to install some required plugins for it. When I click Install, this is the error I receive:
Download failed. cURL error 7: Failed to connect to localhost port 8080: Connection refused
Here is my configuration file:
version: "2"
services:
my-wpdb:
image: mariadb
ports:
- "8081:3306"
environment:
MYSQL_ROOT_PASSWORD: password
my-wp:
image: wordpress:latest
volumes:
- ./:/var/www/html
ports:
- "8080:80"
links:
- my-wpdb:mysql
environment:
WORDPRESS_DB_PASSWORD: password
Probably a simple fix, but I can't seem to figure it out. Thanks!
Following on from papey's answer. curl is trying to connect on the outside port (8080 in your case) whilst inside the container (80).
After much Googling and the only solution people gave was changing the inside and outside ports to 80:80. This is not feasible if you are running another service on port 80.
My solution was to modify the Apache2 conf inside the container so that Apache will respond inside on the outside port. There may be better ways but this is working.
/etc/apache2/ports.conf
Listen 80
Listen 8080
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:*>
According to you docker-compose :
- "8080:80"
8080 is OUTSIDE the container
80 is INSIDE the container
I agree with PaulH's solution.
Execute the following commands inside the running WordPress Linux Docker container then restart the container.
echo -e "\nListen 8080\n" >> /etc/apache2/ports.conf
echo -e "\n<VirtualHost *:*>\n</VirtualHost>\n" >> /etc/apache2/sites-available/000-default.conf
cat /etc/apache2/ports.conf && cat /etc/apache2/sites-available/000-default.conf

Docker Nginx disable default exposed port 80

Is there a way to disable the default EXPOSE 80 443 instruction in the nginx docker file without creating my own image?
I'm using Docker Nginx image and trying to expose only port 443 in the following way:
docker run -itd --name=nginx-test --publish=443:443 nginx
But I can see using docker ps -a that the container exposes port 80 as well:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ddc0bca08acc nginx "nginx -g 'daemon off" 17 seconds ago Up 16 seconds 80/tcp, 0.0.0.0:443->443/tcp nginx-test
How can I disable it?
The expose instruction is in the docker file which the image is built from.
You need to create your own customized Image for that.
To get the job done:
First locate the dockerfile for the official nginx (library)
Then Edit the dockerfile's expose instruction to 443 only.
Now build your own image modified image using official(customized) dockerfile.
To answer your edited question:
Docker uses iptables, While you could manually update the firewall rules to make the service unavailable at a certain port, you would not be able to unbind the Docker proxy. So port 80 will still be consumed on the docker host and docker proxy.
according to nginx docker image configuration , you can set this before container starts passing an environment var like :
docker run -itd -e NGINX_PORT=443 --name=nginx-test nginx
see :
using environment variables in nginx configuration
then in your nginx you can set :
listen ${NGINX_PORT};
There is a workaround to free the port (but not to unexpose it). I tried avoiding to publish the port but it didn't work and I got errors about the por being already in use anyway. Until I found that the trick is to publish the exposed port but mapped to a different one.
Let me explain with an example.
This will still try to use port 80:
docker up -p 443:443
But this will use 443 and some other random port you pick
docker up -p 443:443 -p<some free port>:80
You can do this in your commands, docker-compose or ansible playbooks to be able to start more than one instance on the same machine. (ie: nginx, which exposes port 80 by default)
I do this from docker-compose and ansible too.

How to run 'ionic serve' in global WEB?

I'm new in Ionic Framework, so I need your help. When I'm running ionic serve on localhost everything is great. But now I'm trying to work with Cloud9, it prints:
The port 8100 was taken on the host 172.17.12.3 - using port 8101 instead
The port 35729 was taken on the host 172.17.12.3 - using port 35730 instead
Running live reload server: http://172.17.12.3:35730
Watching : [ 'www/**/*', '!www/lib/**/*' ]
Running dev server: http://172.17.12.3:8101
But this adresses don't work at all. And i get an error from Cloud9:
Error: you may be using the wrong PORT & IP for your server app. Try passing $PORT and $IP to properly launch your application.
So how can I set $PORT and $IP in Ionic?
Since Cloud9 forwards port 8080 (which is the value of $PORT), you need to tell ionic to use that instead. With the recent change of allowing multiple ports, port 8081 and 8082 are also allowed, so you need to tell ionic to use 8081 (or 8082) as the livereload ports. The command that should work is:
ionic serve -p 8080 -l 8081
I also think that adding -a would help since with that option it appears to bind to IP 0.0.0.0 which you should be binding to in the first place. For more information about Ionic cli options, please check out the Ionic CLI github page
simple solution is to close the terminal in which you are running the serve request and open new terminal then give ionic serve request it will take the 8100 port (which you gave in your code)

Resources