从头开始到使用Docker构建Laravel Nuxt TypeScript MySQL环境并显示首页[注意]


前提

当地环境

  • macOS卡塔利娜10.15.5
  • 适用于Mac 2.3.0.4的Docker

版本

  • PHP 7.3
  • Laravel ... 7.30.1
  • Node.js 14.6
  • nuxt /类型2.14
  • MySQL 5.7

其他

  • 最终目录结构

终端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
$ tree -a -L 2 .
.
├── .env
├── .env.example
├── .gitignore
├── .idea
│   ├── modules.xml
│   ├── myapp.iml
│   └── workspace.xml
├── docker
│   ├── nginx
│   ├── node
│   └── php
├── docker-compose.yml
├── frontApp
│   ├── .editorconfig
│   ├── .git
│   ├── .gitignore
│   ├── .nuxt
│   ├── .prettierrc
│   ├── README.md
│   ├── assets
│   ├── components
│   ├── layouts
│   ├── middleware
│   ├── node_modules
│   ├── nuxt.config.js
│   ├── package.json
│   ├── pages
│   ├── plugins
│   ├── static
│   ├── store
│   ├── tsconfig.json
│   └── yarn.lock
└── laravel
    ├── .editorconfig
    ├── .env
    ├── .env.example
    ├── .gitattributes
    ├── .gitignore
    ├── .styleci.yml
    ├── README.md
    ├── app
    ├── artisan
    ├── bootstrap
    ├── composer.json
    ├── composer.lock
    ├── config
    ├── database
    ├── package.json
    ├── phpunit.xml
    ├── public
    ├── resources
    ├── routes
    ├── storage
    ├── tests
    ├── vendor
    └── webpack.mix.js

为项目准备目录

终端

1
2
3
4
$ mkdir -p ~/workspace/myapp
$ cd ~/workspace/myapp
$ mkdir -p laravel docker/{php,nginx,node}
$ mkdir docker/nginx/{conf.d,logs}

.env准备

首先编辑.env.example,然后复制以创建.env

myapp

1
$ touch .env.example .gitignore

编辑.env.example和.gitignore

.env.example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PROJECT_PATH=./laravel
TZ=Asia/Tokyo
WEB_PORT=10080
DB_PORT=13306
DB_TESTING_PORT=13307
DB_CONNECTION=mysql
DB_NAME=myapp
DB_USER=willrewrite
DB_PASS=willrewrite
DB_ROOT_PASS=willrewrite
MAILHOG_PORT=18025
MAIL_HOST=mail
MAIL_PORT=1025

COMPOSE_HTTP_TIMEOUT=70
FRONT_PORT=3000

.gitignore

1
2
3
.env
.idea
# その他個別に追加

复制.env.example

myapp

1
$ cp .env.example .env

复制后,覆盖单个项目的.env环境变量。

创建所需的文件

myapp

1
2
3
4
$ touch docker-compose.yml \
docker/php/{php.ini,Dockerfile} \
docker/nginx/{conf.d/default.conf,Dockerfile} \
docker/node/Dockerfile

编辑每个文件

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
version: "3"

services:
  web:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
      args:
        - TZ=${TZ}
    volumes:
      - ./docker/nginx/logs:/etc/nginx/logs
      - ./docker/nginx/conf.d:/etc/nginx/conf.d
      - ${PROJECT_PATH}:/var/www/laravel
    ports:
      - ${WEB_PORT}:80
    links:
      - app
    depends_on:
      - app

  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
      args:
        - TZ=${TZ}
    volumes:
      - ${PROJECT_PATH}:/var/www/laravel
    links:
      - db_master
    environment:
      - DB_CONNECTION=${DB_CONNECTION}
      - DB_HOST=db_master
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASS}
      - TZ=${TZ}
      - MAIL_HOST=${MAIL_HOST}
      - MAIL_PORT=${MAIL_PORT}

  db_master:
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASS}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASS}
      - TZ=${TZ}
    ports:
      - ${DB_PORT}:3306

  front_app:
    build:
      context: .
      dockerfile: ./docker/node/Dockerfile
      args:
        - TZ=${TZ}
    volumes:
      - ./frontApp:/var/www/frontApp
    ports:
      - ${FRONT_PORT}:3000
    links:
      - web
    depends_on:
      - web

Nginx设置

泊坞窗/ nginx / Dockerfile

