├── .circleci ├── config.yml └── config.yml.sample ├── .env.dev.sample ├── .gitignore ├── Dockerfile.dev ├── Gemfile ├── README.md ├── docker-compose.yml ├── script ├── bootstrap ├── init └── release.sh └── template └── database.yml /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | branches: 5 | only: 6 | - master 7 | - webpacker 8 | 9 | machine: true 10 | 11 | steps: 12 | 13 | - checkout 14 | 15 | - run: 16 | name: Release 17 | command: sh script/release.sh 18 | -------------------------------------------------------------------------------- /.circleci/config.yml.sample: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | # specify the version you desire here 6 | - image: circleci/ruby:{{RUBY_VERSION}} 7 | environment: # environment variables for primary container 8 | BUNDLE_JOBS: 4 9 | BUNDLE_RETRY: 3 10 | BUNDLE_PATH: vendor/bundle 11 | DATABASE_HOST: 127.0.0.1 12 | DATABASE_USER: circleci-ruby 13 | DATABASE_PASSWORD: "" 14 | RAILS_ENV: test 15 | 16 | # Specify service dependencies here if necessary 17 | # CircleCI maintains a library of pre-built images 18 | # documented at https://circleci.com/docs/2.0/circleci-images/ 19 | - image: circleci/postgres:11.2-alpine-ram 20 | environment: # environment variables for database 21 | POSTGRES_USER: circleci-ruby 22 | POSTGRES_DB: app_test 23 | POSTGRES_PASSWORD: "" 24 | 25 | working_directory: ~/repo 26 | 27 | steps: 28 | 29 | - checkout 30 | 31 | # Download and cache dependencies 32 | - restore_cache: 33 | keys: 34 | - v1-dependencies-{{ checksum "Gemfile.lock" }} 35 | # fallback to using the latest cache if no exact match is found 36 | - v1-dependencies- 37 | 38 | - run: 39 | name: install dependencies 40 | command: | 41 | bundle install --jobs=4 --retry=3 --path vendor/bundle 42 | 43 | - save_cache: 44 | paths: 45 | - ./vendor/bundle 46 | key: v1-dependencies-{{ checksum "Gemfile.lock" }} 47 | 48 | 49 | - run: 50 | name: Test 51 | command: echo do test! 52 | -------------------------------------------------------------------------------- /.env.dev.sample: -------------------------------------------------------------------------------- 1 | DATABASE_HOST=db 2 | DATABASE_PORT=5432 3 | DATABASE_USER=postgres 4 | DATABASE_PASSWORD=password 5 | EDITOR=vim 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /log 2 | /tmp 3 | !/log/.keep 4 | !/tmp/.keep 5 | /public/system 6 | /public/packs 7 | /node_modules 8 | 9 | .env 10 | .env.dev 11 | 12 | /.bundle 13 | /vendor/bundle 14 | 15 | /.idea 16 | 17 | .DS_Store 18 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM node:11.10.0 as node 2 | FROM ruby:2.6.3 3 | 4 | ENV LANG C.UTF-8 5 | 6 | RUN apt-get update -qq && \ 7 | apt-get install -y --no-install-recommends \ 8 | build-essential \ 9 | libpq-dev \ 10 | libfontconfig1 && \ 11 | rm -rf /var/lib/apt/lists/* 12 | 13 | ENV ENTRYKIT_VERSION 0.4.0 14 | 15 | RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \ 16 | && tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \ 17 | && rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \ 18 | && mv entrykit /bin/entrykit \ 19 | && chmod +x /bin/entrykit \ 20 | && entrykit --symlink 21 | 22 | ENV YARN_VERSION 1.13.0 23 | 24 | COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn 25 | COPY --from=node /usr/local/bin/node /usr/local/bin/ 26 | 27 | RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \ 28 | && ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg 29 | 30 | RUN mkdir /app 31 | 32 | WORKDIR /app 33 | 34 | ENTRYPOINT [ \ 35 | "prehook", "ruby -v", "--", \ 36 | "prehook", "bundle install -j3 --quiet", "--"] 37 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # A sample Gemfile 3 | source 'https://rubygems.org' 4 | ruby '2.6.3' 5 | 6 | gem 'rails', '5.2.3' 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker rails template 2 | 3 | Docker template for Rails app or Rails + Webpacker app development. 4 | 5 | ## Use for development 6 | 7 | This template use [entrykit](https://github.com/progrium/entrykit) to execute `bundle install` on ENTRYPOINT of Docker. 8 | 9 | No re-build docker image on changing Gemfile because bundled gems is cached in Docker Volume. 10 | 11 | To develop rails app, use following commands. 12 | 13 | ```bash 14 | script/bootstrap 15 | docker-compose exec rails bash 16 | ``` 17 | 18 | You can execute any commands in docker container. 19 | 20 | ## Getting started 21 | 22 | You can build rails app from template like this. 23 | 24 | ```bash 25 | git clone https://github.com/kawasin73/rails_docker_template.git . 26 | git checkout origin/base/ruby-2.5.1-rails-5.2.0 27 | git branch -d master && git checkout -b master 28 | script/init && script/bootstrap 29 | 30 | docker-compose up -d 31 | docker-compose exec rails bash 32 | # access to http://localhost:3000 33 | ``` 34 | 35 | You can also use built app like this. 36 | 37 | ```bash 38 | git clone https://github.com/kawasin73/rails_docker_template.git . 39 | git checkout origin/ruby-2.5.1-rails-5.2.0 40 | git branch -d master && git checkout -b master 41 | script/bootstrap 42 | # initialize credentials.yml.enc 43 | docker-compose run --rm rails bin/rails credentials:edit 44 | 45 | docker-compose up -d 46 | docker-compose exec rails bash 47 | # access to http://localhost:3000 48 | ``` 49 | 50 | ## Branches 51 | 52 | This repository have 4 types of branch, `master`, `webpacker`, `base`, `built`. 53 | If you want start development, Use `built` branch. 54 | 55 | - master 56 | - `master` branch is branch for develop rails app template. 57 | - webpacker 58 | - `webpacker` branch is master branch of `rails + webpacker` app. 59 | 60 | ### base branch 61 | 62 | `base/ruby-RUBY_VERSION-rails-RAILS_VERSION` branch has only template. 63 | base branch have one `Initial Commit` commit. 64 | 65 | Please build application on your local environment. 66 | 67 | ```bash 68 | git clone https://github.com/kawasin73/rails_docker_template.git . 69 | git checkout origin/base/ruby-2.5.1-rails-5.2.0 70 | git branch -d master && git checkout -b master 71 | script/init && script/bootstrap 72 | ``` 73 | 74 | - [base/ruby-2.5.1-rails-5.2.0](https://github.com/kawasin73/rails_docker_template/tree/base/ruby-2.5.1-rails-5.2.0) 75 | - [base/ruby-2.5.1-rails-5.2.0-webpack](https://github.com/kawasin73/rails_docker_template/tree/base/ruby-2.5.1-rails-5.2.0-webpack) 76 | - [base/ruby-2.5.1-rails-5.2.1](https://github.com/kawasin73/rails_docker_template/tree/base/ruby-2.5.1-rails-5.2.1) 77 | - [base/ruby-2.5.1-rails-5.2.1-webpack](https://github.com/kawasin73/rails_docker_template/tree/base/ruby-2.5.1-rails-5.2.1-webpack) 78 | - [base/ruby-2.6.1-rails-5.2.2](https://github.com/kawasin73/rails_docker_template/tree/base/ruby-2.6.1-rails-5.2.2) 79 | - [base/ruby-2.6.1-rails-5.2.2-webpack](https://github.com/kawasin73/rails_docker_template/tree/base/ruby-2.6.1-rails-5.2.2-webpack) 80 | 81 | ### built branch 82 | 83 | `ruby-RUBY_VERSION-rails-RAILS_VERSION` branch has built application. 84 | 85 | Please initialize secrets and start to development. 86 | 87 | ```bash 88 | git clone https://github.com/kawasin73/rails_docker_template.git . 89 | git checkout origin/ruby-2.5.1-rails-5.2.0 90 | git branch -d master && git checkout -b master 91 | script/bootstrap 92 | # initialize credentials.yml.enc 93 | docker-compose run --rm rails bin/rails credentials:edit 94 | ``` 95 | 96 | - [ruby-2.5.1-rails-5.2.0](https://github.com/kawasin73/rails_docker_template/tree/ruby-2.5.1-rails-5.2.0) 97 | - [ruby-2.5.1-rails-5.2.0-webpack](https://github.com/kawasin73/rails_docker_template/tree/ruby-2.5.1-rails-5.2.0-webpack) 98 | - [ruby-2.5.1-rails-5.2.1](https://github.com/kawasin73/rails_docker_template/tree/ruby-2.5.1-rails-5.2.1) 99 | - [ruby-2.5.1-rails-5.2.1-webpack](https://github.com/kawasin73/rails_docker_template/tree/ruby-2.5.1-rails-5.2.1-webpack) 100 | - [ruby-2.6.1-rails-5.2.2](https://github.com/kawasin73/rails_docker_template/tree/ruby-2.6.1-rails-5.2.2) 101 | - [ruby-2.6.1-rails-5.2.2-webpack](https://github.com/kawasin73/rails_docker_template/tree/ruby-2.6.1-rails-5.2.2-webpack) 102 | 103 | ## License 104 | 105 | MIT 106 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | rails: 4 | build: 5 | context: . 6 | dockerfile: "Dockerfile.dev" 7 | command: "bundle exec rails s -p 3000 -b 0.0.0.0" 8 | env_file: 9 | - "./.env.dev" 10 | volumes: 11 | - ".:/app" 12 | volumes_from: 13 | - data 14 | ports: 15 | - "3000:3000" 16 | depends_on: 17 | - db 18 | db: 19 | image: "postgres:11.2" 20 | environment: 21 | - "POSTGRES_USER=postgres" 22 | - "POSTGRES_PASSWORD=password" 23 | volumes_from: 24 | - data 25 | ports: 26 | - "5432:5432" 27 | data: 28 | image: "busybox" 29 | volumes: 30 | - "db:/var/lib/postgresql/data" 31 | - "bundle:/usr/local/bundle" 32 | 33 | volumes: 34 | db: 35 | driver: local 36 | bundle: 37 | driver: local 38 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cp .env.dev.sample .env.dev 4 | 5 | set -e 6 | 7 | 8 | docker-compose build 9 | 10 | docker-compose run --rm rails bin/rails db:create 11 | docker-compose run --rm rails bin/rails db:migrate 12 | -------------------------------------------------------------------------------- /script/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cp .env.dev.sample .env.dev 6 | 7 | docker-compose build 8 | 9 | docker-compose run --rm rails bundle exec rails new . --force --database=postgresql --skip-turbolinks --skip-git --skip-test 10 | 11 | cp -f template/database.yml config/database.yml 12 | 13 | docker-compose run --rm rails bundle exec spring binstub --all 14 | -------------------------------------------------------------------------------- /script/release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # 3 | # release script 4 | # 5 | 6 | set -eu 7 | 8 | # 9 | # remove files for release 10 | # 11 | rm script/release.sh 12 | rm .circleci/config.yml 13 | 14 | # 15 | # parse ruby version 16 | # 17 | RUBY_VERSION=$(cat Gemfile | grep ruby | grep -v "source" | sed "s/.*'\([0-9]\(\.[0-9]*\)*\)'.*/\1/g") 18 | 19 | # 20 | # parse rails version 21 | # 22 | RAILS_VERSION=$(cat Gemfile | grep rails | sed "s/.*'\([0-9]\(\.[0-9]*\)*\)'.*/\1/g") 23 | 24 | # 25 | # check git current branch 26 | # 27 | BRANCH=$(git rev-parse --abbrev-ref HEAD) 28 | SUFFIX= 29 | if [ $BRANCH = master ]; then 30 | SUFFIX="" 31 | elif [ $BRANCH = webpacker ]; then 32 | SUFFIX="-webpack" 33 | else 34 | echo "$BRANCH is not branch for release" 35 | exit 1 36 | fi 37 | 38 | # 39 | # create release branch name 40 | # 41 | RELEASE_BRANCH="ruby-$RUBY_VERSION-rails-$RAILS_VERSION$SUFFIX" 42 | BASE_BRANCH="base/$RELEASE_BRANCH" 43 | 44 | echo 45 | echo === branch name === 46 | echo RELEASE_BRANCH = $RELEASE_BRANCH 47 | echo BASE_BRANCH = $BASE_BRANCH 48 | echo 49 | 50 | # 51 | # setup git config 52 | # 53 | git config user.email "kawasin73@gmail.com" 54 | git config user.name "Kawamura Shintaro" 55 | 56 | # 57 | # create .circleci/config.yml 58 | # 59 | echo 60 | echo === create .circleci/config.yml === 61 | echo 62 | 63 | cat .circleci/config.yml.sample | sed "s/{{RUBY_VERSION}}/$RUBY_VERSION/g" > .circleci/config.yml 64 | rm .circleci/config.yml.sample 65 | 66 | # 67 | # remove duplicated branch 68 | # 69 | if [ -n "$(git branch | grep $BASE_BRANCH)" ]; then 70 | echo === remove git branch $BASE_BRANCH === 71 | git branch -D $BASE_BRANCH 72 | else 73 | echo === not found git branch $BASE_BRANCH === 74 | fi 75 | 76 | if [ -n "$(git branch | grep $RELEASE_BRANCH)" ]; then 77 | echo === remove git branch $RELEASE_BRANCH === 78 | git branch -D $RELEASE_BRANCH 79 | else 80 | echo === not found git branch $RELEASE_BRANCH === 81 | fi 82 | 83 | # 84 | # create base branch 85 | # 86 | echo 87 | echo === create base branch === 88 | echo 89 | 90 | git checkout -b $BASE_BRANCH 91 | 92 | # create initial commit 93 | git reset `git rev-list --max-parents=0 --abbrev-commit HEAD` 94 | git add . 95 | git commit --amend --no-edit --author="Kawamura Shintaro " --date="`date -R`" 96 | 97 | # 98 | # build template and create release branch 99 | # 100 | echo 101 | echo === build template and create release branch === 102 | echo 103 | 104 | git checkout -b $RELEASE_BRANCH 105 | 106 | echo 107 | echo === script/init === 108 | echo 109 | sudo script/init 110 | 111 | echo 112 | echo === script/bootstrap === 113 | echo 114 | sudo script/bootstrap 115 | 116 | echo 117 | echo === remove config/credentials.yml.enc config/master.key === 118 | echo 119 | sudo rm config/credentials.yml.enc config/master.key 120 | 121 | # create build commit 122 | git add . 123 | git commit -m "script/init && script/bootstrap && rm config/credentials.yml.enc config/master.key" 124 | 125 | # 126 | # git push created branches 127 | # 128 | echo 129 | echo === git push created branches === 130 | echo 131 | 132 | git push -f -u origin $BASE_BRANCH 133 | git push -f -u origin $RELEASE_BRANCH 134 | 135 | # 136 | # clean up 137 | # 138 | echo 139 | echo === clean up === 140 | echo 141 | docker-compose down -v 142 | 143 | sudo rm -rf log/ tmp/ 144 | -------------------------------------------------------------------------------- /template/database.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: postgresql 3 | encoding: unicode 4 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 5 | username: <%= ENV.fetch('DATABASE_USER') { 'root' } %> 6 | password: <%= ENV.fetch('DATABASE_PASSWORD') { 'password' } %> 7 | host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %> 8 | port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %> 9 | 10 | development: 11 | <<: *default 12 | database: app_development 13 | 14 | test: 15 | <<: *default 16 | database: app_test 17 | 18 | production: 19 | <<: *default 20 | database: app_production 21 | --------------------------------------------------------------------------------