Rails Docker Issues and Fixes

Problem 1

  docker-compose up
[+] Building 0.0s (0/0)
[+] Running 1/0
 Container orendaa-web-1  Created                                                                                                                                    0.0s
Attaching to orendaa-web-1
orendaa-web-1  | => Booting Puma
orendaa-web-1  | => Rails 7.0.5 application starting in development
orendaa-web-1  | => Run `bin/rails server --help` for more startup options
                                                    orendaa-web-1  | Exiting
                                                    orendaa-web-1  | /usr/local/bundle/gems/railties-7.0.5/lib/rails/application/configuration.rb:353:in `database_configuration': Cannot load database configuration: (RuntimeError)
orendaa-web-1  | Could not load database configuration. No such file - ["config/database.yml"]
orendaa-web-1  |        from /usr/local/bundle/gems/activerecord-7.0.5/lib/active_record/railtie.rb:266:in `block (2 levels) in <class:Railtie>'
orendaa-web-1  |        from /usr/local/bundle/gems/activesupport-7.0.5/lib/active_support/lazy_load_hooks.rb:95:in `class_eval'

Details: docker-compose.yml

version: '3'

services:

  web:
    build: .
    ports:
      - "3000:3000"

Dockerfile

FROM ruby:3.2.2
LABEL maintainer="chandan.jhunjhunwal@gmail.com"

RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \
    nodejs
#RUN apt-get install -yqq --no-install-recommends nodejs

COPY Gemfile* /usr/src/app/
WORKDIR /usr/src/app
RUN bundle install

COPY . /usr/src/app

CMD ["bin/rails", "s", "-b", "0.0.0.0"]
Solution 1

I didn’t have database.yml in my source code, when I had built the image. I had moved database.yml.sample to database.yml and tried to do docker-compose up, which failed, because my original image didn’t have database.yml

So I created docker image for web again:

$> docker-compose build web 

Now this issue is resolved:

➜ docker-compose up                                       
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Running 1/1
 ✔ Container orendaa-web-1  Recreated                                                                                                                                  0.4s 
Attaching to orendaa-web-1
orendaa-web-1  | => Booting Puma
orendaa-web-1  | => Rails 7.0.5 application starting in development 
orendaa-web-1  | => Run `bin/rails server --help` for more startup options
orendaa-web-1  | Exiting
orendaa-web-1  | /usr/local/bundle/gems/activerecord-7.0.5/lib/active_record/database_configurations.rb:207:in `build_db_config_from_raw_config': '{ default =>  }' is not a valid configuration. Expected '' to be a URL string or a Hash. (ActiveRecord::DatabaseConfigurations::InvalidConfigurationError)

Problem 2

± ➜ docker-compose up       
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Running 1/1
 ✔ Container orendaa-web-1  Recreated                                                                                                                                  0.5s 
Attaching to orendaa-web-1
orendaa-web-1  | => Booting Puma
orendaa-web-1  | => Rails 7.0.5 application starting in development 
orendaa-web-1  | => Run `bin/rails server --help` for more startup options
orendaa-web-1  | Exiting
orendaa-web-1  | /usr/local/bundle/gems/activerecord-7.0.5/lib/active_record/database_configurations.rb:207:in `build_db_config_from_raw_config': '{ default =>  }' is not a valid configuration. Expected '' to be a URL string or a Hash. (ActiveRecord::DatabaseConfigurations::InvalidConfigurationError)
orendaa-web-1  |        from /usr/local/bundle/gems/activerecord-7.0.5/lib/active_record/database_configurations.rb:156:in `block in build_configs'
orendaa-web-1  |        from /usr/local/bundle/gems/activerecord-7.0.5/lib/active_record/database_configurations.rb:152:in `each'

Details: database.yml

default: &default
adapter: postgis
encoding: utf8
schema_search_path: public

development:
  <<: *default
  username: postgres
  password: root
  host: localhost
  port: 5432
  database: orendaa_development

Solution 2

Fix the indentation in database.yml.

default: &default
  adapter: postgis
  encoding: utf8
  schema_search_path: public

development:
  <<: *default
  username: postgres
  password: root
  host: localhost
  port: 5432
  database: orendaa_development

Problem 3

Large docker image sizes

Solution 3

Use alpine based or slim docker image if you just need the minimalistic version of docker image.

A very nice detailed article from Lemuel here

Problem 4
± ➜ docker-compose run --rm web bin/rails db:create
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Building 0.0s (0/0)                                                                                                                                                     
could not connect to server: Connection refused
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
        Is the server running on host "::1" and accepting
        TCP/IP connections on port 5432?
Couldn't create 'orendaa_development' database. Please check your configuration.
rails aborted!
ActiveRecord::ConnectionNotEstablished: could not connect to server: Connection refused
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
        Is the server running on host "::1" and accepting
        TCP/IP connections on port 5432?


Caused by:
PG::ConnectionBad: could not connect to server: Connection refused
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?
could not connect to server: Cannot assign requested address
        Is the server running on host "::1" and accepting
        TCP/IP connections on port 5432?

Tasks: TOP => db:create
(See full trace by running task with --trace)

Configuration Details:

docker-compose.yml

version: '3'

services:

  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    env_file:
      - .docker/development/web
      - .docker/development/database

  redis:
    image: redis

  database:
    image: postgres
    env_file:
      - .docker/development/database
Solution 4

Ensure .docker/development/web AND .docker/development/database exists for both development and test environment

Problem 5
 ± ➜ docker-compose run --rm web bin/rails db:create
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Building 0.0s (0/0)                                                                                                                                                     
could not translate host name "database" to address: Name or service not known
Couldn't create 'orendaa_development' database. Please check your configuration.
rails aborted!
ActiveRecord::ConnectionNotEstablished: could not translate host name "database" to address: Name or service not known

Configuration details: docker-compose.yml

version: '3'

services:

  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    env_file:
      - .docker/development/web
      - .docker/development/database

  redis:
    image: redis

  database:
    image: postgres
    env_file:
      - .docker/development/database

.docker/development/database

POSTGRES_USER=postgres
POSTGRES_PASSWORD=root
POSTGRES_DB=orendaa_development

.docker/development/web

DATABASE_HOST=database
Solution 5

Force recreate solved the issue.

$> docker-compose up -d --force-recreate

Problem 6

 ➜ docker-compose run --rm web bin/rails db:migrate
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Building 0.0s (0/0)                                                                                                                                                     
== 20230624194643 AddPostgisExtensionToDatabase: migrating ====================
-- enable_extension("postgis")
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::FeatureNotSupported: ERROR:  extension "postgis" is not available
DETAIL:  Could not open extension control file "/usr/share/postgresql/15/extension/postgis.control": No such file or directory.
HINT:  The extension must first be installed on the system where PostgreSQL is running.
/usr/src/app/db/migrate/20230624194643_add_postgis_extension_to_database.rb:3:in `change'

