dokku / dokku-mariadb

a mariadb plugin for dokku
MIT License
75 stars 26 forks source link

How to connect with client via ssh tunnel? #36

Closed terion-name closed 8 years ago

terion-name commented 8 years ago

I try to connect to a db with sequel pro - can't figure out how. Is it possible?

josegonzalez commented 8 years ago

What problem are you having exactly?

terion-name commented 8 years ago

I just can't understand how to connect) There is nothing about this in readme and my guesses didn't lead to result. I make an ssh tunnel to host machine, then mysql credentials - ip 172.17.0.1, and... and then not clear. It doesn't accept connections like this at all. Also every service username is similar — mariadb, so not very clear how to access certain db.

josegonzalez commented 8 years ago

Once you have your ssh tunnel set in sequel pro, your mysql credentials can be seen from the following command:

dokku mariadb:info MY_SERVICE

The username is the same everywhere on purpose - this is just to simplify our own tracking of the username - though the password changes on a mariadb service basis.

You can also use the mariadb:expose command to expose the internal port to the outside world, thereby avoiding the need for the ssh tunnel. Once you are done, you can turn it off by using mariadb:unexpose. Both should be documented in the readme.

Does that help?

terion-name commented 8 years ago

I've tried first approach (it seemed obvious), but mariadb:info gives a DSN string:

# dokku mariadb:info service-name
       DSN: mysql://mariadb:passwor@dokku-mariadb-service-name:3306/service-name

And provided host (dokku-mariadb-service-name) is not resolvig from the host machine, only internally from linked container.

Exposing a port to outer world is a bad approach, I think...

josegonzalez commented 8 years ago

Interesting, I guess that's the docker host thing, and is only enabled when you link to a container. That was a change introduced by @Flink.

The dsn can be split into parts obviously, and should contain most of the info for connecting to it.

Can you do the following:

docker ps -a | grep SERVICE_NAME

# on docker 1.9
docker inspect --format '{{ .NetworkSettings.IPAddress }}'  CONTAINER_ID_FROM_THE_ABOVE_GREP

# on lower versions of docker
docker inspect  --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' CONTAINER_ID_FROM_THE_ABOVE_GREP

That should spit out the ip address of the container.

We should totally document this though.

terion-name commented 8 years ago

Yes, manually getting the IP of running container and connecting to it gives access to DB. But there is a problem with this: Docker gives new IP for container on every start. So after a container restart the saved connection will fail and it will be needed to search for proper IP again.

Can mariadb service populate it's hostnames to the host machine and repopulate them on every start so that DBs would be accessible from host by hostname? This is quite important feature I suppose

josegonzalez commented 8 years ago

It probably could, that sounds like a good idea. One thing you'd have to take care of is server reboot, which is a hairy situation. Maybe we could add another stanza to the info command that would output the current internal ip instead?

terion-name commented 8 years ago

add another stanza to the info command that would output the current internal ip

Well this will certainly make such connections easier. But if you work with db via client often, repeating changing the ip in stored connection will be a headache... DB-service or host restart is not a frequent case, but it happens (as a real-world example that I've had — a memory leak during deploy that degradated the entire host and only reboot helped)

One thing you'd have to take care of is server reboot, which is a hairy situation

Why hairy? If db-service will populate it's hostnames on every start (of the service) - this situation will be handled by itself. After server reboot service will start and repopulate hostnames. I'm not a specialist in Docker so I don't know, maybe there are some problems with this, but as I can imagine - this looks like a viable concept

josegonzalez commented 8 years ago

Docker containers don't have "hooks" that they run on boot, and you can't reach out of the container to do something on the host. The official plugins are thin layers around running docker run/build, not services that start on boot.

We'd need to handle this via an upstart/systemd command, and that's not guaranteed to work if we move to installing dokku within a dockerfile.

I understand how this is an annoying thing for you, but there are other concerns that make this... "difficult" to do properly.

What happens if you start/stop the container outside of this plugin, directly via docker? Thats a case we'd have to think about, and would also break your workflow, but something we couldn't really handle, even via upstart/systemd.

terion-name commented 8 years ago

Why not to use docker events? https://docs.docker.com/engine/reference/commandline/events/ Listen to the start event and run hostnames population. There are routing sytems for docker that work on this events - they update host nginx on containers start

josegonzalez commented 8 years ago

Right now we don't have a daemon for any of this stuff - which simplifies a lot of stuff - and we'd need one to "listen" to events.

Yes, I agree that this feature would be nice, but it's not necessarily easy to do. Even if you did have a daemon, you'd need to ensure that it starts before the docker daemon starts, so that when it listens to events, it listens to the event that started the dokku mariadb container in the first place. Lots of edge cases to handle here.

terion-name commented 8 years ago

I see. Indeed, without a daemon it's impossible.. Well, it's a pity :( But container IP in info would be useful in any case (I think this is truly for all db-plugins)

terion-name commented 8 years ago

@josegonzalez ubuntu (which is required for docker, as I remember) ships with dnsmasq. What about adding a container resolver into Dokku core that will work with dnsmasq? Some time ago when I was experimenting with docker, I've made an nginx config for dynamic containers resolving: https://gist.github.com/terion-name/816f3e37d5392a810d5a Not perfect but worked. Maybe alike technique can be implemented for local DNS-resolving? And I'm talking about Dokku core because accessing running services is a quite common task, dokku run not always helps

josegonzalez commented 8 years ago

For dokku core, you can access running containers using dokku enter.

If you'd like to PR a dnsmasq solution to this plugin, that would be great :)

terion-name commented 8 years ago

You can't use dokku enter to connect container via third-party client :)

And I'm unfortunately not so competent in system-level to make such PR :(

In any case thank you for your time. And for awesome project itself, of course)

josegonzalez commented 8 years ago

I'm going to close this for the following reasons:

I'll also shortly add a --internal-ip flag to the info commands, which should help workflows that require retrieval of the internal ip for ssh tunnels. That would certainly make it easier to create any external resolvers for enterprising users.

josegonzalez commented 8 years ago

The flag was added in 9f17a3c9442421becbd23b486c28862b42a9a595.