Skip to content

部署

此页面介绍如何将 Dart 服务器应用程序部署到 Docker 容器中,避免常见问题。

准备项目

在将项目容器化之前,建议一些先决条件。

  1. 确保您在 prisma.schema 中使用所需的数据库提供程序。示例

    prisma
    datasource db {
      provider = "mysql"
    }
  2. 建议您将 DATABASE_URL 保留为环境变量,因为根据您的 docker-compose.yml(稍后讨论),硬编码的 DATABASE_URL 处的数据库可能无法被查询引擎访问。例如,如果您为数据库容器设置了自定义主机名。在应用程序的根目录中创建 .env 并将其作为规则添加到 .gitignore。此 .env 对于在本地机器上运行时生成应用程序的类是必需的

    env
    DATABASE_URL = "YOUR DATABASE URL TO USE ON LOCAL MACHINE"

    将其导入模式为

    prisma
    datasource db {
      provider = "mysql"
      url = env("DATABASE_URL")
    }
  3. .gitignore 中标记 Prisma 的输出目录。建议不要跟踪版本控制中的文件,因为 Prisma cli 会根据不同的 DATABASE_URL 重新生成它们。您可以选择生成文件的输出位置

    prisma
     generator client {
         provider = "dart run orm"
         output   = "../lib/src/prisma/generated"
     }

    然后将输出目录添加到 .gitignore

    gitignore
    /lib/src/prisma/generated

设置 Dockerfile

在应用程序的根目录中创建 Dockerfile

dockerfile
FROM dart:stable AS build

# Download npm to work with prisma within the build phase involving Dart
# We need it within "build" buildphase since the prisma cli needs Dart to be installed too to run "dart run orm"
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - &&\
    apt-get install -y nodejs

# Setting up the working directory of the container
WORKDIR /app

# Copying pubspec from the project (left side) into the working directory of the container
COPY ./pubspec.* ./
RUN dart pub get

# Copy the project source code into the working directory
COPY . ./

# Request DATABASE_URL as build-time environment variable because for prisma cli to read it
ARG DATABASE_URL

# Generate prisma-related files
RUN npm install prisma
RUN npx prisma generate

# Following code is specific to a server framework that you are using
# In the example below, it's dart frog
# Generate other Dart classes

# Dart frog build START
RUN dart pub run build_runner build

# Bundle the project
RUN dart pub global activate dart_frog_cli
RUN dart pub global run dart_frog_cli:dart_frog build

# Generate executable
RUN dart pub get --offline
RUN dart compile exe build/bin/server.dart -o build/bin/server

# Dart frog build END

# Configure runtime for prisma
RUN FILES="libz.so libgcc_s.so libssl.so libcrypto.so"; \
    for file in $FILES; do \
    so="$(find / -name "${file}*" -print -quit)"; \
    dir="$(dirname "$so")"; \
    mkdir -p "/runtime${dir}"; \
    cp "$so" "/runtime$so"; \
    echo "Copied $so to /runtime${so}"; \
    done

FROM scratch

# Copy runtime from previous build phase
COPY --from=build /runtime/ /

# Copy executable from the previous phase
COPY --from=build /app/build/bin/server /app/bin/

# [IMPORTANT] Copy executable the binary engine
COPY --from=build /app/prisma-query-engine /app/bin/

# [IMPORTANT] Specify which directory to run the server from
# It's important because prisma will need to discover the query engine referring to Directory.current
# Running it inside /app/bin/ will make Directory.current return "/app/bin/" so it can discover the query engine placed in the same directory
WORKDIR /app/bin/

# "ARG DATABASE_URL" is a dynamic build-phase env variable
# "ENV DATABASE_URL" is a environment variable for the container
# By default it's empty but we will provide it within docker-compose
ENV DATABASE_URL = ""

# Server application port
# Default is 8080
ENV PORT = 8080

# Execute the server executable
CMD ["/app/bin/server"]

设置 docker-compose.yml

yml
version: "3"
services:

  # Launch the db first
  my_database:
    container_name: my_database
    # [IMPORTANT] specify the host name so query engine can access the database referring to the host name
    hostname: myprojdb
    image: mysql:latest
    restart: unless-stopped
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: myPassword123
      MYSQL_DATABASE: mydbname
      MYSQL_USER: myusername
      MYSQL_PASSWORD: myPassword123

  # Launch this after
  my_dart_application:
    container_name: my_dart_application
    build:
      dockerfile: ./Dockerfile
      args:
        # This is needed for the prisma cli at the build phase
        # It's very important to use host name from the database container
        # Otherwise the query engine might not be able to access it
        - DATABASE_URL=mysql://myusername:myPassword123@myprojdb:3306/mydbname
    ports:
      - "8080:8080"
    environment:
      - PORT=8080
      - DATABASE_URL=mysql://myusername:myPassword123@myprojdb:3306/mydbname

networks:
  my_network:
    external: true

如何启动容器?

在第一次运行时,您只需要启动数据库容器。

  1. 运行数据库容器后。通过从项目的根目录执行以下命令来同步模式
    npx prisma db push
  2. 确保数据库模式已在数据库服务器上创建。

现在您可以使用您的 Dart 应用程序启动容器。

在 BSD-3-Clause 许可证下发布