how does the Entrypoint command works here - mongodb

How does the ENTRYPOINT command works given in the below docker compose file. I have found the docker compose file in replica Set mongo docker-compose. "usr/bin/mongod" is the first command given in the ENTRYPOINT, my Question is whether the usr/bin/mongod will start the local mongo and run it has docker container or it will pull the mongo image from repository and run it as container if so why we are using "usr/bin/mongod".
version: "3"
services:
mongo-1:
hostname: mongo-1
container_name: mongo-1
image: mongo:4.0
ports:
- "127.0.0.1:28000:28000"
volumes:
- ./mongo-1/data:/data/db
restart: always
entrypoint: [ "/usr/bin/mongod", "--port", "28000", "--bind_ip_all", "--replSet", "rs1" ]
using this compose file i am able to connect mongoDB running in the port 28000 from host machine but when i replace the ENTRYPOINT with CMD in the compose file i am not able to connect the mongoDB from host machine.

You are using the image "mongo:4.0" which has its own ENTRYPOINT and CMD defined. When you redeclare any of them in your docker-compose.yml then you are overwriting the original ones.
ENTRYPOINT is the main command and CMD are only parameters sent to the main command. For this reason it works for you when you define ENTRYPOINT with a valid command. If you change it to CMD then when is run is the original ENTRYPOINT ("docker-entrypoint.sh") and the new command.
Your entrypoint uses the binary from inside your container that is based on the specified image.
For reference you can see the Dockerfile of the official image: https://github.com/docker-library/mongo/blob/40056ae591c1caca88ffbec2a426e4da07e02d57/4.0/Dockerfile
The ENTRYPOINT and CMD are defined at the end.

Related

Docker with postgresql in flask web application (part 2)

