Docker, Rails, Postgres - 数据库服务未找到错误

34 浏览
0 Comments

Docker, Rails, Postgres - 数据库服务未找到错误

Dockerfile

FROM ruby:2.6.3
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /paper_scammer_docker
WORKDIR /paper_scammer_docker
COPY Gemfile /paper_scammer_docker/Gemfile
COPY Gemfile.lock /paper_scammer_docker/Gemfile.lock
RUN bundle install
COPY . /paper_scammer_docker
# 添加一个脚本,每次容器启动时执行
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# 启动主进程
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml

version: '3'

services:

db:

image: postgres:10

ports:

- "5432:5432"

volumes:

- ./tmp/db:/var/lib/postgresql/data

web:

build: .

command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

volumes:

- .:/paper_scammer_docker

ports:

- "3000:3000"

links:

- "db:db"

depends_on:

- db

我成功使用以下命令构建了镜像

docker-compose build

如果我在项目根目录中运行docker-compose up,我的应用程序正常运行,并且我可以通过docker container ls看到两个容器,一个用于我的Rails应用程序,另一个用于PostgreSQL。我观察到PostgreSQL镜像是从库中加载的。

database.yml 文件

# SQLite version 3.x

# gem install sqlite3

#

# Ensure the SQLite 3 gem is defined in your Gemfile

# gem 'sqlite3'

#

default: &default

adapter: postgresql

encoding: unicode

pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

timeout: 5000

host: db

username: postgres

password:

# user: gnpsllco_papaer

# password: sharma@123

development:

<<: *default

database: paper_scammer_development

# user: postgres

# password: sharma@123

# Warning: The database defined as "test" will be erased and

# re-generated from your development database when you run "rake".

# Do not set this db to the same as development or production.

test:

<<: *default

database: paper_scammer_test

# user: postgres

# password: sharma@123

production:

<<: *default

database: gnpsllco_paper_scammer

问题

我运行以下命令从我的Rails应用程序的镜像启动Docker容器。

sudo docker run -p 3000:3000 paperscammer_web

PostgreSQL容器未运行或丢失。

我想了解这个docker-compose是如何处理的,当我启动Rails应用程序的镜像时,它应该自动启动一个PostgreSQL容器并将"db"设置为连接的主机。

还是需要手动为PostgreSQL启动。

当我运行http://localhost:3000时,我收到以下错误消息:

could not translate host name "db" to address: Name or service not known

我可以看到PostgreSQL容器未运行。

谢谢

0
0 Comments

问题出现的原因是使用了错误的命令,使用了docker run而不是docker-compose updocker run命令不会使用compose文件,只会使用传递给命令的参数。使用docker run命令时,必须明确指定要运行的容器,如果要同时运行dbweb容器,应该使用该命令两次。

解决方法是使用正确的命令docker-compose up来运行所有在docker-compose.yml文件中指定的容器。同时,还需要在compose文件中添加一个网络,以便容器之间可以相互通信。此外,还可以为容器添加container_name,以便通过名称进行引用。使用这些选项后,容器可以使用名称作为IP地址/主机名进行通信。例如,web容器可以通过以下方式连接到db容器的数据库:http://db:5432/gnpsllco_paper_scammer

关于如何运行数据库迁移的问题,可以参考stackoverflow.com/questions/38089999/…中的解决方法。

最后,建议更新问题并更清楚地表达问题,以便更好地得到帮助。

0
0 Comments

Docker, Rails, Postgres - db service not found error

问题原因:

在docker-compose.yml文件中,api服务依赖于api_db服务。但是在.env文件中,DATABASE_HOST参数的值设置为"api_db",而docker-compose.yml文件中的api_db服务的名称为"api_db"。由于名称不一致,导致api服务无法找到依赖的api_db服务,从而报错。

解决方法:

将.env文件中的DATABASE_HOST参数的值修改为"api_db",与docker-compose.yml文件中的api_db服务名称保持一致。

下面是相关配置文件的内容:

Dockerfile:

ROM ruby:2.6.3-alpine

ENV BUNDLER_VERSION=2.0.2

RUN apk add --update --no-cache \

binutils-gold \

build-base \

curl \

file \

g++ \

gcc \

git \

less \

libstdc++ \

libffi-dev \

libc-dev \

linux-headers \

libxml2-dev \

libxslt-dev \

libgcrypt-dev \

make \

netcat-openbsd \

nodejs \

openssl \

pkgconfig \

postgresql-dev \

python \

tzdata \

yarn

RUN mkdir -p /app

WORKDIR /app

COPY Gemfile* ./

RUN gem install bundler

RUN bundle config build.nokogiri --use-system-libraries

RUN bundle check || bundle install

COPY package.json yarn.lock ./

RUN yarn install --check-files

COPY . ./

COPY ./sh/entrypoints/docker-entrypoint.sh /usr/bin/entrypoint.sh

RUN chmod +x /usr/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]

.env文件:

APP_NAME=api
APP_PORT=3100
DATABASE_NAME=rails_db
DATABASE_USER=batman
DATABASE_PASSWORD=super_pass_123
DATABASE_PORT=5342
DATABASE_HOST=api_db # must be equal to the name of the postgres service in docker-compose.yml

docker-compose.yml文件:

version: '3.7'

services:

api:

build:

