レガシー環境から脱却したい

プログラミングや環境構築の話をまとめています。

docker環境におけるコマンドの省略方法

はじめに

今のプロジェクトではdocker-composeを使って環境構築しています。

その時に問題なのが、コンテナ起動やコンテナ内で実行(composerとかartisanとか)したいときに打つコマンドの長さです。

毎回毎回docker-compose exec app php artisan ...など打つのはちょっと面倒。

コマンドのエイリアスを設定しても良いのですが、複数人で開発するときに全員に設定してもらうのもなぁ。。。
との思いで、スクリプトファイルを用意しましています。

下記記事を参考にしています。感謝
Docker コマンドのショートカットをプロジェクトルートに置いたら快適になった - Qiita

ファイル構成

LinuxBash)とWindowsPowerShell)の両方に対応できるよう作成しています。

┬- bin      (スクリプトディレクトリ)
│    ├- doc.sh
│    ├- artisan.sh
│    ├- composer.sh
│    ├- doc.ps1
│    ├- artisan.ps1
│    └- composer.ps1
├- docker (Dockerの設定)
│    └- Dockerfile
├- src  (ソースディレクトリ)
└- docker-compose.yml

bash

  • bin/doc.sh
#!/bin/bash

cmd="docker-compose $@"

echo $cmd
$cmd
  • bin/artisan.sh
    コンテナ起動時はexec、停止時はrunコマンドで実行するように設定
#!/bin/bash

set -eu

if docker-compose ps app | grep -q Up; then
    cmd="docker-compose exec app php artisan $@"
else
    cmd="docker-compose run --rm app php artisan $@"
fi

echo $cmd
$cmd
  • bin/composer.sh
#!/bin/bash

set -eu

if docker-compose ps app | grep -q Up; then
    cmd="docker-compose exec app composer $@"
else
    cmd="docker-compose run --rm app composer $@"
fi

echo $cmd
$cmd

powershell

  • bin/doc.ps1
$cmd = "docker-compose $Args"

echo $cmd
invoke-expression $cmd
  • bin/artisan.ps1
$run = docker-compose.exe ps app | Out-String -Stream | Select-String "Up"

if($run) {
  $cmd = "docker-compose exec app php artisan $Args"
} else {
  $cmd = "docker-compose run --rm app php artisan $Args"
}

echo $cmd
invoke-expression $cmd
  • bin/composer.ps1
    ※artisan.ps1とほぼ同じため省略

使い方

プロジェクトルートに移動して下記コマンドを実行

# コンテナ起動
./bin/doc.ps1 up -d

# artisanコマンド実行
./bin/artisan.ps1 make:controller HogeController

nuxt.jsのbuildでcore-jsのエラーが出る

f:id:odaryo:20200901175501p:plain

※ issueを再確認すると別の解法のレスがあったので追記します。(2020/06/26追記)

エラーの内容

Nuxt.js + Vuetifyの環境でbuildすると、下記のようなエラーが出るようになりました。

Module not found: Error: Can't resolve 'core-js/modules/...' in '/app/...'

buildログを一部抜粋

$ yarn build

...

ERROR in ./node_modules/vuetify/lib/components/VTabs/VTabs.js
Module not found: Error: Can't resolve 'core-js/modules/web.dom.iterable' in '/app/node_modules/vuetify/lib/components/VTabs'
 @ ./node_modules/vuetify/lib/components/VTabs/VTabs.js 3:0-42
 @ ./node_modules/vuetify/lib/components/VTabs/index.js
 @ ./node_modules/vuetify/lib/components/index.js
 @ ./node_modules/vuetify/lib/index.js
 @ ./.nuxt/vuetify/plugin.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi ./.nuxt/client.js

ERROR in ./node_modules/vuetify/lib/components/VTabs/VTabsBar.js
Module not found: Error: Can't resolve 'core-js/modules/web.dom.iterable' in '/app/node_modules/vuetify/lib/components/VTabs'
 @ ./node_modules/vuetify/lib/components/VTabs/VTabsBar.js 6:0-42
 @ ./node_modules/vuetify/lib/components/VTabs/VTabs.js
 @ ./node_modules/vuetify/lib/components/VTabs/index.js
 @ ./node_modules/vuetify/lib/components/index.js
 @ ./node_modules/vuetify/lib/index.js
 @ ./.nuxt/vuetify/plugin.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi ./.nuxt/client.js

ERROR in ./pages/login.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--2-0!./node_modules/vuetify-loader/lib/loader.js??ref--16-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/login.vue?vue&type=script&lang=js&)
Module not found: Error: Can't resolve 'core-js/modules/web.dom.iterable' in '/app/pages'
 @ ./pages/login.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--2-0!./node_modules/vuetify-loader/lib/loader.js??ref--16-0!./node_modules/vue-loader/lib??vue-loader-options!./pages/login.vue?vue&type=script&lang=js&) 3:0-42
 @ ./pages/login.vue?vue&type=script&lang=js&
 @ ./pages/login.vue
 @ ./.nuxt/router.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi ./.nuxt/client.js

 FATAL  Nuxt build error                                                                                                                                                                                                                                                        06:14:11

  at WebpackBundler.webpackCompile (node_modules/@nuxt/webpack/dist/webpack.js:5314:21)
  at processTicksAndRejections (internal/process/task_queues.js:93:5)
  at async WebpackBundler.build (node_modules/@nuxt/webpack/dist/webpack.js:5263:5)
  at async Builder.build (node_modules/@nuxt/builder/dist/builder.js:5597:5)
  at async Generator.initiate (node_modules/@nuxt/generator/dist/generator.js:70:7)
  at async Generator.generate (node_modules/@nuxt/generator/dist/generator.js:40:5)
  at async Object.run (node_modules/@nuxt/cli/dist/cli-build.js:96:7)
  at async NuxtCommand.run (node_modules/@nuxt/cli/dist/cli-command.js:2575:7)


   ╭─────────────────────────────╮
   │                             │
   │   ✖ Nuxt Fatal Error        │
   │                             │
   │   Error: Nuxt build error   │
   │                             │
   ╰─────────────────────────────╯