I am building a Flask application in Python. I'm using SQLAlchemy to connect to PostgreSQL.
In the flask application, I'm using this to connect SQLAlchemy to PostgreSQL
engine = create_engine('postgresql://postgres:[mypassword]#db:5432/employee-manager-db')
And this is my docker-compose.yml
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
ports:
- 8000:8000
volumes:
- .:/app
links:
- db:db
depends_on:
- pgadmin
db:
image: postgres:14.5
restart: always
volumes:
- .dbdata:/var/lib/postgresql
hostname: postgres
environment:
POSTGRES_PASSWORD: [mypassword]
POSTGRES_DB: employee-manager-db
pgadmin:
image: 'dpage/pgadmin4'
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: [myemail]
PGADMIN_DEFAULT_PASSWORD: [mypassword]
ports:
- "5050:80"
depends_on:
- db
I can do "docker build -t employee-manager ." to build the image. However, when I do "docker run -p 5000:5000 employee-manager" to run the image, I get an error saying
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Try again
Does anybody know how to fix this? Thank you so much for your help
Your containers are on different networks and that is why they don't see each other.
When you run docker-compose up, docker-compose creates a separate network and puts all the services defined inside docker-compose.yml on that network. You can see that with docker network ls.
When you run a container with docker run, it is attached to the default bridge network, which is isolated from other networks.
There are several ways to fix this, but this one will serve you in many other scenarios:
Run docker container ls and identify the name or ID of the db container that was started with docker-compose
Then run your container with:
# ID_or_name from the previous point
docker run -p 5000:5000 --network container:<ID_or_name> employee-manager
This attached the new container to the same network as your database container.
Other ways include creating a network manually and defining that network as default in the docker-compose.yml. Then you can use docker run --network <network_name> ... to attach other containers to that network.
docker run doesn't read any of the information in the docker-compose.yml file, and it doesn't see things like the Docker network that Compose automatically creates.
In your case you already have the service fully-defined in the docker-compose.yml file, so you can use Compose commands to build and restart it
docker-compose build
docker-compose up -d # will delete and recreate changed containers
(If the name of the image is important to you – maybe you're pushing to a registry – you can specify image: alongside build:. links: are obsolete and you should remove them. I'd also avoid replacing the image's content with volumes:, since this misses any setup or modification that's done in the Dockerfile and it means you're running untested code if you ever deploy the image without the mount.)

How to communicate multiple containers with each other in Docker?

I'm trying to containerize my application. I use mongodb and 2 more micro services.
As you can see in the docker compose file below, I have some problems.
My requirements:
main_image needs to connect to MongoDB.
gui_image needs to connect to MongoDB.
gui_image needs to show its GUI on port 8080 (Can use another port as well)
gui_image has to read and write to a file inside my computer.
MongoDB has to access a volume inside my computer.
main_image needs access to the internet.
Here is my questions:
1- Does exposing ports in docker file and docker-compose the same thing?
2- How do I mount a volume to mongodb as best practice?
3- How to accomplish the requirements above with the diagram below in docker-compose?
Here is my docker-compose file:
version: "3"
services:
mongo:
image: mongo:latest
ports:
- 27017:27017
main_image:
build:
context: .
dockerfile: .\my_project\dockerfile
depends_on:
- mongo
gui_image:
build:
context: .
dockerfile: .\my_gui\dockerfile
ports:
- 8080:8080
- 27017:27017
depends_on:
- mongo
Here is my dockerfile under my_gui directory:
FROM continuumio/miniconda3
WORKDIR /app
COPY . .
RUN pip install dash
EXPOSE 8080
EXPOSE 27017
ENTRYPOINT [ "python","gui_script.py"]
And lastly, here is my dockerfile under my_project directory:
FROM continuumio/miniconda3
WORKDIR /app
COPY . .
EXPOSE 27017
ENTRYPOINT [ "python","main_script.py"]
1.The EXPOSE instruction in Dockerfile informs Docker that the container listens on the specified network ports at runtime(like when using docker run -p command).
However using ports in compose is a dynamic way of specifying these ports. So images like nginx or apache which are always supposed to run on port 80 inside the container will use EXPOSE in Dockerfile itself.
While an image which has dynamic port which may be controlled using an environment variable will then use expose in docker run or compose file.
some_webapi:
environment:
- ASPNETCORE_URLS=http://*:80
build:
context: .
dockerfile: ./Dockerfile
2.As documented on the docker hub page for mongo image (https://hub.docker.com/_/mongo/) you can use
volumes:
- '/path/to/your/pc/folder:/path/inside/docker'
3.And for the last question you might wanna use Networking in Compose.
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
Services can join networks like this
gui_image:
build:
context: .
dockerfile: .\my_gui\dockerfile
ports:
- 8080:8080
- 27017:27017
depends_on:
- mongo
networks:
- gui
And also you have to define all the networks used by services in global scope of compose file
version: '3'
services:
networks:
gui:
After that containers will be able to see each other even by their container_name which you can define in services
mongo:
image: mongo:latest
ports:
- 27017:27017
container_name: gui_mogno
then you will be able to connect to mongo with a connection string like this mongodb://gui_mogno:27017/
You can get more information about networking here

Docker-compose: Container is not running

I created the following Dockerfile:
FROM postgres
COPY short_codes.csv /var/lib/postgresql/data/short_codes.txt
ENTRYPOINT ["docker-entrypoint.sh"]
And docker-compose:
version: '3'
services:
codes:
container_name: short_codes
build:
context: codes_store
image: andrey1981spb/short_codes
ports:
- 5432:5432
I up docker-compose successfully. But when I try to enter in container, I receive:
"Container ... is not running"
I suppose, I have to prescribe some run-command in Dockerfile. But what is this command?
Your container is probably not running because you haven't copied your docker-entrypoint.sh script anywhere to your container.
You also don't need to supply a run command, since entrypoint is going to run a command on start up, and docker-compose up auto runs your container.

docker-compose - Application can't communicate with postgres container

I have a scrapy application which I'm trying to containerized it. Basically, this is my docker-compose.yml file:
version: '3'
services:
scrapper:
container_name: scrapper
build: .
ports:
- 80:80
depends_on:
- db
links:
- db
db:
volumes:
- ./scrapper/sql:/docker-entrypoint-initdb.d
image: postgres
container_name: postgres
restart: always
ports:
- 5432:5432
And this is my Dockerfile:
FROM python:3
WORKDIR /usr/app
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .
But when I try to execute my application using the following command: docker run -it scrapper_scrapper scrapy crawl angeloni, I'm receiving this message:
File "/usr/local/lib/python3.7/site-packages/scrapy/crawler.py", line 88, in crawl
yield self.engine.open_spider(self.spider, start_requests)
psycopg2.OperationalError: could not translate host name "db" to address: Name or service not known
Why this is happening? When I execute docker-compose ps command, it shows:
Name Command State Ports
--------------------------------------------------------------------------
postgres docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
scrapper python3 Exit 0
When running docker-compose up to start db, that container will run under its network that is also created by docker compose. As such, running docker run ... will not be able to connect to that instance, since it is not running on the same network. But you can specify it with:
docker run --network $network_name
To get the docker networks available, you can run:
docker networks ls
I think you have to explicitly define a user network and put your containers on it:
https://docs.docker.com/network/bridge/
Under the section:
User-defined bridges provide automatic DNS resolution between containers.

Docker compose doesn't connect two containers

I have two containers that don't connect to each other:
1. I made an image postgres that get data from dump.sql
here is Dockerfile:
FROM postgres:11.1-alpine
COPY restore_db.sh /docker-entrypoint-initdb.d/
COPY db.sql /backup/
ENV PGDATA=/data
Then I created container with docker run --name db -p 5432:5432 db
4.I made a image with app. Dockerfile for app look like:
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY build/libs/ /app/
# Make port 80 available to the world outside this container
EXPOSE 8085
# Define environment variable
ENV NAME app
# Run app when the container launches
CMD java -jar /app/olympic-0.0.1-SNAPSHOT.jar
I made a container with run.
then i use docker-compose up with file that looks like:
version: '3'
services:
db:
image: db-data
container_name: postgres
ports:
- 5432:5432
volumes:
- ./pg_data:/data
environment:
POSTGRES_DB: innovation
POSTGRES_USER: postgres
PGDATA: /data
restart: always
web:
image: app
container_name: roc
environment:
POSTGRES_HOST: db
ports:
- 8085:8085
restart: always
links:
- db
```
here is property file:
```
spring.datasource.url=jdbc:postgresql://db:5432/innovation
spring.datasource.username=postgres
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.root=INFO
spring.output.ansi.enabled=ALWAYS
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.liquibase.change-log=classpath:liqubase/db.changelog-master.xml
spring.liquibase.url=jdbc:postgresql://db:5432/innovation
spring.liquibase.user=postgres
```
Thet are not able to be connected.
I always got an error:
org.postgresql.util.PSQLException: Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
First of all I dont see any network defined in your Docker files for both containers
So I assume ther are on $project-default network.
docker network inspect $project-default
will give you list of all containers using default network.
Now coming to the containers, Let's assume DB is Container 1 (10.1.1.2) and Spring App is Container 2 (10.1.1.3).
You can get running containers IP by running
docker inspect containerName
You are exposing 5432 and 8085 port for db and Spring respectively
Inside Spring app container property file spring.datasource.url
localhost:5432 or db:5432 (not sure what is db hostname mapped to) is not accessable as DB is in different container.
You can try 10.1.1.2:5432
When you are exposing 5432 and 8085 port from Host machine you can access these port.
eg in Docker for Windows it would be 192.168.99.100:5432
but same cant be access from inside container.
spring.datasource.url=jdbc:postgresql://10.1.1.2:5432/innov should work assuming DB is up and running