Caused by:
ActiveRecord::StatementInvalid: PG::FeatureNotSupported: ERROR:  extension "postgis" is not available
DETAIL:  Could not open extension control file "/usr/share/postgresql/15/extension/postgis.control": No such file or directory.
HINT:  The extension must first be installed on the system where PostgreSQL is running.
/usr/src/app/db/migrate/20230624194643_add_postgis_extension_to_database.rb:3:in `change'

Caused by:
PG::FeatureNotSupported: ERROR:  extension "postgis" is not available
DETAIL:  Could not open extension control file "/usr/share/postgresql/15/extension/postgis.control": No such file or directory.
HINT:  The extension must first be installed on the system where PostgreSQL is running.
/usr/src/app/db/migrate/20230624194643_add_postgis_extension_to_database.rb:3:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Configuration detail: My database uses postgis extension database.yml

default: &default
  adapter: postgis
  encoding: utf8
  schema_search_path: public

My migration was enabling the POSTGIS extension. However it’s not available with standard postgres image.

class AddPostgisExtensionToDatabase < ActiveRecord::Migration[7.0]
  def change
    enable_extension 'postgis'
  end
end

Solution 6

We need to CREATE POSTGIS EXTENSION onetime. Refer answer here Create a Docker-database file as follows:

FROM postgres:15.3

RUN apt-get update -yqq && apt-get install -yqq \
    postgresql-15-postgis-3

CMD ["/usr/local/bin/docker-entrypoint.sh","postgres"]

Update docker-compose.yml

version: '3'

services:
  database:
    image: postgres
    build:
      context: .
      dockerfile: Dockerfile-database
    env_file:
      - .docker/development/database

Now do docker-compose build

$> docker-compose build 
$> docker-compose up -d --force-recreate
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Running 3/3
 ✔ Container orendaa-web-1       Started                                                                                                                               2.4s 
 ✔ Container orendaa-redis-1     Started                                                                                                                               2.4s 
 ✔ Container orendaa-database-1  Started                                                                                                                               2.4s 

$> docker-compose run database psql -U postgres -h database
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Building 0.0s (0/0)                                                                                                                                                     
Password for user postgres: 
psql (15.3 (Debian 15.3-1.pgdg120+1))
Type "help" for help.

postgres=# CREATE EXTENSION postgis;
CREATE EXTENSION
postgres=# \q
Problem 7
$> docker-compose up web
[+] Building 0.0s (0/0)                                                                                                                                                     
[+] Running 1/0
 ✔ Container orendaa-database-1  Running                                                                                                                               0.0s 
Attaching to orendaa-web-1
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "bin/rails": stat bin/rails: no such file or directory: unknown

Configuration Details:

  web:
    build:
      context: ./rails-api
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    depends_on:
      - database
    env_file:
      - .env
    environment:
      - DATABASE_HOST=postgres
      - DATABASE_USERNAME=$DATABASE_USERNAME
      - DATABASE_PASSWORD=$DATABASE_PASSWORD
      - DATABASE_NAME=$DATABASE_NAME
Solution 7

The volumes was mounting current directory of docker-compose file to /usr/src/app. Updated docker-compose.yml

  web:
    build:
      context: ./rails-api
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - ./rails-api:/usr/src/app

Rails Docker Docker Notes

This is a sapling 🌱 in my digital garden 🏡.

Notes mentioning this note

There are no notes linking to this note.


Here are all the notes in this garden, along with their links, visualized as a graph.