We were developing using rails in the local environment, but in consideration of future deployment, we decided to manage the environment in a container with Docker. It took a long time for the first time, so I will leave it as a memorandum. I hope it will be helpful for those who need to build a similar environment.
Only the parts changed this time are listed. The root directory is the root directory of the rails app.
.
├── config
│ ├── database.yml #update
│ └── webpacker.yml #update
├── docker
│ └── rails
│ └── Dockerfile #Create New
├── docker-compose.yml #Create New
├── .env #Create New
└── Gemfile #update
Dockerfile
Dockerfile
#Alpine is used for weight reduction.
FROM ruby:2.7.2-alpine3.12
ENV TZ="Asia/Tokyo" \
LANG="C.UTF-8" \
APP_ROOT="/app" \
ENTRYKIT_VERSION="0.4.0"
WORKDIR $APP_ROOT
#Introduction of ENTRY KIT
RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
&& tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
&& rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
&& mv entrykit /bin/entrykit \
&& chmod +x /bin/entrykit \
&& entrykit --symlink
RUN apk update \
&& apk add --no-cache \
alpine-sdk \
bash \
build-base \
mysql-client \
mysql-dev \
nodejs \
tzdata \
yarn
COPY . $APP_ROOT
ENTRYPOINT [ \
"prehook", "bundle install -j4 --quiet", "--", \
"prehook", "yarn install --check-files --ignore-optional", "--"]
Alpine is used to reduce the weight of the image for the efficiency of future work. The capacity has been reduced from about 1.6GB to about 400MB.
By using a multi-stage build and installing nodejs separately, it seems that the image can be further reduced in weight. I was able to reduce the weight to some extent, so this time I decided to stop.
I am using ENTRY KIT to execute yarn install
and bundle install
when the container is started.
In the articles I examined, most of them were executed in the Dockerfile, but due to the following problems, I forgot this time.
Therefore, it is configured to solve the above problem by executing it when the container is started and making the module persistent.
docker-compose.yml
docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0.22
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
ports:
- '3306:3306'
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_DATABASE: ${DATABASE}
MYSQL_ROOT_PASSWORD: ${ROOTPASS}
MYSQL_USER: ${USERNAME}
MYSQL_PASSWORD: ${USERPASS}
web: &app_base
build:
context: .
dockerfile: ./docker/rails/Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b 0.0.0.0"
depends_on:
- db
ports:
- "3000:3000"
volumes:
- .:/app
- gem_modules:/vendor/bundle
- node_modules:/node_modules
tty: true #binding.For pry execution
stdin_open: true #binding.For pry execution
environment:
WEBPACKER_DEV_SERVER_HOST: webpacker #webpack_dev_Specify the container for server execution
BUNDLE_APP_CONFIG: ./.bundle
NODE_ENV: development
RAILS_ENV: development
webpacker: #webpack_dev_container for server execution
<<: *app_base
command: bash -c "bundle exec bin/webpack-dev-server"
depends_on:
- web
ports:
- '3035:3035'
tty: false #binding.Change to false because pry is unnecessary
stdin_open: false #binding.Change to false because pry is unnecessary
environment:
BUNDLE_APP_CONFIG: ./.bundle
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
NODE_ENV: development
RAILS_ENV: development
volumes:
db_data:
gem_modules:
node_modules:
.env
.database.yml
database.yml
default: &default
- adapter: sqlite3
+ adapter: mysql2
+ username: app
+ password: password
+ host: db #Specify the service name
development:
<<: *default
- database: db/development.sqlite3
+ database: mysql_development
webpacker.yml
webpacker.yml
default: &default
dev_server:
- host: localhost
+ host: webpack #Specify the service name
Gemfile
Gemfile
-gem 'sqlite3', '~> 1.4'
+gem 'mysql2', '0.5.3'
.env
.env
DATABASE=mysql_development
USERNAME=app
USERPASS=password
ROOTPASS=password
An error may occur during yarn install
when the container is started for the first time.
As a result of investigation, it seems that the cause is that the name cannot be resolved by DNS.
I tried changing the DNS on the host side, which seems to be the solution, and specifying the DNS in docker-compose.yml
, but it did not solve.
The error did not occur at the second startup, and there was an article that the solution was to restart the container, so leave it as it is.
error /app/node_modules/node-sass: Command failed.
web_1 | Exit code: 1
web_1 | Command: node scripts/build.js
web_1 | Arguments:
web_1 | Directory: /app/node_modules/node-sass
web_1 | Output:
web_1 | Building: /usr/bin/node /app/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
web_1 | gyp info it worked if it ends with ok
web_1 | gyp verb cli [
web_1 | gyp verb cli '/usr/bin/node',
web_1 | gyp verb cli '/app/node_modules/node-gyp/bin/node-gyp.js',
web_1 | gyp verb cli 'rebuild',
web_1 | gyp verb cli '--verbose',
web_1 | gyp verb cli '--libsass_ext=',
web_1 | gyp verb cli '--libsass_cflags=',
web_1 | gyp verb cli '--libsass_ldflags=',
web_1 | gyp verb cli '--libsass_library='
web_1 | gyp verb cli ]
web_1 | gyp info using [email protected]
web_1 | gyp info using [email protected] | linux | x64
web_1 | gyp verb command rebuild []
web_1 | gyp verb command clean []
web_1 | gyp verb clean removing "build" directory
web_1 | gyp verb command configure []
web_1 | gyp verb check python checking for Python executable "python2" in the PATH
web_1 | gyp verb `which` succeeded python2 /usr/bin/python2
web_1 | gyp verb check python version `/usr/bin/python2 -c "import sys; print "2.7.18
web_1 | gyp verb check python version .%s.%s" % sys.version_info[:3];"` returned: %j
web_1 | gyp verb get node dir no --target version specified, falling back to host node version: 12.20.1
web_1 | gyp verb command install [ '12.20.1' ]
web_1 | gyp verb install input version string "12.20.1"
web_1 | gyp verb install installing version: 12.20.1
web_1 | gyp verb install --ensure was passed, so won't reinstall if already installed
web_1 | gyp verb install version not already installed, continuing with install 12.20.1
web_1 | gyp verb ensuring nodedir is created /root/.node-gyp/12.20.1
web_1 | gyp verb created nodedir /root/.node-gyp
web_1 | gyp http GET https://nodejs.org/download/release/v12.20.1/node-v12.20.1-headers.tar.gz
web_1 | gyp WARN install got an error, rolling back install
web_1 | gyp verb command remove [ '12.20.1' ]
web_1 | gyp verb remove using node-gyp dir: /root/.node-gyp
web_1 | gyp verb remove removing target version: 12.20.1
web_1 | gyp verb remove removing development files for version: 12.20.1
web_1 | gyp ERR! configure error
web_1 | gyp ERR! stack Error: getaddrinfo EAI_AGAIN nodejs.org
web_1 | gyp ERR! stack at GetAddrInfoReqWrap.onlookup [as oncomplete](dns.js:66:26)
web_1 | gyp ERR! System Linux 4.19.121-linuxkit
web_1 | gyp ERR! command "/usr/bin/node" "/app/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
web_1 | gyp ERR! cwd /app/node_modules/node-sass
web_1 | gyp ERR! node -v v12.20.1
web_1 | gyp ERR! node-gyp -v v3.8.0
web_1 | gyp ERR! not ok
I will try it when further efficiency is needed, such as shortening the time.
There was an article about building a new Rails app with Docker, but I had a hard time because there weren't many articles about containerizing existing Rails apps. Since it was built once as a development environment, we will consider and work on how to divide and build the test environment and production environment.
In addition, I would like to work on the following contents, so I will write an article if possible.
** ・ How to create a Rails on Docker environment that is easy to develop --Qiita ** ** ・ From Rails new until it works in production mode --Qiita ** ** ・ Building Docker environment with Rails 6.0 x MySQL8 (Alpine base) --Qiita ** ** · More efficient with Docker Compose volumes-Qiita ** ** ・ [Dockerfile full explanation] Create the simplest Docker image for Rails production environment --Qiita ** ** ・ [Docker] I want to know about Rails development! Talk about improving work efficiency by making gem persistent | Enjoy IT Life ** ** ・ Points to keep in mind when building an environment with docker-compose --Qiita ** ** ・ Build Rails + webpacker on Docker environment with docker-compose --RoadMovie **
Recommended Posts