Traefik and PostgreSQL - postgresql

I have server with Docker and open 80 port.
I use Traefik to redirect between containers. And I want to host PostgreSQL database. After start conteiner with this settings:
postgresql:
image: orchardup/postgresql
environment:
- "POSTGRESQL_PASS=***"
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Path:/postgresql/"
But is not work
What am I doing wrong?

Traefik is a layer 7 reverse proxy.
Postgres doesn't use http, and requires a layer 4 proxy.
You need to look at using another product to proxy Postgres connections.

I guess name of your host should be name of the postgres container, not name of the service. I suggest using container_name in your compose to be persistent.

Postgres does have a http protocol, but I think its way easier to just run it outside of Traefik. Keep your backend and frontend inside traefik, and the db outside:
docker pull postgres:latest
docker run -p 5432:5432 postgres

Related

Connect to Hasura Postgres database on DigitalOcean droplet

I've set up Hasura on a DigitalOcean droplet using the instructions here - https://docs.hasura.io/1.0/graphql/manual/guides/deployment/digital-ocean-one-click.html -
How can I connect to the Postgres database? Preferably using something like DBeaver - with host, database, user, password.
I guess the Postgres is running inside a Docker container, but how do you expose it to the outside world?
The docker-compose.yaml used on the Digital Ocean Marketplace does not expose the Postgres database on the host machine.
You can find the file at /etc/hasura/docker-compose.yaml. If your database management tool supports running as a docker container, I recommend adding it's relevant configuration to the docker-compose.yaml and exposing that application to the ouside like how graphql-engine is exposed via Caddy (config in /etc/hasura/Caddyfile.
But if you'd like to connect to postgres from within the machine, add a port mapping to the docker-compose file:
postgres:
image: postgres:10.5
restart: always
volumes:
- db_data:/var/lib/postgresql/data
ports:
- "127.0.0.1:5432:5432"
Now, Postgres will be available at postgres://postgres:#127.0.0.1:5432/postgres
Do set a password if you're exposing it on the host machine.

How to get long hostname of a docker container inside a container?

Our application is behind traefik reverse proxy. We manage many subdomains and we use the watch-file ability of traefik to dynamically setup new subdomains to proxyfy.
So our application generate a traefik .yaml dynamic config file.
The same traefik will manage many instances of the same application.
For that purprose we need to indicate to traefik how to reach our application inside it own network.
We know we can use the simple hostname, the one which is the container name.
But this only work inside the default docker-compose network of the app instance and not the external network shared with traefik.
This one need the long hostname version so we are sure it reach the right application instance.
(<compose_name>_<container_name>_1 or depending docker-compose version (<compose_name>_<container_name>_1_<hash>)
Do you know a way to get the long version of the hostname of a docker-compose container inside another container of the same docker-compose default network ?
For better context, here a simple docker-compose.yaml file
version: "3"
services:
app:
image: app_image
networks:
- app_network
restart: unless-stopped
nginx:
image: nginx
links:
- app
networks:
- app_network
- traefik_traefik
restart: unless-stopped
networks:
traefik_traefik:
external: true
app_network:
driver: bridge
We want, from inside the app container, to get the nginx long hostname version, so we can use it to generate the dynamic configuration for traefik.
Thanks for your help.
We thought to have found a solution. Querying for the FQDN of the short-named hostname give the needed long hostname.
dig +short -x `dig +short nginx`
Return composename_app_1.composename.app_network.
In our python app we can get the same result with
import socket
socket.getfqdn('nginx')

Ambassador API Gateway doesn't pickup services

I'm a new Ambassador user here. I have walked thru the tutorial, in an effort to understand how use ambassador gateway. I am attempting to run this locally via Docker Compose until it's ready for deployment to K8s in production.
My use case is that all http traffic comes in on port 80, and then directed to the appropriate service. Is it considered best practice to have a docker-compose.yaml file in the working directory that refers to services in the /config directory? I ask because this doesn't appear to actually pickup my files (the postgres startup doesn't show in console). And when I run "docker ps" I only show:
CONTAINER ID IMAGE PORTS NAMES
8bc8393ac04c 05a916199684 k8s_statsd_ambassador-8564bfb874-q97l9_default_e775d686-a93c-11e8-9caa-025000000001_0
1c00f2341caf d7cf7cf837f9 k8s_ambassador_ambassador-8564bfb874-q97l9_default_e775d686-a93c-11e8-9caa-025000000001_0
fe20c4819514 05a916199684 k8s_statsd_ambassador-8564bfb874-xzvkl_default_e775ffe6-a93c-11e8-9caa-025000000001_0
ba6415b028ba d7cf7cf837f9 k8s_ambassador_ambassador-8564bfb874-xzvkl_default_e775ffe6-a93c-11e8-9caa-025000000001_0
9df07dc5083d 05a916199684 k8s_statsd_ambassador-8564bfb874-w5vsq_default_e773ed53-a93c-11e8-9caa-025000000001_0
682e1f9902a0 d7cf7cf837f9 k8s_ambassador_ambassador-8564bfb874-w5vsq_default_e773ed53-a93c-11e8-9caa-025000000001_0
bb6d2f749491 quay.io/datawire/ambassador:0.40.2 0.0.0.0:80->80/tcp apigateway_ambassador_1
I have a docker-compose.yaml:
version: '3.1'
# Define the services/containers to be run
services:
ambassador:
image: quay.io/datawire/ambassador:0.40.2
ports:
- 80:80
volumes:
# mount a volume where we can inject configuration files
- ./config:/ambassador/config
postgres:
image: my-postgresql
ports:
- '5432:5432'
and in /config/mapping-postgres.yaml:
---
apiVersion: ambassador/v0
kind: Mapping
name: postgres_mapping
rewrite: ""
service: postgres:5432
volumes:
- ../my-postgres:/docker-entrypoint-initdb.d
environment:
- POSTGRES_MULTIPLE_DATABASES=db1, db2, db3
- POSTGRES_USER=<>
- POSTGRES_PASSWORD=<>
volumes and environment are not valid configs for Ambassador Mappings. Ambassador lets you proxy to postgres but the authentication has to be handled by your application.
Having said that, it looks like your Postgres container is not starting. (Perhaps because it needs an initial config). You can check for errors with:
$ docker ps -a | grep postgres
$ docker logs <container-id-from-previous-step>
You can also check a postgres docker compose example here.
Is it considered best practice to have a docker-compose.yaml file in the working directory that refers to services in the /config directory?
It's pretty standard, but you can use any directory you like for this.

