I am trying to learn to deploy apps using docker. I have a flask app I am trying to deploy. Each time I run docker-compose up, the output doesn't show any errors but the app won't load in the browser. I make use of flask-sqlalchemy to connect to a mysql database. The contents of my docker-compose file are as follows:
version: "3.7"
services:
db:
image: mysql:5.7
ports:
- "32000:3306"
environment:
MYSQL_HOST: db
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: data_scientist
volumes:
- ./db/route_client.sql:/docker-entrypoint-initdb.d/route_client.sql:ro
app:
build: C:\abdul_files\flask_apps\leaflet\control_search
links:
- db
ports:
- "5001:5000"
depends_on:
- db
The contents of my Dockerfile are as follows:
# Use an official Python runtime as an image
FROM python:2.7.9
# The EXPOSE instruction indicates the ports on which a container
# will listen for connections
# Since Flask apps listen to port 5000 by default, we expose it
EXPOSE 5000
# Sets the working directory for following COPY and CMD instructions
# Notice we haven’t created a directory by this name - this instruction
# creates a directory with this name if it doesn’t exist
WORKDIR /control_search
# Install any needed packages specified in requirements.txt
COPY requirements.txt /control_search
RUN pip install -r requirements.txt
# Run app.py when the container launches
COPY . /control_search
CMD python control_search.py
The contents of my config file where I have my sqlalchemy database uri are as follows:
import os
class Config(object):
SQLALCHEMY_DATABASE_URI = 'mysql://root:data_scientist#db/route_client'
SECRET_KEY = os.urandom(32)
SESSION_TYPE = 'filesystem'
As I said earlier, the docker-compose up command executes without errors but the app won't load in the browser. Any pointers to what I am doing wrong will be greatly appreciated.
Related
I've found a lot of questions on this topic. Always the answer was to use the '0.0.0.0' IP-adress. But I'm already doing this and still I get the error.
So I'm running a docker compose file that runs a database and a flask front end. The dockerfile runs fine on my own computer but on the server in the cloud I am getting this error.
This code launches the application:
app.run(host="0.0.0.0", port=5000, ssl_context="adhoc", debug=cfg.app_debug_mode)
This is my docker compose file:
version: "3.8"
services:
app:
image: app_image #the beginning is the unique uri of my amazon qccount. Then follows the repository name (ratio) and then the tag of the image (app) https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html
build: ./app
links:
- database
ports:
- "5000:5000"
environment:
AM_I_IN_A_DOCKER_CONTAINER: 'Yes'
CONFIG_NAME: 'config' #Name of the config file to use
database:
image: database_image
container_name: database
build: ./sql
restart: always
ports:
- "32000:32000"
environment:
MYSQL_ROOT_HOST: '%' #This allows the root user to access the database from any ip. For some reason amazon requires it.
MYSQL_ROOT_PASSWORD: 'zv2yRCt79AsGvz'
MYSQL_DATABASE: 'education'
volumes:
- ratio_volume:/var/lib/mysql #use a named volume for the database.
networks:
default:
name: my-network
volumes:
ratio_volume:
This is the docker file:
FROM python:3
RUN pip3 install --upgrade pip
WORKDIR /app
COPY . /app
RUN pip3 --no-cache-dir install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python3"]
CMD ["/app/run.py"]
What am I doing wrong? The error is also not really helpful.. I am not getting any errors in the console, just the browser is complaining.
I'm trying to run a Next.js project inside docker-compose. To take advantage of hot-reloading, I'm mounting in the entire project to the Docker image as a volume.
So far, so good!
This is where things are starting to get tricky: For this particular project, it turns out Apple Silicon users need a .babelrc file included in their dockerized app, but NOT in the files on their computer.
All other users do not need a .babelrc file at all.
To sum up, this is what I'd like to be able to do:
hot reload project (hence ./:/usr/src/app/)
have an environment variable write content to /usr/src/app/.babelrc.
not have a .babelrc in the host's project root.
My attempt at solving was including the .babelrc under ci-cd/.babelrc in the host file system.
Then I tried mounting the file as a volume like - ./ci-cd/.babelrc:/usr/src/app/.babelrc. But then a .babelrc file gets written back to the root of the project in the host filesystem.
I also tried include COPY ./ci-cd/.babelrc /usr/src/app/.babelrc within the Dockerfile, but it seems to be overwritten with docker-composes's volume property.
Here's my Dockerfile:
FROM node:14
WORKDIR /usr/src/app/
COPY package.json .
RUN npm install
And the docker-compose.yml:
version: "3.8"
services:
# Database image
psql:
image: postgres:13
restart: unless-stopped
ports:
- 5432:5432
# image for next.js project
webapp:
build: .
command: >
bash -c "npm run dev"
ports:
- 3002:3002
expose:
- 3002
depends_on:
- testing-psql
volumes:
- ./:/usr/src/app/
I've 2 problems with flask app in docker. Application working slowly and freeze after finish last request (for example: first route work fine, next click other link/page app freeze. If i go to homepage via URL and run page again working ok ). Outside docker app working very fast.
Second problem is docker not synch files in container after change files.
# Dockerfile
FROM python:3.9
# set work directory
WORKDIR /base
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apt-get update
RUN pip install --upgrade pip
COPY ./requirements.txt /base/requirements.txt
COPY ./base_app.py /base/base_app.py
COPY ./config.py /base/config.py
COPY ./certs/ /base/certs/
COPY ./app/ /base/app/
COPY ./tests/ /base/tests/
RUN pip install -r requirements.txt
# docker-compose
version: '3.3'
services:
web:
build: .
command: tail -f /dev/null
volumes:
- ${PWD}/app/:/usr/src/app/
networks:
- flask-network
ports:
- 5000:5000
depends_on:
- flaskdb
flaskdb:
image: postgres:13-alpine
volumes:
- ${PWD}/postgres_database:/var/lib/postgresql/data/
networks:
- flask-network
environment:
- POSTGRES_DB=db_name
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
ports:
- "5432:5432"
restart: always
networks:
flask-network:
driver: bridge
`
You have a couple of significant errors in the code you show.
The first problem is that your application doesn't run at all: the Dockerfile is missing the CMD line that tells Docker what to run, and you override it in the Compose setup with a meaningless tail command. You should generally set this in the Dockerfile:
CMD ["./base_app.py"]
You can remove most of the Compose settings you have. You do not need command: (it's in the Dockerfile), volumes: (what you have is ineffective and the code is in the image anyways), or networks: (Compose provides a network named default; delete all of the networks: blocks in the file).
Second problem is docker not synch files in container after change files.
I don't usually recommend trying to do actual development in Docker. You can tell Compose to just start the database
docker-compose up -d flaskdb
and then you can access it from the host (PGHOST=localhost, PGPORT=5432). This means you can use an ordinary non-Docker Python virtual environment for development.
If you do want to try to use volumes: to simulate a live development environment (you talk about performance; this specific path can be quite slow on non-Linux hosts) then you need to make sure the left side of volumes: is the host directory with your code (probably .), the right side is the container directory (your Dockerfile uses /base), and your Dockerfile doesn't rearrange, modify, or generate the files at all (the bind mount hides all of it).
# don't run the application in the image; use the Docker infrastructure
# to run something else
volumes:
# v-------- left side: host path (matches COPY source directory)
- .:/base
# ^^^^-- right side: container path (matches WORKDIR/destination directory)
I'm working on a project required dockerizing a rails application, the app is using mongodb (mongoid gem), and sidekiq & redis.
our goal is to create 3 containers, one for redis, the other is for sidekiq, and the third is for the rails application, we do not want to create a container for mongodb, but we will use the rails app container to connect to the mongodb running on our local machine (because on staging and production we're using mongodb atlas so no need for a mongodb container at all).
Every time I try to run the 3 containers, I get this error when trying to access endpoints dealing with mongo
Mongo::Error::NoServerAvailable (No server is available matching preference: #<Mongo::ServerSelector::Primary:0x41321220 tag_sets=[] max_staleness=nil> using server_selection_timeout=30 and local_threshold=0.015):
and here are the files I used to dockerize my application
Dockerfile
FROM ruby:2.4.2
RUN apt-get update -qq && apt-get install -y nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
# Add a script to be executed every time the container starts.
COPY /docker/entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
version: '3.7'
services:
redis:
image: redis:latest
ports:
- "6379:6379"
elagi_app:
build:
context: '..'
dockerfile: 'docker/Dockerfile'
environment:
RAILS_ENV: development
ELASTICSEARCH_URL: 192.168.1.109:9200
MONGO_CONNECTION_STRING: 192.168.1.109:27017
REDIS_URL: redis://redis:6379
ports:
- "3000:3000"
volumes:
- ./../app:/myapp/app
- ./../config:/myapp/config
- ./../lib:/myapp/lib
- ./../db:/myapp/db
- ./../spec:/myapp/spec
sidekiq:
build:
context: '..'
dockerfile: 'docker/Dockerfile'
environment:
RAILS_ENV: development
ELASTICSEARCH_URL: 192.168.1.109:9200
MONGO_CONNECTION_STRING: 192.168.1.109:27017
REDIS_URL: redis://redis:6379
volumes:
- ./../app:/myapp/app
- ./../config:/myapp/config
- ./../lib:/myapp/lib
- ./../db:/myapp/db
- ./../spec:/myapp/spec
depends_on:
- 'redis'
command: 'sidekiq -C config/sidekiq.yml'
entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$#"
mongoid.yml
development:
clients:
default:
database: elagi
hosts:
- <%= ENV["MONGO_CONNECTION_STRING"] %>
options:
user: 'admin'
password: 'admin123'
max_pool_size: 20
wait_queue_timeout: 15
options:
raise_not_found_error: false
how can I solve this problem ?
You are juggling a lot of moving pieces.
First, the exception message you referenced indicates you are using an old version of the driver (mongo gem). Update to the current version to get improved diagnostics, including for this particular scenario, as well as bugfixes.
Then, start verifying that each piece is functioning by itself. You are running the database on the host; can you connect to it from the host machine? Are you able to connect to other services on the host from the app container (e.g. ssh)? Are you able to connect from the app container to other services (e.g. elasticsearch)?
I have an issue running my docker-compose.yml file with 4 services. They are my go microservice, phoenix web server, mongodb and redis images.
I specified in both my phoenix and golang dockerfiles to change working directory before running both services. I currently get the following errors when I do docker-compose up.
The task "phx.server" could not be found
main.go: no such file or directory
Here is my Dockerfile.go.development:
# base image elixer to start with
FROM golang:latest
# create app folder
RUN mkdir /goApp
COPY ./genesys-api /goApp
WORKDIR /goApp/cmd/genesys-server
# install dependencies
RUN go get gopkg.in/redis.v2
RUN go get github.com/gorilla/handlers
RUN go get github.com/dgrijalva/jwt-go
RUN go get github.com/gorilla/context
RUN go get github.com/gorilla/mux
RUN go get gopkg.in/mgo.v2/bson
RUN go get github.com/graphql-go/graphql
# run phoenix in *dev* mode on port 8080
CMD go run main.go
Here is my Dockerfile.phoenix.development:
# base image elixer to start with
FROM elixir:1.6
# install hex package manager
RUN mix local.hex --force
RUN mix local.rebar --force
# install the latest phoenix
RUN mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez --force
# create app folder
RUN mkdir /app
COPY ./my_app /app
WORKDIR /app
# install dependencies
RUN mix deps.get
# run phoenix in *dev* mode on port 4000
CMD mix phx.server
Here is my docker-compose.yml file:
version: '3.6'
services:
go:
build:
context: .
dockerfile: Dockerfile.go.development
ports:
- 8080:8080
volumes:
- .:/goApp
depends_on:
- db
- redis
phoenix:
# tell docker-compose which Dockerfile it needs to build
build:
context: .
dockerfile: Dockerfile.phoenix.development
# map the port of phoenix to the local dev port
ports:
- 4000:4000
# mount the code folder inside the running container for easy development
volumes:
- .:/app
# make sure we start mongodb when we start this service
# links:
# - db
depends_on:
- db
- redis
environment:
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
FACEBOOK_CLIENT_ID: ${FACEBOOK_CLIENT_ID}
FACEBOOK_CLIENT_SECRET: ${FACEBOOK_CLIENT_SECRET}
db:
container_name: db
image: mongo:latest
volumes:
- ./data/db:/data/db
ports:
- 27017:27017
redis:
container_name: redis
image: redis:latest
ports:
- "6379:6379"
volumes:
- ./data/redis:/data/redis
entrypoint: redis-server
restart: always
For the error related to go microservice, Since the go binary is not found in PATH, you may need to set the GOPATH env variable via your docker file for go:
export GOPATH=