error Command failed with exit code 1.

対策

対策①

モジュールを最新にしても解決せず。

調べているとこんなissueが上がってました。

github.com

core-jsが3.xになるとエラーが起きるらしい。

2系の最新版(2019/12/10時点)をインストールするように明記

$ yarn add core-js@2.6.11
$ yarn build

成功!

ビルドするとcore-jsを3系にしろとwarningが出るようになったので対策を考えないと。。。

▽=== 2020/06/25追記 ===▽

対策②

https://github.com/nuxt/nuxt.js/issues/5287#issuecomment-622660147 に別の解法が載っていました。
こちらだとcore-js 3.xにあげても問題なく動作します。

nuxt.config.jsに下記を追加

export default {
  build: {
    babel: {
      presets({ isServer }) {
        return [
          [
            require.resolve('@nuxt/babel-preset-app'),
            // require.resolve('@nuxt/babel-preset-app-edge'), // For nuxt-edge users
            {
              buildTarget: isServer ? 'server' : 'client',
              corejs: { version: 3 }
            }
          ]
        ]
      }
    }
  }
}

package.jsonに「core-js」を追加していたら、記述を削除
(package.jsonに明示的に書かなくても問題ありません。)

下記の依存関係の確認でも古いバージョンを使っていると怒られなくなりました。

$ yarn outdated

なお、このやり方はNuxt.js v2.6.0時点のリリースノートに書かれているようです。

△=== 2020/06/25追記 ===△

nuxt.jsのDocker開発環境

f:id:odaryo:20200901175501p:plain

Nuxt.jsのDocker(docker-compose)を使った開発環境構築メモ

自動で環境構築とテストサーバー起動までを行います。

動作環境

  • Ubuntu18.04

ファイルの説明

ファイル構成

┬ .env
├ docker-compose.yml
├ docker
│    └ Dockerfile
└ front  // ソースコード

docker-compose.yml

version: '3'

services:

  # frontend
  front:
    build:
      context: ./
      dockerfile: ./docker/Dockerfile
      args:
        - NODE_VERSION=${NODE_VERSION}
        - USER_ID=${UID}
        - GROUP_ID=${GROUPS}
    environment:
      HOST: "0.0.0.0"
    command: bash -c "yarn && yarn dev"
    volumes:
      - ./front:/app:cached

Dockerfile

デフォルトだとnpmやyarnがroot権限で動くため、モジュールやビルドファイルがrootで作成されてしまいます。 ファイル削除の際などに面倒なのでパーミッションをユーザと合わせます。

Dockerfileにuser_id/group_idの変更を記載します。

ARG NODE_VERSION

FROM node:${NODE_VERSION}-alpine

RUN apk update \
    && apk upgrade \
    && apk add --no-cache bash \
    && npm install -g nuxt

# change user
ARG USER_ID
ARG GROUP_ID

RUN deluser node && \
    addgroup -g ${GROUP_ID} -S node && \
    adduser -u ${USER_ID} -S node -G node

USER node:node

WORKDIR /app

.env

.envにdocker-compose, Dockerfileで使用する各パラメータを記載します

# Dockerプロジェクト名
COMPOSE_PROJECT_NAME=nuxt_sanple

# ホストのユーザIDと合わせて設定
UID=1000
GROUPS=1000

### Node ##################################################
NODE_VERSION=12

起動方法

$ docker-compose build (初回のみ)
$ docker-compose up -d

補足

nuxt.config.jsを編集した場合は自動読み込みされないため、下記コマンドでリスタートします。

$ docker-compose restart

Windows開発環境でのgitの設定

Windows環境でのGitはGit for Windowsを使っています。

Windowsで開発するときに気をつけないといけないものはいくつかありますが、そのうちの一つが改行コードの設定です。

デフォルトのままGit for Windowsを利用すると、git pullするときに改行コードがCRLFでアップされたりします。

それを防ぐために下記を設定します。

git config -g core.autocrlf input

autocrlfのオプションの意味はこちら

設定 チェックアウト時 コミット時
true LF→CRLF CRLF→LF
input 変換しない CRLF→LF
false 変換しない 変換しない

Windowsでは「input」か「false」にするべきですが、新規ファイル作成時にCRLFになる可能性があるので私は「input」を選択しています。

Windows版Gitでパーミッションを無視する方法

同じリポジトリWindowsLinuxMacなど別々の環境での開発を余儀なくされる場合、パーミッションの違いが差分扱いとなることがあります。 例えばLinuxパーミッションchmod 755のように設定したファイルでも、Windows側では644として判定されるなど。

Windowsでも、ホストとWSL2で扱いが変わったりします。

これはWindowsパーミッションの概念がないことが原因です。

解決策として、Windowsではパーミッションのチェックをしない設定があります。

WindowsでGit bashなどで実行

git config -g core.filemode false

※ 検索すると-gオプションがなくても設定できる記載があったのですが、私の環境ではできませんでした。

ただし。。。

このオプションはすべての環境で行う必要があるそうです。 複数環境で開発している場合は、すべてでcore.filemode falseに設定する必要があります。