Equivalent of using a ssh tunnel - postgresql

Using virtual hosts rather than deployed Docker container it was a normal work process for me to create ssh tunnels in order to access delimited machines from my local box. For instance connect with my psql client to a Postgres instance which I could only reach from a bastion box.
With Docker everything is boxes away even more. Is there an equivalent for doing the same but with Docker? Tunnel through the Docker instance to the RDS instance?

You use the docker CLI to connect to a running container. For instance...
To log into a db running in a container you can use (from your local machine)
docker exec -it mypsqlcontainer psql -U username dbname
I personally almost never have to ssh into the host. Everything can be done through the docker CLI.

You can make ssh-tunnel to the docker host. DB port must be accessible from docker host (i.e. using "-p" docker run option).
If you prefer not publishing DB port you can create jumpbox container with ssh server, publish port 22 on this container and user container linking to link jumpbox container with DB container.

Related

How to connect to containerized database with its IP?

I'm new to Docker. I successfully created a PostgreSQL container my-database and I am able to access it from SQLTools on my local machine with server address localhost and the port.
I got the containerized database's IP address from the following command:
docker container inspect my-database
But when I go back to SQLTools or the PHP web application (not containerized) and try to connect to my-database with the IP address I got above, it couldn't connect successfully.
What am I missing here?
FYI, I also created another container and was able to connect to my-database with the following way: Use the same network for both my-database and the second container.
It all depends on how you enable access to the database.
If your php service runs in the same machine, then localhost could work
If its on a different machine in the same network, then use the network IP assigned to that machine. If you have your php server in a totally different location, then you may want to use something like an nginx reverse proxy to your docker container.
So in your case you should get the ip:port where your db container runs and use that. Docker inspect shows the internal network ip which only helps other containers in the same virtual network connect to a container.
You never need the docker inspect IP address. You can only connect to it in two specific circumstances: if you're in a different container on the same Docker network, or if you're (a) not in a container at all, (b) on the same host, and (c) that host is running native Linux and not a different OS.
You've already identified the right answers. Say you start the container as
docker network create any-network-name
docker run \
--name database \
--net any-network-name \
-p 5432:5432 \
postgres
From another Docker container on the any-network-name network, you can use the database container name as a DNS name, and avoid the manual IP lookup; ignore any -p options and use the "normal" port for the service. From outside a container, you can use the host's DNS name or IP address (or, if it's the same host, localhost) and the first -p port number.
If you're running this in Docker Compose, it automatically creates a network for you and registers containers under their Compose service name; you do not need networks:, container_name:, or other similar settings.
version: '3.8'
services:
database:
image: postgres
ports: ['5432:5432']
application:
build: .
environment:
- PGHOST=postgres

Can remote Docker be used locally?

For examample, I have a Postgres docker container and I connect to it with psql -H localhost:5432.
If I "move" this container to the remote machine and add a Docker context with docker context create remote --docker 'host=ssh://<remote machine>' then after docker use context remote I can see that it is up and running remotely. I can manage that remote container without ssh-ing remote machine, everything consider Docker is fine.
However, I don't know how to connect to this remote container with psql, without exposing a port to the internet on remote host.
I thought that when I use Docker context all connections to my local Docker are transfered via SSH-tunnel to the remote Docker, but it seems to be not true.
So, is remote host feature is only for remote Docker management and to actually interact with services inside them I should open ports, configure firewall, etc (and that kills the point of moving everything on remote machine) or I just do something wrong and Docker supposed to work as I described above?

Connect to Windows Postgres from Debian Docker container

