I want to build the latest environment as much as possible at the minimum.
――It is an environment constructed on a trial basis. ――For various reasons, one container has multiple roles. --Even if it is "#" at the time of actual execution, it is written with "$". --I wrote the password directly, because it is a trial environment.
$ mkdir -p containers/base_image
$ cd containers/base_image
Write a Dockerfile.
$ vi Dockerfile
Enable systemd by referring to Docker Hub description. Migrated from CentOS 8 to CentOS Stream by referring to Official information of CentOS Stream.
[Dockerfile]
FROM centos:latest
MAINTAINER tora_tz
ENV CONTAINER_NAME local/cos-stream
ENV CONTAINER_VERSION 20210104_01
#Migrate to Centos Stream
#Install CentOS Stream repository information
RUN dnf install -y centos-release-stream
#Delete repository information
RUN dnf swap -y centos-{linux,stream}-repos
#Synchronize with the latest package
RUN dnf distro-sync -y
#Build
$ docker build --rm -t local/cos-stream .
#Confirm that it was built
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
local/cos-stream latest f0ccd16bd6fc 16 seconds ago 526MB
Create a minimum image required for development that contains Ruby.
First of all, confirmation with the minimum contents
$ mkdir ../dev_base
$ cd ../dev_base
$ vi Dockerfile
[Dockerfile]
FROM local/cos-stream
MAINTAINER tora_tz
# system update
RUN dnf -y upgrade; dnf clean all;
$ docker build --rm -t local/dev_base:0.1 .
(Omission)
Successfully tagged local/dev_base:0.1
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
local/dev_base 0.1 cab625bee967 10 seconds ago 532MB
local/cos-stream latest f0ccd16bd6fc 10 minutes ago 526MB
#Create and start.
$ docker run -dit --name dev_base_container local/dev_base:0.1
#Check the created container.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae0b8ebe78b2 local/dev_base:0.1 "/bin/bash" 5 seconds ago Up 5 seconds dev_base_container
$ docker start dev_base_container
#Go inside the container
$ docker exec -it dev_base_container bash
#Confirm that you have migrated to CentOS Stream.
$ cat /etc/centos-release
CentOS Stream release 8
#Check what is in
$ dnf list installed
When deleting
$ docker stop dev_base_container
$ docker rm dev_base_container
I rewrote the Dockerfile as follows. Specifically, the following points have been fixed.
--Install rbenv
for Ruby version control.
--Install nodenv
for version control of Node.js.
--Added environment variables so that you can check the version of the container from the inside.
FROM local/cos-stream
MAINTAINER tora_tz
ENV CONTAINER_VERSION 0.2
# system update&install
RUN dnf -y upgrade && dnf install -y git && dnf clean all
# anyenv install
SHELL ["/bin/bash", "-c"]
RUN git clone https://github.com/anyenv/anyenv ~/.anyenv
ENV PATH ~/.anyenv/bin:$PATH
RUN echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
RUN anyenv install --force-init
RUN anyenv install rbenv
RUN anyenv install nodenv
RUN exec $SHELL -l
#Build
$ docker run -dit --name dev_base_container local/dev_base:0.2
# --Without login,.bash_profile doesn't work.
$ docker exec -it dev_base_container /bin/bash --login
$ rbenv install --list
2.5.8
2.6.6
2.7.2
3.0.0
$ nodenv install --list
(Omission)
15.2.1
15.3.0
15.4.0
15.5.0
Make sure you have Ruby 3.0.
Corrected Dockerfile by referring to Dependent library at build time.
[Dockerfile]
FROM local/cos-stream
MAINTAINER tora_tz
ENV CONTAINER_NAME dev_name
ENV CONTAINER_VERSION 0.3
# change bash
SHELL ["/bin/bash", "-c"]
# system update&install
RUN dnf upgrade -y \
&& dnf install -y dnf-plugins-core \
&& dnf config-manager --enable powertools \
&& dnf install -y sudo which git gcc make bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel \
&& dnf clean all
ENV DOCKER_USER developer
RUN useradd -mU ${DOCKER_USER}
#Add sudo settings
RUN echo '${DOCKER_USER} ALL=(ALL:ALL) ALL' | EDITOR='tee -a' visudo
# RUN echo '${DOCKER_USER} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
#Grant sudo privileges
RUN gpasswd -a ${DOCKER_USER} ${DOCKER_USER}
#Belong to a sudo-enabled group.
RUN usermod -aG wheel ${DOCKER_USER}
#Set password
RUN echo "${DOCKER_USER}:dev_pass" | chpasswd
#Change execution user
USER ${DOCKER_USER}
ENV WORKSPACE_PATH /home/${DOCKER_USER}/workspace
RUN mkdir -p ${WORKSPACE_PATH}
WORKDIR ${WORKSPACE_PATH}
# anyenv install
RUN git clone https://github.com/anyenv/anyenv ~/.anyenv
ENV PATH ~/.anyenv/bin:$PATH
RUN echo 'eval "$(anyenv init -)"' >> ~/.bashrc
RUN anyenv install --force-init
RUN anyenv install rbenv
RUN anyenv install nodenv
RUN exec $SHELL -l
# Ruby&Node.js Install
RUN source ~/.bashrc \
&& rbenv install 3.0.0 \
&& rbenv global 3.0.0 \
&& nodenv install 15.5.0 \
&& nodenv global 15.5.0
$ docker build --rm -t local/dev_base:0.3 .
$ docker stop dev_base_container
$ docker rm dev_base_container
$ docker run -dit --name dev_base_container local/dev_base:0.3
$ docker exec -it dev_base_container /bin/bash --login
$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]
$ node -v
v15.5.0
$ gem -v
3.2.3
$ bundler -v
Bundler version 2.2.4
$ mkdir ../dev_rails_base
$ cd ../dev_rails_base
$ vi Dockerfile
[Dockerfile]
FROM local/dev_base:0.3
MAINTAINER tora_tz
ENV CONTAINER_NAME dev_rails_base
ENV CONTAINER_VERSION 0.1
USER ${DOCKER_USER}
ENV APP_ROOT ${WORKSPACE_PATH}/rails_test
RUN mkdir -p ${WORKSPACE_PATH}/rails_test
WORKDIR ${APP_ROOT}
USER root
#Add the yarn repository and install the Rails dependent libraries.
# see https://classic.yarnpkg.com/ja/docs/install/#centos-stable
RUN curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo && dnf install -y yarn sqlite gcc-c++
#Set up the repository using the MariaDB package repository setup script.
# see https://mariadb.com/kb/en/yum/
RUN curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash
#Install MariaDB
RUN dnf upgrade -y && dnf install -y MariaDB-server galera-4 MariaDB-client MariaDB-shared MariaDB-backup MariaDB-common MariaDB-devel && dnf clean all
USER ${DOCKER_USER}
#Add a Gemfile.
COPY --chown=${DOCKER_USER}:${DOCKER_USER} Gemfile ${APP_ROOT}
#Generate a Gem file.
RUN source ~/.bashrc \
&& bundle config set path 'vendor/bundle' \
&& bundle install \
&& bundle exec rails new . --force -d mysql --minimal
COPY --chown=${DOCKER_USER}:${DOCKER_USER} database.yml ${APP_ROOT}/config/database.yml
EXPOSE 3000
$ vi Gemfile
[Gemfile]
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails", '>= 6.1'
$ vi database.yml
[database.yml]
# MySQL. Versions 5.5.8 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: rails_user
password: test_password
host: localhost
development:
<<: *default
database: rails_test_development
port: 3315
# 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: rails_test_test
# As with config/credentials.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password or a full connection URL as an environment
# variable when you boot the app. For example:
#
# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# If the connection URL is provided in the special DATABASE_URL environment
# variable, Rails will automatically merge its configuration values on top of
# the values provided in this file. Alternatively, you can specify a connection
# URL environment variable explicitly:
#
# production:
# url: <%= ENV['MY_APP_DATABASE_URL'] %>
#
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full overview on how database connection configuration can be specified.
#
production:
<<: *default
database: rails_test_production
username: rails_test
password: <%= ENV['RAILS_TEST_DATABASE_PASSWORD'] %>
$ docker build --rm -t local/dev_rails_base:0.1 .
$ docker run -dit --name dev_rails_base_container -p49152:3000 local/dev_rails_base:0.1
$ docker exec -it dev_rails_base_container /bin/bash --login
#Launch MariaDB
$ echo dev_pass | sudo -S nohup mysqld_safe &
Execute the following in another tab.
#MariaDB initial setup
$ docker exec -it dev_rails_base_container /bin/bash --login
$ sudo mysql_secure_installation
Enter current password for root (enter for none):test_password
Switch to unix_socket authentication [Y/n]:n
Change the root password? [Y/n]:n
Remove anonymous users? [Y/n]:Y
Disallow root login remotely? [Y/n]:Y
Remove test database and access to it? [Y/n]:Y
Reload privilege tables now? [Y/n]:Y
Thanks for using MariaDB!
$ sudo mysql -u root -p
MariaDB [(none)]> use mysql;
MariaDB [mysql]> SELECT user, host, plugin FROM user;
+-------------+-----------+-----------------------+
| User | Host | plugin |
+-------------+-----------+-----------------------+
| mariadb.sys | localhost | mysql_native_password |
| root | localhost | mysql_native_password |
| mysql | localhost | mysql_native_password |
+-------------+-----------+-----------------------+
#Create a user to access from Rails.
MariaDB [mysql]> CREATE USER 'rails_user'@'%' identified by 'test_password';
MariaDB [mysql]> GRANT ALL PRIVILEGES ON *.* TO 'rails_user'@'%' WITH GRANT OPTION;
MariaDB [mysql]> SELECT user, host, plugin FROM user;
+-------------+-----------+-----------------------+
| User | Host | plugin |
+-------------+-----------+-----------------------+
|(Omission) | | |
| rails_user | % | mysql_native_password |
+-------------+-----------+-----------------------+
MariaDB [mysql]> flush privileges;
MariaDB [mysql]> quit;
$ bin/rails db:create
Created database 'rails_test_development'
Created database 'rails_test_test'
#Start Rails.
$ bin/rails s -b 0.0.0.0
I was able to build it so far.
--Enable systemd. (It seems that you have to have privileges, so give up in some cases)
[OK]Started Update UTMP about System Runlevel Changes.
Since it stops at, it is necessary to investigate this area when implementing it.
--Switch to Docker Compose and split the container. --Allow development from Visual Studio Code. ――Automate the manual setup. --Enable MariaDB autostart settings. (Since systemctl cannot be used, use mysqld_safe ... but it is necessary to consider the startup time, so countermeasures are required) --Allow DB access from clients such as Sequel Ace. (I tried to add the port setting, but I could not do it, so I need to investigate) --Linkage with GitHub (account is passed as an argument) --Allow information such as a solid password to be passed as an argument from the outside. --You don't have to specify a login shell. (Use ENTRY POINT, etc ...)
-I wrote CentOS (Docker image) in Japanese environment with Dockerfile -CentOS Official Repository -List of Dockerfile notations that you might use often -How to delete Docker image and container -Check CMD of existing image -About Dockerfile (Japanese translation) -Run Dockerfile RUN and CMD in Bash login shell -Virtualize development environment with Docker