Skip to content

Expose to localhost the default port number (3000) of the 3scale_backend listener on the Makefile 'dev' rule#8

Merged
miguelsorianod merged 1 commit intomasterfrom
feature/expose-3scale-backendlistener-port
Apr 5, 2018
Merged

Expose to localhost the default port number (3000) of the 3scale_backend listener on the Makefile 'dev' rule#8
miguelsorianod merged 1 commit intomasterfrom
feature/expose-3scale-backendlistener-port

Conversation

@miguelsorianod
Copy link
Copy Markdown
Contributor

In order to be able to perform local development testing more easily we expose the default port (3000) of the 3scale_backend listener when executing the Makefile 'dev' rule

Copy link
Copy Markdown
Contributor

@unleashed unleashed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's try it without --expose to see whether it also picks up the server in any other port... also make the commit title shorter (ie. around 80 chars max)

@eguzki
Copy link
Copy Markdown
Member

eguzki commented Apr 3, 2018

Isolation level is being lowered a little bit. Will not be possible to run two dev containers concurrently. Not a big deal, though.

@eguzki
Copy link
Copy Markdown
Member

eguzki commented Apr 3, 2018

--expose does not have actual effect on networking, if I am not wrong. It is just a way to register info about container (or image in dockerfile) that can be requested by other containers using docker API.

Should not make any difference

@miguelsorianod
Copy link
Copy Markdown
Contributor Author

By reading at the documentation, as eguzki said it seems --expose flag does not have an effect on networking:
https://docs.docker.com/engine/reference/builder/#expose

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.

So it is purely informational to docker/the clients that use the container or the docker API to obtain container information.

