会社の技術スタックのPlaygroundを用意する

# 概要
- 僕はフロントエンドの肩書をもらっていますが、元々はバックエンドでPHPやPythonを扱ってました。Rails初心者です
- Railsを最近触ることが多くなってきました。これまでよちよちしながら書いてたのでそろそろ爆速にならないと厳しくなってきました（色々と(ry
- それゆえ、簡単に遊べる環境がほしいなっておもったので、PlaygroundをDockerでポーンと用意してみました。そのメモです

# 前提

- RubyやVueは最新バージョンを使っていますが、弊社プロダクト色々ありますが最新とは限りませんmm
- あとはもっと色んなサービスを叩く構成してるところもあったりするんですが、その辺は簡単にしています

# compose.yamlの用意

```yaml

services:
  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
      - MYSQL_DATABASE=${DATABASE_NAME}
      - MYSQL_USER=${DATABASE_USER}
      - MYSQL_PASSWORD=${DATABASE_PASSWORD}
    ports:
      - "3306:3306"
    env_file:
      - .env

  redis:
    image: redis:6.2

  backend:
    build:
      context: backend
      dockerfile: Dockerfile.backend
    volumes:
      - ./backend:/app
    ports:
      - "3000:3000"
    env_file:
      - .env
    depends_on:
      - db
      - redis

  sidekiq:
    build:
      context: backend
      dockerfile: Dockerfile.backend
    command: bundle exec sidekiq
    volumes:
      - ./backend:/app
    env_file:
      - .env
    depends_on:
      - db
      - redis

  frontend:
    build:
      context: frontend
      dockerfile: Dockerfile.frontend
    volumes:
      - ./frontend:/app
    ports:
      - "8080:8080"
    depends_on:
      - backend

volumes:
  db_data:
```


# RailsとVueを用意するディレクトリを用意する

```bash
$ mkdir {backend,frontend}
```

# Rails側の準備

```bash
$ touch backend/{Gemfile,Gemfile.lock}
$ vim backend/Dockerfile.backend
```

```Dockerfile:backend/Dockerfile.backend
FROM ruby:3.3.1

# Install dependencies
RUN apt-get update -qq && apt-get install -y nodejs yarn postgresql-client

# Set working directory
WORKDIR /app

# Copy Gemfile and Gemfile.lock
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

# Install gems
RUN bundle install

# Copy the rest of the app
COPY . /app

# Expose port
EXPOSE 3000

# Start the server
CMD ["rails", "server", "-b", "0.0.0.0"]
```


# Vue/Nuxtの準備


```bash
$ touch frontend/{package.json,yarn.lock}
$ vim frontend/Dockerifle.frontend
```


```Dockerfile:frontend/Dockerifle.frontend
FROM node:20

# Set working directory
WORKDIR /frontend

# Copy package.json and yarn.lock
COPY package.json /frontend/package.json
COPY yarn.lock /frontend/yarn.lock

# Copy the rest of the app
COPY . /frontend

# Expose port
EXPOSE 8080

# Start the server
CMD ["yarn", "run", "dev", "--", "--host", "0", "--port", "8080"]

```

# .envファイルの用意

```bash
$ cat <<EOF > .env
DATABASE_HOST=db
DATABASE_NAME=app_development
DATABASE_USER=app_user
DATABASE_PASSWORD=app_password
REDIS_URL=redis://redis:6379/1
RAILS_ENV=development
EOF
```

# Rails、Nuxtのインストール

```bash
# Rails
$ docker compose run --rm backend rails new . --force --database=mysql
$ docker compose run --rm backend bundle add sidekiq rack-cors grape grape-entity

# Nuxt
$ docker compose run --rm frontend npx nuxi@latest init /app --force
Ok to proceed? (y) y

✔ Which package manager would you like to use?
yarn

✔ Initialize git repository?
No
```

# Railsの設定周り

```bash
$ cat <<EOF > backend/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['DATABASE_USER'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  host: <%= ENV['DATABASE_HOST'] %>

development:
  <<: *default
  database: <%= ENV['DATABASE_NAME'] %>

test:
  <<: *default
  database: app_test

production:
  <<: *default
  database: <%= ENV['DATABASE_NAME'] %>
  username: <%= ENV['DATABASE_USER'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  host: <%= ENV['DATABASE_HOST'] %>
EOF

$ cat <<EOF > backend/config/sidekiq.yml
:concurrency: 5
:queues:
  - default

:redis:
  url: <%= ENV['REDIS_URL'] %>
EOF
```


# 起動！

```bash
$ docker compose build --no-cache
$ docker comopse up
```

おｋ〜〜

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101690/66f17522-7c51-154f-23c9-8a94a70d2b7b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101690/59179f45-91c8-acd9-2270-e8d591a07891.png)


話全く関係ないけど、localhostはブクマできるのね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101690/f5482879-82dc-024d-1027-a99c1c9f748f.png)

# マイグレーションとか試してみる

```bash
$ docker compose exec backend rails g model Task
$ docker compose exec backend rails db:migrate RAILS_ENV=development
```


# Grapeの設定

こちら参考にさせてもらいました（ありがとうございます！）

https://zenn.dev/kei1232/articles/3a9218761eff35


```bash
$ docker compose exec backend bundle exec rake grape:routes
/usr/local/bundle/gems/bootsnap-1.18.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30: warning: /usr/local/lib/ruby/3.3.0/mutex_m.rb was loaded from the standard library, but will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. Also contact author of activesupport-7.0.8.3 to add mutex_m into its gemspec.
V1::Tasks  GET    /api/:version/tasks(.:format) タスクの一覧取得
V1::Tasks  GET    /api/:version/tasks/:id(.:format) タスクの詳細取得
V1::Tasks  POST   /api/:version/tasks(.:format) タスクの作成
V1::Tasks  PUT    /api/:version/tasks/:id(.:format) タスクの更新
V1::Tasks  DELETE /api/:version/tasks/:id(.:format) タスクの削除

V1::Root   GET    /api/:version/tasks(.:format) タスクの一覧取得
V1::Root   GET    /api/:version/tasks/:id(.:format) タスクの詳細取得
V1::Root   POST   /api/:version/tasks(.:format) タスクの作成
V1::Root   PUT    /api/:version/tasks/:id(.:format) タスクの更新
V1::Root   DELETE /api/:version/tasks/:id(.:format) タスクの削除

Root       GET    /api/:version/tasks(.:format) タスクの一覧取得
Root       GET    /api/:version/tasks/:id(.:format) タスクの詳細取得
Root       POST   /api/:version/tasks(.:format) タスクの作成
Root       PUT    /api/:version/tasks/:id(.:format) タスクの更新
Root       DELETE /api/:version/tasks/:id(.:format) タスクの削除
```

参考記事通りに進めるとこうなります。（なんか変なワーニングがでてるけど）

# 雑感

これで遊べます。