I am trying to learn how to containerize my flask api with docker. I am very new to docker, but from my understanding, I was able to build/update it. When I navigate to my route I get site can't be reached.
Any help would be greatly appreciated. Thank you.
Here is my yml file:
version: "3.6"
services:
users:
build:
context: ./services/users
dockerfile: Dockerfile-dev
volumes:
- "./services/users:/usr/src/app"
ports:
- 5001:5000
environment:
- FLASK_APP=project/__init__.py
- FLASK_ENV=development
- APP_SETTINGS=project.config.DevelopmentConfig
here is my dockerfile:
FROM python:3.6.5-alpine
WORKDIR /usr/src/app
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
COPY . /usr/src/app
CMD python manage.py -h 0.0.0.0
and here is my powershell command and output:
docker-compose -f docker-compose-dev.yml up -d --build
upon further diagnosis I found this from the ps command
I however cannot find in docker documentation what state of exit 2 means. Unless that is bash for misuse of shell builtin: http://www.tldp.org/LDP/abs/html/exitcodes.html. In that case I really don't know my problem and would appreciate any help!
Edit 3:
upon reading some github threads removing the -d flag from my command showed more information but it is still cryptic if anyone has an explanation for it:
I guess new flask versions doesn't support -h anymore, try with --host -
Change CMD statement in Dockerfile to -
CMD python manage.py runserver --host 0.0.0.0
Ref - https://flask-script.readthedocs.io/en/latest/
Related
I am using Ubuntu and tried to run Django with Docker.
When I give docker-compose up command it give below output
Starting aug6_web_1 ... done
Attaching to aug6_web_1
web_1 | Watching for file changes with StatReloader
and does not print anything else ... for almost 20 min now.
Here is my docker-compose.yml:
version: '3'
services:
web:
build:
context: ./
command: python manage.py runserver 127.0.0.0:8000
volumes:
- .:/AUG6
ports:
- '8000:8000'
And my Dockerfile:
FROM python:3
ENV PYTHONBUFFERED 1
RUN mkdir /AUG6
WORKDIR /AUG6
COPY /requirements.txt /AUG6/
RUN pip install -r requirements.txt
COPY . /AUG6/
Very first day of learning Docker, excuse if any mistakes
docker-compose up will not terminate as long as the containers are running.
If you want it to start the containers and then terminate, use docker-compose up -d.
Check the docker-compose manual.
EDIT 1:
I just spotted a mistake in your runserver command:
You have python manage.py runserver 127.0.0.0:8000 but it should be python manage.py runserver 127.0.0.1:8000.
You can remove the IP:PORT completely, as you use the defaults. Check the docs.
I am able to run my application with the following command:
docker run --rm -p 4000:4000 myapp:latest python3.8 -m pipenv run flask run -h 0.0.0.0
I am trying to write a docker-compose file so that I can bringup the app using
docker-compose up. This is not working. How do "add" the docker run params to the docker-compose file?
version: '3'
services:
web:
build: .
ports:
- "4000:4000"
volumes:
- .:/code
You need to use command to specify this.
version: '3'
services:
web:
build: .
ports:
- '4000: 4000'
image: myapp:latest
command: 'python3.8 -m pipenv run flask run -h 0.0.0.0'
volumes:
- .:/code
You should use CMD in your Dockerfile to specify this. Since you'll want to specify this every time you run a container based on the image, there's no reason to want to specify it manually when you run the image.
CMD python3.8 -m pipenv run flask run -h 0.0.0.0
Within the context of a Docker container, it's typical to install packages into the "system" Python: it's already isolated from the host Python by virtue of being in a Docker container, and the setup to use a virtual environment is a little bit tricky. That gets rid of the need to run pipenv run.
FROM python:3.8
WORKDIR /code
COPY Pipfile Pipfile.lock .
RUN pipenv install --deploy --system
COPY . .
CMD flask run -h 0.0.0.0
Since the /code directory is already in your image, you can actually make your docker-compose.yml shorter by removing the unnecessary bind mount
version: '3'
services:
web:
build: .
ports:
- "4000:4000"
# no volumes:
So I'm trying to set up a docker-compose file, and do some data initialisation in it. However when I do docker-compose up in my terminal (windows one + tried a bash one) I get sh: 1: ./entrypoint: not found despite it showing the file when I add ls to my command.
mssql_1 | data
mssql_1 | entrypoint.sh
mssql_1 | init.sql
mssql_1 | table
My docker-compose file:
version: '2.1'
services:
mssqldata:
image: microsoft/mssql-server-linux:latest
entrypoint: /bin/bash
mssql:
image: microsoft/mssql-server-linux:latest
ports:
- 1433:1433
volumes:
- /var/opt/mssql
- ./sql:/usr/src/app
working_dir: /usr/src/app
command: sh -c 'chmod +x ./entrypoint.sh; ./entrypoint.sh & /opt/mssql/bin/sqlservr;'
environment:
ACCEPT_EULA: Y
SA_PASSWORD: P#55w0rd
volumes_from:
- mssqldata
Folder structure:
docker-compose.yml
sql/
data/
table/
entrypoint.sh
init.sql
In my opinion this should be happening in your dockerfile instead of in your docker-compose.yml file. Generally the idea behind docker-compose is to get a multi container application running and to get the containers in a multi container application to talk to each other. So for example in your context it would perhaps be to get three containers to communicate with other for a asp.net+ MSSQL + IIS container.
In any case what you are trying to achieve you can do in your dockerfile
I'll try write this dockerfile for you as far as possible. Here is the dockerfile:
FROM microsoft/mssql-server-linux:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
EXPOSE 1433
ADD entrypoint.sh /entrypoint.sh
COPY entrypoint.sh /entrypoint.sh
# I suggest you add starting : "/opt/mssql/bin/sqlservr" to the entrypoint.sh script it would simplify things a bit.
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
Here is the docker-compose.yml file that you need:
version: '2'
services:
ms-sql-server-container:
image: mssql-container:latest
# This refers to the docker container created by building our dockerfile with:
# docker build -t mssql-container .
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=P#55w0rd
volumes:
- ./sql:/usr/src/app
# I don't really understand the reason for the second volume that you had if you can kindly explain, then I can edit my answer to accomodate the second volume
# if I think that you need it.
ports:
- 1433:1433
Let me know if this works.
I have set up a docker-compose.yml file that runs a web service along with postgres.
It works nicely when I run it with docker-compose up.
docker-compose.yml:
version: '3'
services:
db:
image: postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
Dockerfile:
FROM python:3
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
CMD ["python", "manage.py", "runserver"]
Is there any way to construct an image out of the services?
I tried it with docker-compose build, but running the created image simply freezes the terminal.
Thanks!
docker-compose is a container orchestration tool, albeit a simple one , and not a bundler of multiple images and preferences into one. In fact, such a thing does not even exists.
What happens when you run docker-compose up is that it effectively runs docker-compose build for those images that need to be built, web in your example, and then effectively replaces the build: . with image: web and executes the configuration as defined by the compose file.
So if you were to run docker-compose build manually and wanted to run the same configuration you have in the compose file manually, you would need to something along the lines of (in order)
run docker-compose build or docker build -t web . to build the web image
run docker run --name db postgres
run docker run --name web -v .:/code -p 8000:8000 web python manage.py runserver 0.0.0.0:8000
I have just started learning Docker, and run into this issue which don't know how to go abound.
My Dockerfile looks like this:
FROM node:7.0.0
WORKDIR /app
COPY app /app
COPY hermes-entry /usr/local/bin
RUN chmod +x /usr/local/bin/hermes-entry
COPY entry.d /entry.d
RUN npm install
RUN npm install -g gulp
RUN npm install gulp
RUN gulp
My docker-compose.yml looks like this:
version: '2'
services:
hermes:
build: .
container_name: hermes
volumes:
- ./app:/app
ports:
- "4000:4000"
entrypoint: /bin/bash
links:
- postgres
depends_on:
- postgres
tty: true
postgres:
image: postgres
container_name: postgres
volumes:
- ~/.docker-volumes/hermes/postgresql/data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
ports:
- "2345:5432"
After starting the containers up with:
docker-compose up -d
I tried running a simple bash cmd:
docker-compose run hermes ls
And I got this error:
/bin/ls cannot execute binary file
Any idea on what I am doing wrong?
The entrypoint to your container is bash. By default bash expects a shell script as its first argument, but /bin/ls is a binary, as the error says. If you want to run /bin/ls you need to use -c /bin/ls as your command. -c tells bash that the rest of the arguments are a command line rather than the path of a script, and the command line happens to be a request to run /bin/ls.
You can't run Gulp and Node at the same time in one container. Containers should always have one process each.
If you just want node to serve files, remove your entrypoint from the hermes service.
You can add another service to run gulp, if you are having it run tests, you'd have to map the same volume and add a command: ["gulp"]
And you'd need to remove RUN gulp from your dockerfile (unless you are using it to build your node files)
then run docker-compose up