context: .

dockerfile: Dockerfile

container_name: ${APP_NAME}

depends_on:

- api_db

ports:

- "${APP_PORT}:${APP_PORT}"

volumes:

- .:/app

- gem_cache:/usr/local/bundle/gems

- node_modules:/app/node_modules

env_file: .env

environment:

RAILS_ENV: development

api_db: # must be equal to `DATABASE_HOST ` in ./.env

image: postgres

command: postgres -c logging_collector=on -c log_destination=stderr -c log_directory=/logs -p ${DATABASE_PORT}

ports:

- "${DATABASE_PORT}:${DATABASE_PORT}"

volumes:

- db_data:/var/lib/postgresql/data

- ./log/db:/logs

environment:

- POSTGRES_USER=${DATABASE_USER}

- POSTGRES_PASSWORD=${DATABASE_PASSWORD}

- POSTGRES_DB=${DATABASE_NAME}

volumes:

gem_cache:

db_data:

node_modules:

.dockerignore文件:

.git
.gitignore
README.md
#
# OS X
#
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
#
# Rails
#
.env
.env.sample
*.rbc
capybara-*.html
log
tmp
db/*.sqlite3
db/*.sqlite3-journal
public/system
coverage/
spec/tmp
**.orig
.bundle
.ruby-version
.ruby-gemset
.rvmrc
# if using bower-rails ignore default bower_components path bower.json files
vendor/assets/bower_components
*.bowerrc
bower.json

docker-entrypoint.sh文件:

DB_INITED=0
if db_version=$(bundle exec rake db:version 2>/dev/null)
then
    if [ "$db_version" = "Current version: 0" ]
    then
        echo "DB is empty"
    else
        echo "DB exists"
        DB_INITED=1
    fi
    bundle exec rake db:migrate 
else
    echo "DB does not exist"
    bundle exec rake db:setup
fi
if [ $DB_INITED == 0 ]
then
    echo "Performing initial configuration"
    # init some plugins, updated db if need, add initial data
fi

database.yml文件:

default: &default

adapter: postgresql

encoding: unicode

pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

database: <%= ENV['DATABASE_NAME'] %>

username: <%= ENV['DATABASE_USER'] %>

password: <%= ENV['DATABASE_PASSWORD'] %>

port: <%= ENV['DATABASE_PORT'] || '5432' %>

host: <%= ENV['DATABASE_HOST'] %>

development:

<<: *default

test:

<<: *default

production:

<<: *default

使用方法:

- 构建和运行:`docker-compose up --build -d`

- 停止:`docker-compose down`

- 停止并删除镜像和卷:`docker-compose down --rmi all --volumes`

0
0 Comments

问题原因:使用docker run命令启动Rails应用时,无法连接到数据库服务,导致数据库未创建。

解决方法:根据文档docs.docker.com/engine/examples/postgresql_service中的建议,在Dockerfile中添加创建数据库的命令,并在数据库存在时跳过。同时,需要通过docker run命令来执行数据库迁移。

以下是完整的

使用Docker部署Rails应用时,遇到了一个问题:无法连接到数据库服务,导致数据库未能成功创建。经过一番探索和尝试,我终于找到了解决方法。

首先,我尝试使用以下命令启动Rails应用:sudo docker run -p 3000:3000 paperscammer_web,但发现只有Web服务器启动了,数据库服务并没有启动。根据提示,我需要使用docker-compose命令来启动应用。具体命令如下:sudo docker-compose up -d --build

第二种方法是使用以下命令:

sudo docker run --name db -p 5432:5432 -v ./tmp/db:/var/lib/postgresql/data postgres:10
sudo docker run -p 3000:3000 --link db:db -v .:/paper_scammer_docker paperscammer_web

。这种方法可以成功启动数据库服务,并与Rails应用建立连接。

然而,当我在生产环境部署时,发现问题又出现了。使用docker-compose up命令时,会查找Dockerfile中定义的服务,并将它们作为容器启动。但是,当我尝试使用sudo docker run -p 3000:3000 paperscammer_web命令启动Rails应用时,发现Rails应用的镜像并不能正常工作。这是因为docker-compose build命令会生成一个用于启动容器的镜像。

我意识到需要在自己的Dockerfile中创建PostgreSQL镜像,并在其中添加创建数据库的命令。同时,如果数据库已存在,则应跳过该步骤。为了实现这一点,我参考了docs.docker.com/engine/examples/postgresql_service中的建议。

通过以上方法,我解决了无法连接到数据库服务的问题,并成功创建了数据库。然而,当我尝试使用sudo docker run -p 3000:3000 --link db:db paperscammer_web bundle exec rake db:create db:migrate命令来执行数据库迁移时,发现容器只执行了迁移命令,然后就退出了。

对此,我认为问题是出在Web应用的镜像上,而不是数据库镜像上。因为Rails的迁移命令需要在数据库容器中运行。我推测,解决方法可能是在Web应用的镜像中添加一些额外的配置。

总结起来,我遇到了无法连接到数据库服务的问题,导致数据库未能成功创建。通过在Dockerfile中添加创建数据库的命令,并在数据库存在时跳过,我解决了这个问题。但是,在执行数据库迁移时仍然遇到了一些困难。希望这篇文章对其他遇到相似问题的人有所帮助。

0