1
2
3
4
5
6
7
8
9
10
FROM nginx:1.15.7-alpine
# timezone
ARG TZ
COPY ./docker/nginx/conf.d/ /etc/nginx/conf.d/
COPY ./docker/nginx/logs/ /etc/nginx/logs/
COPY ./laravel/ /var/www/laravel/
RUN apk update && apk --update add tzdata && \
  cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
  apk del tzdata && \
  rm -rf /var/cache/apk/*

泊坞窗/ nginx / conf.d / default.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
    listen       0.0.0.0:80;
    # server_nameで設定した名前をローカルマシンの/etc/hostsにも設定する
    server_name  www.example.org example.org;
    charset      utf-8;
    client_max_body_size 3M;

    root /var/www/laravel/public;

    index index.php;

    location / {
        access_log  /etc/nginx/logs/access.log main;
        error_log   /etc/nginx/logs/error.log;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass  app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

PHP设置

码头工人/ PHP / Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM php:7.3.0RC6-fpm-alpine3.8
# timezone
ARG TZ
WORKDIR /var/www/laravel
COPY ./docker/php/php.ini /usr/local/etc/php/
COPY ./laravel/ /var/www/laravel/

RUN apk upgrade --update && apk add --no-cache \
  coreutils freetype-dev jpeg-dev libjpeg-turbo-dev libpng-dev libmcrypt-dev \
  git vim unzip tzdata \
  libltdl && \
  docker-php-ext-install pdo_mysql mysqli mbstring && \
  docker-php-ext-install -j$(nproc) iconv && \
  docker-php-ext-configure gd \
  --with-freetype-dir=/usr/include/ \
  --with-jpeg-dir=/usr/include/ && \
  docker-php-ext-install -j$(nproc) gd && \
  cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
  apk del tzdata && \
  rm -rf /var/cache/apk/*

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

泊坞窗/ php / php.ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
log_errors = on
error_log = /var/log/php/php-error.log
upload_max_filesize = 3M
memory_limit = -1
post_max_size = 100M
max_execution_time = 900
max_input_vars = 100000
default_charset = UTF-8

[Date]
date.timezone = ${TZ}
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

节点设置

码头工人/节点/ Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM node:14.6.0-alpine
RUN mkdir -p /var/www/frontApp
# timezone
ARG TZ
WORKDIR /var/www/frontApp
COPY ./frontApp/ /var/www/frontApp/

RUN apk update && \
    apk upgrade && \
    apk add --no-cache make gcc g++ python && \
    yarn install

EXPOSE 3000

ENTRYPOINT ["yarn", "run", "dev"]

nuxt-ts项目创建

myapp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ yarn create nuxt-app frontApp

yarn create v1.22.4
[1/4] ??  Resolving packages...
[2/4] ??  Fetching packages...
[3/4] ??  Linking dependencies...
[4/4] ??  Building fresh packages...
warning Your current version of Yarn is out of date. The latest version is "1.22.5", while you're on "1.22.4".
info To upgrade, run the following command:
$ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash
success Installed "[email protected]" with binaries:
      - create-nuxt-app

create-nuxt-app v3.5.2
?  Generating Nuxt.js project in frontApp
? Project name: frontApp
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Continuous integration: None
? Version control system: Git

启动服务器一次,然后检查屏幕

myapp

1
2
$ cd frontApp
$ yarn run dev
  • 访问localhost:3000并检查以下屏幕后,使用命令C停止服务器

top.jpg

  • 容器启动时修改package.json

frontApp / package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "name": "frontApp",
  "version": "1.0.0",
  "private": true,
  "scripts": {
-   "dev": "nuxt-ts",
+   "dev": "HOST=0.0.0.0 PORT=3000 nuxt-ts",
    "build": "nuxt-ts build",
-   "start": "nuxt-ts start",
+   "start": "HOST=0.0.0.0 PORT=3000 nuxt-ts start",
    "generate": "nuxt-ts generate"
  },
  // 以下略
}

直接在laravel目录下创建一个Laravel项目

myapp

1
$ docker-compose run app composer create-project --prefer-dist laravel/laravel .

./ laravel目录下的结构如下是可以的。

myapp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ tree -a -L 1 laravel
laravel
├── .editorconfig
├── .env
├── .env.example
├── .gitattributes
├── .gitignore
├── .styleci.yml
├── README.md
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── package.json
├── phpunit.xml
├── public
├── resources
├── routes
├── server.php
├── storage
├── tests
├── vendor
└── webpack.mix.js

在后台启动容器

myapp

1
$ docker-compose up -d --build

Laravel配置文件缓存等

myapp

1
2
3
4
5
6
$ docker-compose exec app ash
$ php artisan -V   // バージョンが表示されればOK
$ php artisan config:cache
$ php artisan migrate
$ chmod -R a+rw storage/ bootstrap/cache
$ exit

屏幕检查

  • 再次访问本地主机:3000,如果显示TOP屏幕,则成功
    top.jpg

检查Nuxt和Laravel之间的通信

放在Laravel侧面

laravel /路线/ api.php

1
2
3
4
5
6
7
8
9
10
11
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
 * 中略
 */
+ Route::get('/', function () {
+    return 'Hello';
+ });

Nuxt侧面设置

myapp

1
2
$ cd frontApp
$ yarn add @nuxtjs/proxy @nuxtjs/dotenv

frontApp / nuxt.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
+ const environment = process.env.NODE_ENV || 'development'
+ require('dotenv').config()

export default {
// (中略)

  modules: [
    // https://go.nuxtjs.dev/axios
    '@nuxtjs/axios',
+   '@nuxtjs/proxy',
+   '@nuxtjs/dotenv',
  ],

+ proxy: {
+   '/api':
+     environment === 'development'
+       ? process.env.API_URL
+       : 'https://www.risk-exam.site',
+ },

+ axios: {
+   baseURL: process.env.API_URL,
+   browserBaseURL: process.env.API_BROWSER_URL,
+   credentials: true,
+ },

}

myapp / frontApp

1
$ touch .env

frontApp / .env

1
2
API_URL=http://web/api
API_BROWSER_URL=http://localhost:10080/api

frontApp /页面/ index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
  <div class="container">
    <div>
      <Logo />
      <h1 class="title">
         {{ greet }} // デフォルトの「frontApp」から変更
      </h1>
      <div class="links">
        <a
          href="https://nuxtjs.org/"
          target="_blank"
          rel="noopener noreferrer"
          class="button--green"
        >
          Documentation
        </a>
        <a
          href="https://github.com/nuxt/nuxt.js"
          target="_blank"
          rel="noopener noreferrer"
          class="button--grey"
        >
          GitHub
        </a>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  async asyncData({ app }): Promise<object> {
    const greet: string = await app.$axios.$get('/').catch((err) => err)
    return { greet }
  }
})
</script>
// 以下略
  • 访问localhost:3000,如果标题更改为Hello,则单击"确定"。

hello.jpg