nickjj / docker-rails-example

A production ready example Rails app that's using Docker and Docker Compose.
MIT License
975 stars 197 forks source link

Add Postgres port forwarding #42

Open chapmandu opened 2 years ago

chapmandu commented 2 years ago

Add Postgres port forwarding to be able to connect to the development db using a GUI.

eg:

.env

export POSTGRES_PORT_FORWARD=54320

docker-compose.yml

services:
  postgres:
    ...
    ports:
      - "${POSTGRES_PORT_FORWARD:-54320}:${POSTGRES_PORT:-5432}"
nickjj commented 2 years ago

Hi,

Out of the box if you ran this project on most cloud providers with your change it would allow anyone on the internet to make a connection to your postgres instance and brute force your password unless you explicitly put a cloud firewall in front of your app to block that port.

If you wanted to connect to postgres using an external tool you could follow the same pattern this project uses for the web app and publish it over 127.0.0.1:5432:5432 so it only allows connections from localhost. I didn't include this by default because I figured if you wanted to allow any access to postgres outside of Docker, you can opt into doing it for your project.

I wrote about this topic in more detail in my DockerCon talk listed at the top of this readme btw https://nickjanetakis.com/blog/best-practices-around-production-ready-web-apps-with-docker-compose#publishing-ports-more-securely-in-production. It's in reference to the web app but it applies to postgres too.

chapmandu commented 2 years ago

Thanks! A good solution.. and I neglected to say thanks for this great project!

johnpitchko commented 2 years ago

For folks newer to Docker, perhaps a brief comment explaining the possible need to include a port mapping? Always want to make sure more novice users don't run into the same simple frustrations that I have 😆

nickjj commented 2 years ago

It's an idea. Were you thinking as a comment in the compose file or readme file?

johnpitchko commented 2 years ago

I think for stuff like this, the compose file would be the best place as it is right where the change may need to be made. I can do a PR if you like.

nickjj commented 2 years ago

Yeah I'm on the fence for enabling it by default for 127.0.0.1:5432:5432 with a new env var. This way it works out of the box locally but still protects anyone from the outside world connecting, and you can adjust the env var if you need to.

johnpitchko commented 2 years ago

@nickjj I think those are fair concerns; so maybe add it but commented out with a note explaining the risk or other considerations? That way, people could better figure it out for themselves without leaving open a security risk by default.

Oh I just realized that I may be experiencing this issue because I'm running Postgres and Redis in containers, but Rails from my console (and not from a container). That would explain why the port mapping is needed in my circumstance.

"The more I know....."

nickjj commented 2 years ago

Oh I just realized that I may be experiencing this issue because I'm running Postgres and Redis in containers, but Rails from my console (and not from a container). That would explain why the port mapping is needed in my circumstance.

Yeah normally if everything is running in Docker you don't need port forwarding, but you would need port forwarding if you wanted to make something like Postgres available to pgadmin or some other app running on your Docker host outside of the same Docker network that this project's apps are within.

lesterzone commented 10 months ago

First: Great project!

I would say it is common to have a client connected to Postgres in development

nickjj commented 10 months ago

Thanks. The quickest way to handle that now is to add ports: ["127.0.0.1:5432:5432"] to the postgres service. Then you'll be able to connect with any 3rd party client you want.

If you're ok with using psql you can run ./run psql to connect without needing to add that line too.