Regarding the need of having to expose ports or not:
· If the --network parameter is not specified, then the container is created within the 'bridge' network, which is a default docker bridged network (https://docs.docker.com/network/bridge/). Machines that are within this bridged network can communicate with each other without the need of publishing ports. Due to the docker host machine is also in this bridged network (can be seen by looking at docker0 interface in the local machine) then it can be communicated directly with the container at any port without the need of publishing any port in the container.

I think it is better to not limit ourselves to only be able to run one container at a time so it may be not a good idea to start the container in local host mode. If in a future there is the need to connect via localhost we can always configure the publishing of the port to localhost, which would be a valid syntax:

       Format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort Both hostPort and containerPort can be specified as a range of ports.  When specifying ranges for both,
       the number of container ports in the range must match the number of host ports in the range.  (e.g., docker run -p 1234-1236:1222-1224 --name thisWorks -t busybox but not docker run -p
       1230-1236:1230-1240 --name RangeContainerPortsBiggerThanRangeHostPorts -t busybox) With ip: docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage Use docker port to see the
       actual mapping: docker port CONTAINER $CONTAINERPORT

What do you think?

@unleashed
Copy link
Copy Markdown
Contributor

I think it is completely ok and expected to have a single apisonator-dev container per machine running (and it is designed that way), and also to have it expose the listener service on the local host for convenience.

What we need to know is whether we can limit the services exposed to just the listener (ie. not anything else, like the Redis server or other services that are currently run simultaneously) in order to avoid conflict with other services a developer might have in their machine (ie. a local Redis install). This might need to make use of -p 3000:3000 to avoid mapping everything?

Can you check this is the case?

@miguelsorianod
Copy link
Copy Markdown
Contributor Author

Hi,

Host networking in docker (https://docs.docker.com/network/host/) removes the network isolation from the Docker host so every port that is listening on the container will be made available in the docker host.
No concept of mapping applies because there is no network isolation.
If you try to specify a port remapping with local networking specified in docker you can see there is no ports configured even if you specify -p.

For example, I specified the following parameters: --network=host -p 5000:3000 to remap the port but no port remapping has been done because it uses local networking:

[msoriano@localhost apisonator]$ ps aux | grep -i apisonator-dev
msoriano 22905  0.0  0.0 120112  3252 pts/3    S+   12:56   0:00 /bin/sh /home/msoriano/repositories/apisonator/script/make_report_time.sh -c if docker ps -a --filter name=apisonator-dev | grep -q apisonator-dev 2> /dev/null >&2; then \ ?docker start -ai apisonator-dev ; \ else \ docker run -ti -h apisonator-dev --network=host -p 5000:3000 -v \ ?/home/msoriano/repositories/apisonator:$(docker run --rm apisonator-dev /bin/bash -c 'cd && pwd')/apisonator:z \ ?-u $(docker run --rm apisonator-dev /bin/bash -c 'id -u'):$(docker run --rm apisonator-dev /bin/bash -c 'id -g') \ ?--name apisonator-dev apisonator-dev /bin/bash ; \ fi
msoriano 22907  0.0  0.0   4276   736 pts/3    S+   12:56   0:00 time -o bench.txt -a -f [%E] : if docker ps -a --filter name=apisonator-dev | grep -q apisonator-dev 2> /dev/null >&2; then \ ?docker start -ai apisonator-dev ; \ else \ docker run -ti -h apisonator-dev --network=host -p 5000:3000 -v \ ?/home/msoriano/repositories/apisonator:$(docker run --rm apisonator-dev /bin/bash -c 'cd && pwd')/apisonator:z \ ?-u $(docker run --rm apisonator-dev /bin/bash -c 'id -u'):$(docker run --rm apisonator-dev /bin/bash -c 'id -g') \ ?--name apisonator-dev apisonator-dev /bin/bash ; \ fi -- sh -c if docker ps -a --filter name=apisonator-dev | grep -q apisonator-dev 2> /dev/null >&2; then \ ?docker start -ai apisonator-dev ; \ else \ docker run -ti -h apisonator-dev --network=host -p 5000:3000 -v \ ?/home/msoriano/repositories/apisonator:$(docker run --rm apisonator-dev /bin/bash -c 'cd && pwd')/apisonator:z \ ?-u $(docker run --rm apisonator-dev /bin/bash -c 'id -u'):$(docker run --rm apisonator-dev /bin/bash -c 'id -g') \ ?--name apisonator-dev apisonator-dev /bin/bash ; \ fi
msoriano 22908  0.0  0.0 120108  3092 pts/3    S+   12:56   0:00 sh -c if docker ps -a --filter name=apisonator-dev | grep -q apisonator-dev 2> /dev/null >&2; then \ ?docker start -ai apisonator-dev ; \ else \ docker run -ti -h apisonator-dev --network=host -p 5000:3000 -v \ ?/home/msoriano/repositories/apisonator:$(docker run --rm apisonator-dev /bin/bash -c 'cd && pwd')/apisonator:z \ ?-u $(docker run --rm apisonator-dev /bin/bash -c 'id -u'):$(docker run --rm apisonator-dev /bin/bash -c 'id -g') \ ?--name apisonator-dev apisonator-dev /bin/bash ; \ fi
msoriano 23187  0.0  0.0 623716 16104 pts/3    Sl+  12:56   0:00 /usr/bin/docker-current run -ti -h apisonator-dev --network=host -p 5000:3000 -v /home/msoriano/repositories/apisonator:/home/ruby/apisonator:z -u 1000:1000 --name apisonator-dev apisonator-dev /bin/bash
msoriano 23823  0.0  0.0 119660  1044 pts/2    S+   12:59   0:00 grep --color=auto -i apisonator-dev

$ docker port apisonator-dev
$ 

All opened ports in the docker container are made available in the docker host in that case.

If what we want to do is to make available the backend_service port into the local machine through the localhost interface (127.0.0.1) what can be done is to perform a port remapping (with -p) using the bridged networking type (the default one when no --network is specified). In that way we can:
· Perform requests to the backend_service via localhost with an arbitrary port number that we have defined (which may be the same or different than the port in the container)
· Perform requests to the backend_service via the IP address of the container that is configured when the bridged mode is applied.

For example, if we specify -p 5000:3000, this would remap the port 3000 of the container to the port 5000 of the host machine (we can perform -p 3000:3000 if we want to use the same port than the one used in the container):

[msoriano@localhost apisonator]$ curl 127.0.0.1:5000/status
{"status":"ok","version":{"backend":"2.85.0"}}[msoriano@localhost apisonator]$ 

[msoriano@localhost apisonator]$ curl 172.17.0.2:3000/status
{"status":"ok","version":{"backend":"2.85.0"}}[msoriano@localhost apisonator]$ 

I think the best idea would be to use the bridged networking (default one) with -p 3000:3000

What do you think?

@unleashed
Copy link
Copy Markdown
Contributor

unleashed commented Apr 4, 2018 via email

@mikz
Copy link
Copy Markdown
Contributor

mikz commented Apr 4, 2018

👍 for bridge, host networking is a bit broken on Docker for macOS.

@miguelsorianod miguelsorianod force-pushed the feature/expose-3scale-backendlistener-port branch from 4b1d8f5 to e4a3339 Compare April 4, 2018 13:13
@miguelsorianod
Copy link
Copy Markdown
Contributor Author

I have configured the publishing of port 3000 and modified the commit.

You can proceed to review it again.

Thank you.

Comment thread Makefile Outdated
docker start -ai apisonator-dev ; \
else \
docker run -ti -h apisonator-dev -v \
docker run -ti -h apisonator-dev --expose=3000 -p 3000:3000 -v \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW it is pretty common to be able to configure local port by PORT env variable.
That would be helpful for people running more than one ruby app locally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand you want to be able to modify the port in use in the local host machine so it does not cause conflict with other local ports of other service that may use the same port.

I performed a new commit that would allow this with an environment variable.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. And common name for this variable is PORT.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

I agree that usually PORT name is a good name but I chose the name BACKEND_SERVICE_PORT in order to be able to differentiate it from other potentially configurable ports in this Makefile for other services/actions.
For example, if in the future we want to be able to modify the container port we would need another environment variable, which would have to have another name. The same think would happen if we want to be able to control other ports on other services.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this command starts one service that starts listening on one port then I really don't see the need for namespaced name. If there would be need in the future to customize other ports, then those could be named differently, because PORT is the port the service starts listening on.
I don't really like making compromises now for future that might never arrive.

Good to merge anyway 👍 at least it is configurable (for someone who is going to check the makefile).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi mikz,

Seems reasonable what you are saying. I updated the variable name and added documentation on the Makefile so people can be aware of this variable.

@miguelsorianod miguelsorianod force-pushed the feature/expose-3scale-backendlistener-port branch from e2541c6 to cff2ae5 Compare April 5, 2018 07:58
In order to be able to perform local development testing more easily we expose and publish the default port (3000) of the 3scale_backend listener
when executing the Makefile 'dev' rule.

The variable PORT has been added to allow the client of the Makefile to remap the local backend_service port to a desired one. If the variable is not defined then the value is the default port of the
backend_service service (3000).

Also, the README.md documentation has been updated accordingly.
@miguelsorianod miguelsorianod force-pushed the feature/expose-3scale-backendlistener-port branch from cff2ae5 to aa3d1af Compare April 5, 2018 08:01
@miguelsorianod miguelsorianod merged commit 1f7c92b into master Apr 5, 2018
@bors bors Bot deleted the feature/expose-3scale-backendlistener-port branch April 5, 2018 09:54
unleashed pushed a commit that referenced this pull request Apr 5, 2018
8: Makefile: publish default backend_service port on 'dev' rule. r=davidor,mikz a=miguelsorianod

In order to be able to perform local development testing more easily
we expose and publish the default port (3000) of the 3scale_backend
listener when executing the Makefile 'dev' rule.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants