unsupported port number: 0 - docker-compose

If we specify single port in dockerfile or docker-compose file like below
sshd:
build: ./backend/mock/sshd
volumes:
- ./docker/sftp_upload_dir:/root/upload_dir
ports:
- '22'. #<----------
and use the docker-compose file with nerdctl using command
nerdctl compose up
then nerdctl command will exit with following error
FATA[0000] unsupported port number: 0

As per docker documentation https://docs.docker.com/compose/compose-file/compose-file-v3/#ports
There are three options:
Specify both ports (HOST:CONTAINER)
Specify just the container port (an ephemeral host port is chosen for the host port).
Thus 0 is chosen as the host port which creates error, so solution is to explicitly specify host port as below
sshd:
build: ./backend/mock/sshd
volumes:
- ./docker/sftp_upload_dir:/root/upload_dir
ports:
- '22:22' #<<<<---------
Note that I have explicitly added 22: before 22 in the last line to make it work with nerdctl. It works by default with docker-compose up.

Related

Send a azure queue message in a docker container to a queue triggered function in another docker container

It is really difficult to explain. I am not expert in docker. I will try it.
I have 3 components:
1 container with Azurite
1 container with a queue function
Microsoft Azure Storage Explorer in the host.
I am using docker-compose.yml to reach my goal.
After two day I could configure correctly the Azurite container to communicate correctly with the Storage Explorer in the host. Here the portion of code in my composer file:
services:
storage:
image: mcr.microsoft.com/azure-storage/azurite
container_name: storage
restart: always
ports:
- 7777:10000
- 8888:10001
- 9999:10002
environment:
- "AZURITE_ACCOUNTS=devnotificationsstorage:Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
command: "azurite -l /workspace -d /workspace/debug.log --blobPort 10000 --blobHost 0.0.0.0 --queuePort 10001 --queueHost 0.0.0.0 --tablePort 10002 --tableHost 0.0.0.0"
volumes:
- "./datadir/azurite:/workspace"
I mapped the port 7777 in my host with the port 10000 of the container with Azurite. I cannot use the port 10000 in my host because it is already used by Storage Explorer with another local container. However I find strange that everything works setting port 8888 on the host. Here a screen of Sotrage Explorer:
Surely I haven'y understood something.
In any case, now I can correctly insert the message in the containerized queue from the Storage Explorer.
But when I insert the message in the queue I expect to receive the message on the queue container. I let you see the whole compose file:
version: '3.4'
services:
storage:
image: mcr.microsoft.com/azure-storage/azurite
container_name: storage
restart: always
ports:
- 7777:10000
- 8888:10001
- 9999:10002
environment:
- "AZURITE_ACCOUNTS=devnotificationsstorage:Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
command: "azurite -l /workspace -d /workspace/debug.log --blobPort 10000 --blobHost 0.0.0.0 --queuePort 10001 --queueHost 0.0.0.0 --tablePort 10002 --tableHost 0.0.0.0"
volumes:
- "./datadir/azurite:/workspace"
networks:
- shared_network
xxx.notifications.azurefunction.emails:
image: ${DOCKER_REGISTRY-}xxxgonotificationsazurefunctionemails
container_name: notifications_email
build:
context: .
dockerfile: XXX.Notifications.AzureFunction.Emails/Dockerfile
depends_on:
- storage
networks:
- shared_network
networks:
shared_network:
And here the localhost.settings.json file:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"StorageConnectionString": "UseDevelopmentStorage=true"
}
}
Please, note that if I send a message from local queue on port 10000 (the non-dockerized queue), I receive the message on the queue triggered function.
But if I send the queue from the dockerized queue nothing happend.
I also thought that perhpas, the connection string is wrong. So I changed the StorageConnectionString with the value I see in the Storage explorer. That is the new localhost.settings.json file:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"StorageConnectionString": "AccountName=devnotificationsstorage;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:7777/devnotificationsstorage;QueueEndpoint=http://127.0.0.1:8888/devnotificationsstorage;TableEndpoint=http://127.0.0.1:9999/devnotificationsstorage;"
}
}
In this case, when I write a message on the dockerized queue (and just when I write the message on the queue), I get this error:
Azure.Core: Connection refused (127.0.0.1:8888). System.Net.Http: Connection refused (127.0.0.1:8888). System.Net.Sockets: Connection refused.
How do I have to configure my containers?
Thank you.
This connection string is wrong:
"StorageConnectionString": "AccountName=devnotificationsstorage;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:7777/devnotificationsstorage;QueueEndpoint=http://127.0.0.1:8888/devnotificationsstorage;TableEndpoint=http://127.0.0.1:9999/devnotificationsstorage;"
I must replace the host 127.0.0.1 and the ports with the ones I defined for my container.
First of all, the host. We can use the same name we used to define the container in the compose. In my case storage (second line):
services:
storage: <-- This is thehost name
image: mcr.microsoft.com/azure-storage/azurite
container_name: storage
restart: always
ports:
- 7777:10000
- 8888:10001
- 9999:10002
environment:
- "AZURITE_ACCOUNTS=devnotificationsstorage:Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
command: "azurite -l /workspace -d /workspace/debug.log --blobPort 10000 --blobHost 0.0.0.0 --queuePort 10001 --queueHost 0.0.0.0 --tablePort 10002 --tableHost 0.0.0.0"
volumes:
- "./datadir/azurite:/workspace"
networks:
- shared_network
Second I mapped the ports of my service in this way:
ports:
- 7777:10000
- 8888:10001
- 9999:10002
That means host:container. So every Http message sent on port 8888 of the host (in the context of Docker) will be received on port 10001 in my container.
So if I have to check if there are messages in the queue of my container I must change the connection string in this way:
"StorageConnectionString": "AccountName=devnotificationsstorage;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://storage:10000/devnotificationsstorage;QueueEndpoint=http://storage:10001/devnotificationsstorage;TableEndpoint=http://storage:10002/devnotificationsstorage;"

Docker Compose: Increment environment variable

I am locally deploying a full-stack app via Docker Compose and would like to derive the backend and frontend ports from a single environment variable $PORT. For example, if $PORT = 3000, then the backend port should be 3000 and the frontend port should be 3001. And if $PORT = 4000, then the backend port should be 4000 and the frontend port should be 4001.
For this, I would like to do something like this in my docker-compose.yml:
version: "3"
services:
backend:
...
ports:
- "${PORT}:3000"
frontend:
...
ports:
- "$((PORT + 1)):4200"
This fails with ERROR: Invalid interpolation format for "environment" option in service "frontend". Is there a way to achieve this in Docker Compose?
Compose only supports a limited set of environment variable substitutions: ${VARIABLE}, ${VARIABLE:-default}, ${VARIABLE:?error message}, and the latter two options without colons. You cannot do other substitutions, computation, or shell callouts in Compose.
For this particular case, you can let Docker pick the host port number for you. This is less predictable than the scheme you describe, but it doesn't require any special setup. Instead of using two numbers in ports: just specify the container port number
version: '3.8'
services:
backend:
ports:
- '3000'
frontend:
ports:
- '4200'
To find the corresponding host port number, you need to run docker-compose port
docker-compose port frontend 4200
I don't think it's possible to do that. But why don't you set before in your environment those ports variables? For example run before everything:
export PORT=3000 #or whatever number you want
export PORT_INC=$(($PORT+1))
And then you use like this:
ports:
- "$PORT_INC:4200"

Can't access Postgres running with docker-compose from WebStorm (JetBrains)

I have the following docker-compose.yml:
version: '3.7'
services:
postgres-service:
image: postgres:12.3
env_file:
- .env
ports:
- '5432:5432'
volumes:
- /postgres/data/
This is my .env:
POSTGRES_USER=app_postgres_user
POSTGRES_PASSWORD=foobar
POSTGRES_DB=app_database
I know postgres-service is working because I connect manually to the service and it works with following commands:
docker-compose run postgres-service bash # connect to postgres-service
psql --host=postgres-service --username=app_postgres_user --dbname=app_database
But when I try to connect from within "Webstorm > Database" I get this error:
The connection attempt failed.
java.net.UnknownHostException: postgres-service.
Screenshot:
If Webstorm is running on the same host as the container, replace postgres-service with localhost.
If it is running elsewhere, replace postgres-service with the IP address of the docker host machine where the container resides.
I used your docker-compose and connected with DBeaver with these settings:
Your postgres container resides in a virtual network (e.g.: 172.17.0.0/16). By default there is no route from your machine to that network.
When you use
ports:
- 'src:dest'
...in your docker-compose.yml file, a DNAT rule is created from your host:src to the container:dest and that's the reason of using localhost:src or the IP address of the docker host.

Connecting to Postgresql in a docker container with a GUI

I just started learning docker and I decided to create a postgresql container, and I want to use it as my database.
But the thing is, every time I tried to connect to my postgresql container with my Gui (PostBird), I get an error that says "Connection terminated unexpectedly".
My config file:
postgres:
image: postgres:alpine
restart: always
ports:
- '3000:3000'
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: root
POSTGRES_DB: adonisvue
volumes:
- ./init:/docker-entrypoint-initdb.d/
The command I used:
sudo docker-compose up
When my postgres container is running it says "database system is ready to accept connections" but I can't connect with my gui, even using connect url.
I had to change my port to 3000 because docker says that the port 5432 is already in use, but I don't have any container running in it. Is it because of psql?
Sorry, I'm really new to this and I just have a bunch of questions xD
I had to change my port to 3000 because docker says that the port 5432 is already in use, but I don't have any container running in it. Is it because of psql?
Yes, this is most probably because you have an other postgresql using this port on the local machine. Meanwhile, the postgres instance running inside your container is still using port 5432 (unless you also changed the port inside your container but I'm 99.9% sure you didn't). So the following port setting is wrong.
ports:
- '3000:3000'
This is mapping port 3000 for any IP configured on your host to port 3000 of your container... with no service running on that one. Try:
ports:
- '3000:5432'
You can then connect to postgres on port 3000 on your local machine which will forward packets to port 5432 inside the container.

Map port of container without exposing to host in docker-compose

I have
services:
api:
build: .
ports:
- "8080:8080"
superservice:
image: superservice
ports:
- # ?
superservice is very super, but I simply pulled it from the Docker hub and its port cannot be configured when creating a container. The default port is 8080. But that is already in use. How do I change it to 8081? I do NOT want it to be accessible from the host, that is why - "8081:8080" is not desirable.
In this case you would have to change the port superservice is running on by either changing its configuration, or if possible, change the command or entrypoint it runs on start and pass the new port as an argument.
Although, if superservice does not have to be reachable from the host then you should have no problem referencing it as http://superservice:8080 from inside the api container.