i try to connect from one docker container to another.
Container A has a Derby DB installed and started, listening on port 3301
Container B should connect to Container A
the docker files look like:
Container A
FROM java:8
# Install Derby
COPY db-derby-10.12.1.1-bin.tar.gz db-derby-10.12.1.1-bin.tar.gz
RUN mkdir /opt/Apache
RUN cp db-derby-10.12.1.1-bin.tar.gz /opt/Apache
RUN tar xzvf /opt/Apache/db-derby-10.12.1.1-bin.tar.gz
EXPOSE 3301
CMD ["/db-derby-10.12.1.1-bin/bin/startNetworkServer", "-p 3301"]
Container B
FROM java:8
# Install nmap
RUN apt-get update
RUN apt-get install -y nmap
COPY db-derby-10.12.1.1-bin.tar.gz db-derby-10.12.1.1-bin.tar.gz
RUN mkdir /opt/Apache
RUN cp db-derby-10.12.1.1-bin.tar.gz /opt/Apache
RUN tar xzvf /opt/Apache/db-derby-10.12.1.1-bin.tar.gz
EXPOSE 9080
I start both container and give them names
Container A
docker run -it --name derby <image>
Container B
docker run -it --link derby:derby <image> /bin/bash
Then i attach container B and
ping derby or ping 172.17.0.2
which is succesfull. But when i try to connect to the derby database via cli tool and giving a jdbc url like
connect 'jdbc:derby://172.17.0.2:3301/testdb;create=true';
I get an connection refused error.
Using nmap to scan the ports of container A results in "All ports are closed"
which is confusing because Docker References states:
So what does linking the containers actually do? You’ve learned that a
link allows a source container to provide information about itself to
a recipient container. In our example, the recipient, web, can access
information about the source db. To do this, Docker creates a secure
tunnel between the containers that doesn’t need to expose any ports
externally on the container; you’ll note when we started the db
container we did not use either the -P or -p flags. That’s a big
benefit of linking: we don’t need to expose the source container, here
the PostgreSQL database, to the network.
Has anybody maybe a hint or solution for me?
Regards
Allright i got it solved. For all others who might be interessted, you need to start Derby with command
startNetworkServer -h 0.0.0.0
that way you tell Derby to accept all connections from outside, restrict it if you need but the parameter has to be present otherwise connections are refused.
Regards
The port is not open as you have not told docker to open it.
EXPOSE in the Dockerfile instructs docker that the container listens on the specified port, but it does NOT open that port or expose it to the host.
--link doesn't open ports either, that is the benefit of link, you can securely connect 2 containers without having to expose any ports to the host.
So, to connect to the derby BD with your command line tool you have 2 options.
1) Open the port - (possible security implications?)
When you run the container, you specificy the port to open.
docker run -it --name derby -p 3301:3301 <image>
The above will map the 3301 port on the container to the 3301 port on the host.
Then you can use the host IP and port 3301 to connect to that container.
2) Connect to the container directly
You can effectively ssh in to the container and run the command on the container itself...
$ sudo docker exec -it derby bash
And then you have a bash session on the derby container directly, and can run commands on it.
UPDATE
To connect from one container to another over the link you can use the ENV vars that docker exposes on the container about the link. http://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#environment-variables
So, on container B you will have ENV vars containing the link name DERBY.
So, DERBY_PORT will be a IP and PORT to connect to the derby container.
However, if the "derby" container is restarted, the IP in the ENV var will be out of date. So it is better to connect to it by its link name.
Docker also sets up host names about the links, so you can connect to the derby container with
http://derby:3301
from within container B
So you could try..
connect 'jdbc:derby://derby:3301/testdb;create=true';
Related
I have a Docker container running a C application using hiredis, which should write data to a Redis server exposed at the default address and port running locally on the same Linux device at 127.0.0.1:6379 .
The Redis server is running in a different Docker container. I start this container running, exposing port 6379 as follows : sudo docker run --name redis_container -d -p 6379:6379 40c68ed3a4d2
redsi-cli can connect to this via 127.0.0.1:6379 without issues.
However, no matter what I try, my container which should write to the Redis gets a Redis connection refused error from the C code all the time. This was my last attempt at running the container : sudo docker run --expose=6379 -i 7340dfee8ea5
What exactly am I missing here? Thanks
The C client is running inside a container, that means 127.0.0.1 points to the container itself, not to your host. You should configure the redis client to redis_container:6379 as that is the name you have used when docker run the redis container. More about this here
Besides, both containers need to be inside the same docker network. Use the following command to create a simple network
docker network create my-net
and add --network my-net to both docker run commands (redis client and redis server)
You can read more about docker network here
I set up Anzograph DB Free Edition in Docker Desktop on my Mac, and (per the commands below) ran it. But I can’t connect to the admin console.
docker pull cambridgesemantics/anzograph
docker run cambridgesemantics/anzograph
When I use the inspect feature in Docker Desktop’s Dashboard, all of the ports for the running image are “not binded”. I would have expected to connect on port 5600 but that doesn’t work – not with localhost, not with 0.0.0.0, not with 127.0.0.1 …
Am I perhaps missing some pre-requisite? I allocated 8 GB of memory to Docker.
From the information you documented, what you are seeing is true as you have not documented in your command the specific ports.
What you entered was the following,
docker run cambridgesemantics/anzograph
What you should run to address this, which is documented on the download page for Anzograph, specifying the ports to install,
docker run -d -p 80:8080 -p 443:8443 --name=anzograph cambridgesemantics/anzograph:latest
AnzoGraph frontend binds to port 8443 (https) and 8080 (http),
AnzoGraph DB binds to port 5600 (gRPC DB management) and 5700 (gRPC DB query) inside the docker container.
Docker Desktop for MAC is mapping these container internal ports to ports on localhost. If you do not tell docker how to map those ports, it uses a random strategy to allocate those ports on localhost. In specifying the mapping
docker run -d -p 80:8080 -p 443:8443 -p 5600:5600 -p 5700:5700 --name=anzograph cambridgesemantics/anzograph:2.1.1-latest
you tell docker what localhost ports to use ( -p { localhost port } : { port inside of container} )
Many users new to docker struggle, when they use for example Kitematic, or similar UIs, that make it simple to deploy a running docker container, however they face complexities understanding and determining these random ports.
So if you are new to docker, and you do not want to use kubernetes yet, please use the command line to specify the localhost ports - it ends up being easier.
I've created a docker container that contains a mssql Database. On the command line ip a gives an ip address for the container, however trying to ssh into it username#docker_ip_address yields ssh: connect to host ip_address port 22: Connection refused. So I'm wondering if I am even able to ssh into the container so I don't have to always be using the docker tool docker exec .... and if so how would I go about doing that?
To ssh into container you should full-fill followings
SSH server(Openssh) should be installed within the container and ssh service should be running
Port 22 should be published from container (when you run the container).more info here > Publish ports on Docker
docker ps command should display mapped ports 22
Hope above information helps for you to understand the situation...
If your container contains a database server, the normal way to interact with will be through an SQL client that connects to it; Google suggests SQL Server Management Studio and that connector libraries exist for popular languages. I'm not clear what you would do given a shell in the container, and my main recommendation here would be to focus on working with the server in the normal way.
Docker containers normally run a single process, and that's normally the main server process. In this case, the container runs only SQL Server. As some other answers here suggest, you'd need to significantly rearchitect the container to even have it be possible to run an ssh daemon, at which point you need to worry about a bunch of other things like ssh host keys and user accounts and passwords that a typical Docker image doesn't think about at all.
Also note that the Docker-internal IP address (what you got from ip addr; what docker inspect might tell you) is essentially useless. There are always better ways to reach a container (using inter-container DNS to communicate between containers; using the host's IP address or DNS name to reach published ports from the same or other hosts).
Basically, alter your Dockerfile to something like the following - that will install openssh-server, alter a prohibitive default configs and start the service:
# FROM a-image-with-mssql
RUN echo "root:toor" | chpasswd
RUN apt-get update
RUN apt-get install -y openssh-server
COPY entrypoint.sh .
RUN cd /;wget https://gist.githubusercontent.com/spekulant/e04521d6c6e1ccffbd3455c673518c5b/raw/1e4f6f2cb32caf3a4a9f73b02efdcbd5dde4ba7a/sshd_config
RUN rm /etc/ssh/sshd_config; cp sshd_config /etc/ssh/
ENTRYPOINT ["./entrypoint.sh"]
# further commands
Now you've got yourself an image with ssh server inside, all you have to do is start the service, you cant do RUN service ssh start because it won't work - docker specifics, refer to the documentation. You have to use a Entrypoint like the following:
#!/bin/bash
set -e
sh -c 'service ssh start'
exec "$#"
Put it in a file entrypoint.sh next to your Dockerfile - remember to chmod 755 entrypoint.sh it. There's one thing to mention here, you still wouldn't be able to ssh into the container - the default SSH server configuration doesn't allow login into root account using a password. So you either change the configs yourself and provide it to the image, or you can trust me and use the file I created - inspect it with the link from Dockerfile - nothing malicious there, only a change from prohibit-password to yes.
Fortunately for us - MSSQL official images start from Ubuntu so all the commands above fit perfectly into the environment.
Edit
Be sure to ask if something is unclear or I'm jumping too fast.
Following the documentation on the microsoft/mssql-server-linux page, it provides the following command to get a docker container running.
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Test!234' -p 1433:1433 -d --name sqllinux microsoft/mssql-server-linux
This works fine and I'm able to open up SSMS and connect to localhost with the credentials:
username: sa
password: Test!234
What I wanted to do after that is to create a Dockerfile that will create the image that will do the same thing:
FROM microsoft/mssql-server-linux
ENV ACCEPT_EULA Y
ENV SA_PASSWORD Test!234
EXPOSE 1433 1433
I then ran docker build . -t sqltestfile followed by docker run sqltestfile.
The container seems to start just fine and through Kitematic I can see (what looks like to me) the same output as running the other image, but I'm not able to connect to this image through SSMS using localhost.
What needs to be changed about the Dockerfile to have it work the way I would expect (can connect to the container instance using SSMS through localhost)?
Any help would be greatly appreciated!
You still need to explicitly publish the port with -p.
From the docs:
The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.
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 to high-order ports.
I am using the latest Docker version (17 CE) on a Mac OSX and I have spun up an instance of SQL Server using the following tutorial: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-setup-docker
The server was set up successfully and I managed to connect to it from outside the container via an SQL command line utility.
The next step is that I want to be able to connect to this instance from another PC within the same local network by assigning a public IP to the instance.
I have looked through a number of tutorials and it seems that with docker 10 this functionality is now possible, so I am looking to do it the 'right' way rather than the hacky way (pre-docker 10). I have looked through a number of tutorials namely How to assign static public IP to docker container and Assign static IP to Docker container.
I was testing using the ubuntu image to stay true to the example, but it still didn't work. Although the image ran, whenever I tried to ping the assigned IP from the same computer docker is installed on, I was not receiving a request timeout. Also on Kitematic the only host under IP AND PORTS is localhost. The image is being assigned to the custom network (docker network prune while instance is running does not prune my custom network) but I can't seem to discover my instance from the outside.
Commands I am using are
$ docker network create --subnet=172.18.0.0/16 mynet123
$ docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash
$ ping 172.18.0.22
and for my sql server
$ docker network create --driver=bridge --subnet=192.168.0.0/24 --gateway=192.168.0.1 mynet
$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=MyPassword123<>' -p 1433:1433 --ip=192.168.0.10 --net=mynet microsoft/mssql-server-linux
$ ping 192.168.0.10
What am I missing?
Any help would be appreciated.