Connect to docker sqlserver via ssh - sql-server

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.

Related

How to connect superset to postgresql - The port is closed

My operating system is Linux.
I am going to connect Superset to PostgreSQL.
PostgreSQL port is open and its value is 5432.
PostgreSQL is also running and not closed.
Unfortunately, after a day of research on the Internet, I could not solve the problem and it gives the following error:
The port is closed.
Database port:
command: lsof -i TCP:5432
python3 13127 user 13u IPv4 279806 0t0 TCP localhost:40166->localhost:postgresql (ESTABLISHED)
python3 13127 user 14u IPv4 274261 0t0 TCP localhost:38814->localhost:postgresql (ESTABLISHED)
Please help me, I am a beginner, but I searched a lot and did not get any results.
Since you're running Superset in a docker container, you can't use 127.0.0.1 nor localhost, since they resolve to the container, not the host. For the host, use host.docker.internal
I had a similar problem using docker compose. Port is closed can be due to networking problem. Host.docker.internal doesn’t worked for me on Ubuntu 22. I would like to recommend to not follow official doc and use better approach with single docker image to start. Instead of running 5 containers by compose, run everything in one. Use official docker image, here image. Than modify docker file as follows to install custom db driver:
FROM apache/superset
USER root
RUN pip install mysqlclient
RUN pip install sqlalchemy-redshift
USER superset
Second step is to build new image based on docker file description. To avoid networking problems start both containers on same network (superset, your db) easier is to use host network. I used this on Google cloud example as follow:
docker run -d --network host --name superset supers
The same command to start container with your database. —network host. This solved my problems. More about in whole step to step tutorial: medium or here blog
From the configuration file, you set port 5432, but it does not mean that your pg service is available

Docker container can't connect to Redis

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

Assigning Public IP to SQL Server Docker Image

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.

connect SQL to apache nifi

I'm new to nifi and i want to connect SQL server database to nifi and create a data flow with the processors. how can I do this, can any one Help me with this clearly.
Thanks in Advance
sam
Here are two great articles on getting information in and out of databases with NiFi:
http://www.batchiq.com/database-injest-with-nifi.html
http://www.batchiq.com/database-extract-with-nifi.html
They describe/illustrate how to configure a DBCPConnectionPool service to provide connection(s) to an RDBMS, and example flows to extract data and ingest data.
Expanding on mattyb answer
If you are using the latest Hortonworks sandbox, or other setup that uses docker containers, read below.
You have to install the JDBC jar file inside the docker. For SQL Server, it should be 6.2 or above.
docker ps
docker exec -it <mycontainer uuid> bash
How do I get into a Docker container's shell?
will help you log into the container.
cd file:///usr/lib/jvm/jre/lib/
mkdir jdbc
cd ./jdbc
wget https://download.microsoft.com/download/3/F/7/3F74A9B9-C5F0-43EA-A721-07DA590FD186/sqljdbc_6.2.2.0_enu.tar.gz
tar xvzf sqljdbc_6.2.2.0_enu.tar.gz
cp ./sqljdbc_6.2/enu/mssql-jdbc-6.2.2.jre8.jar ./
jdbc:sqlserver://192.168.1.201:1433;databaseName=[your database]
com.microsoft.sqlserver.jdbc.SQLServerDriver
You might need to replace the ip address with IPv4 address of your host found under ipconfig in Windows or ifconfig in Mac/Linux.
You may change file:///usr/lib/jvm/jre/lib/ to any path you desire.
Expanding on TamusJRoyce's answer
If you are running nifi via a docker image like apache/nifi or the aforementioned Hortonworks sandbox, the following should help you get the required driver on the image so that you don't need to exec into the container to do it manually.
See the comments below the docker file
FROM apache/nifi
USER root
RUN mkdir /lib/jdbc
WORKDIR /lib/jdbc
RUN wget https://download.microsoft.com/download/3/F/7/3F74A9B9-C5F0-43EA-A721-07DA590FD186/sqljdbc_6.2.2.0_enu.tar.gz
RUN tar xvzf sqljdbc_6.2.2.0_enu.tar.gz
RUN cp ./sqljdbc_6.2/enu/mssql-jdbc-6.2.2.jre8.jar ./
USER nifi
EXPOSE 8080 8443 10000 8000
WORKDIR ${NIFI_HOME}
ENTRYPOINT ["../scripts/start.sh"]
The above image uses apache/nifi as the base image. You can use any nifi docker image has a base if you would like.
You can specify any location for lib/jdbc, just remember that you need to use this as the reference for the file location so that it is referenced as file:///lib/jdbc/mssql-jdbc-6.2.2.jre8.jar
Lastly, switch back to the nifi user and finish off with the standard nifi image details. This will allow the image to run correctly.

docker linked container all ports closed

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';

Resources