Using Docker-compose, how to access the container database via the same port in container and in host

I'm running a docker-compose container for postgresql. The postgresql database in the container is running on the standard port 5432, and I am publishing that port out to port 5444 on the host (since the host's postgresql default port is in use).
I am using the same configuration on the host and in the container (a .env file that provides config settings for cli commands and the app as a whole). Unfortunately, whichever port I choose, one system will lose access. For example, I cannot run:
[k#host]$ pgsql -p 5444 # Connects
in the host and still have work inside the container:
[k#db-container]$ pgsql -p 5444 # Errors in container
The container's postgresql-server is running on 5432:
[k#db-container]$ pgsql -p 5432 # Connects successfully in container
and the ports are published via the docker-compose.yml via:
- ports:
- "5444:5432"
So currently I don't know how to configure the same port everywhere simply via the docker-compose.yml! expose command exposes the port but does not allow remapping, ports forwards host<-->container, but does not remap the internal port. I have thought of remapping the postgresql default port inside the postgresql container configuration, but fully reconfiguring postgresql seems non-trivial to do via docker-compose on every docker-compose up.
How can I remap the ports inside the container so that I can use port 5444 everywhere, in the host & container?
The standard PostgreSQL client library supports several environment variables that tell it where the server is. In the same way that you can configure the host using $PGHOST, you can configure the port using $PGPORT.
In a Docker Compose context, it should be straightforward to set these:
version: '3'
services:
postgres:
image: postgres:11
ports: ['5444:5432']
volumes: ['./postgres:/var/lib/postgresql/data']
myapp:
build: .
ports: ['8888:8888']
env:
PGHOST: postgres
# default PGPORT=5432 will work fine
Similarly, if you're running the application in a development environment on the host, you can set
PGHOST=localhost PGPORT=5444 ./myapp
You can't use the same port on the host.
Nothing prevents you to run multiple instances if they has different IP-addresses.
psql -p 5444
Defaults to psql --host=127.0.0.1 -p 5444. If you want several instances - obviously you must make them different in some way.

How to connect Postgresql Docker Container with another Docker Container

I want to connect mysoft docker container to postgresql docker container.
But i have some errors:
ERROR: for mysoft_db_1 Cannot start service db: driver failed programming external connectivity on endpoint mysoft_db_1 (XXX):
Error starting userland proxy: listen tcp 0.0.0.0:5432: bind: address already in use
ERROR: for db Cannot start service db: driver failed programming external connectivity on endpoint mysoft_db_1 (XXX):
Error starting userland proxy: listen tcp 0.0.0.0:5432: bind: address already in use
here is my docker-compose.yml
version: '2'
services:
mysoft:
image: mysoft/mysoft:1.2.3
ports:
- "80:8080"
environment:
- DATABASE_URL=postgres://mysoft:PASSWORD#db/mysoft?sslmode=disable
db:
image: postgresql
environment:
- POSTGRES_USER=mysoft
- POSTGRES_PASSWORD=PASSWORD
- POSTGRES_DB=mysoft
ports:
- 5432:5432
I want use another, already running docker pg server to connect new soft, also one pg docker server, for more projects
Is it possible?
You should add links to the definition of mysoft service in docker-compose.yml. Then your db service will be accessible from mysoft container.
After that your service definition will look like this.
mysoft:
image: mysoft/mysoft:1.2.3
ports:
- "80:8080"
environment:
- DATABASE_URL=postgres://mysoft:PASSWORD#db/mysoft?sslmode=disable
links:
- db
Now about error of binding. Probably, you receive it, because you have a local postgresql running on port 5432 or you already have a running docker container with 5432 port mapped to local machine.
ports:
- 5432:5432
It is used for mapping ports to your local machine. And if you don't need to access container's db from it, just remove it.
I want use another, already running docker pg server to connect new
soft, also one pg docker server, for more projects Is it possible?
Yes, it's possible. Use external_links.
If you choose this option:
Remove the db service and links in mysoft service definition from your docker-compose.yml
Add external_links with correct container name to mysoft service definition.
Update host and port in DATABASE_URL according to the container name and postgresql port in it.
You might want to check of you already have a local postgres running on port 5432? If you do you can not do the ports 5432:5432 but have to expose the inner port to an other outer port e.g. 5555:5432
at least if you are using native docker (running on localhost)...