I am running Postgres on a Windows 10 computer, and I want to connect to it from a Docker container. I've followed instructions from many sources and things should be working, but they're not.
Command line used to create Docker container:
docker run --rm -d --network=host --name mycontainer myimage
In postgresql.conf:
listen_addresses = '*'
In pg_hba.conf:
host all all 172.17.0.0/16 trust
In the bash shell of my container, I run:
psql -h 127.0.0.1
and I get the error:
psql: could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432?
Needless to say, Postgres is definitely running on my computer and I am able to query it from local applications. What am I missing?
THIS WON'T WORK FOR DOCKER v18.03 AND ONWARDS
The answer is already there - From inside of a Docker container, how do I connect to the localhost of the machine?
This question is related to a mysql setup, but it should work for your case too.
FOR DOCKER v18.03 ONWARDS
Use host.docker.internal to refer to the host machine.
https://docs.docker.com/docker-for-windows/networking/#i-cannot-ping-my-containers
As you've discovered, --network-host doesn't work with Docker for Windows or Docker for Mac. It only works on Linux hosts.
One option for this scenario might be to host PostgreSql in a container, also. If you deploy them with a docker-compose file, you should be able to have two separate Docker containers (one for the database and one for your service) that are networked together. By default, docker-compose will expose containers to others in the same compose file using the container name as its DNS name.
You could also consider including the database in the same container as your service, but I think the docker-compose solution is better for several reasons:
It adheres to the best practice of each container having only a single process and single responsibility.
It means that you can easily change and re-deploy your service without having to recreate the database container.
Configure the connection inside your docker container with the real ip-address of your host or as workaround with a dns name

How to use pgAdmin to connect postgresql image on a docker container?

I just cloned a project from GitHub and in the readme file it asks me to run docker-compose up to run the PostgreSQL image...
I assume that after I run the command, the PostgreSQL server image will start in the Docker container on my pc using port 5432. Then I run npm install and npm start to start the project (the database tables will be automatically created using an ORM framework). However, when I open my pgAdmin to connect to the server, it says it successfully connected but I could not find those tables created. Here I guess the pgAdmin didn't connect the PostgreSQL server (Docker image) on 5432... So my question is whether it is possible to use pgAmin installed in my local pc to connect to the PostgreSQL server Docker image which is already running, mapping to the port 5432 of my local PC?
docker ps --format "table {{.Names}}\t{{.ID}}" | grep 'postgres'
The above command will give a list of containers name and Id of Postgres container running via docker. if you have multiple Postgres container, pick one that you want to add in Pg-Admin and use the container id of that Postgres container for next command
docker inspect <container id> | grep -E -A 1 "IPAddress|Ports"
It will give the IPAddress and port of Postgres container you want to connect via PG-Admin. Use that IPAddress and Port to connect via Pg-Admin
Yes, its possible you just have to get Ip address from Docker container, run the next commands to reach that.
docker ps
and then use the ID container to:
docker inspect ID container
Search by IPAddress from Docker config and use it to connect from pgAdmin.

Allowing Docker container to access Postgres running on localhost

I've got a docker container which is supposed to run a (HTTP) service.
This container should be able to connect to PostgresSQL running on the host machine (so it's not part of the container). The container uses the host's network settings:
docker run -e "DBHOST=localhost:5432" -e "DB=somedb" -e "AUTH=user:pw" -i -t --net="host" myservice
I'm using MacOSX, so Docker is running on a Virtualbox VM. I guess I need port forwarding to make this work. I've tried to configure that:
VBoxManage controlvm "default" natpf1 "rule1,tcp,,5432,,5432";
But this doesn't work. If I start up the service, all I get is a connection refused message and the service cannot connect to Postgres.
Postgres is running on port 5432, on the host machine. The "default" is the name of the VM created by Docker installer.
What am I doing wrong? Please help!
I've had success with this using the --add-host flag, which adds an entry into the /etc/hosts in your container. Boot2docker and docker-machine both assign an ip you can use to hit your localhost from inside a container, so you just want to add an entry that points back to this.
With boot2docker, where the default host ip is 192.168.59.3, you can just do docker run --add-host=my_localhost:192.168.59.3 ...
With docker-machine, I think you'll need to lookup your localhost's mapped ip in Virtualbox, and then you can do the same: docker run --add-host=my_localhost:[localhost_mapped_ip_from_docker] ...
Try setting that up and then trying to connect to your Postgres instance through my_localhost. Make sure you correctly set access and accepted inbound ip permissions in Postgres as well, as if it's not listening on the container's ip or 0.0.0.0, it won't work no matter what.