我有一个使用 PHP 开发的项目,我想将其移动到 Docker 容器中。我想在 Dockerfile 中自动导入数据库。如果我在构建容器后导入数据库,一切正常(
docker exec -it my-laravel-app bash
,然后mysql -u user -p1993 -h db bsp < /var/www/database/bsp.sql
)。
我收到错误
failed to solve: process "/bin/sh -c wait-for-it -t 30 ${DB_HOST}:${DB_PORT} if [ -f /var/www/database/bsp.sql ]; then mysql -u ${DB_USERNAME} -p${DB_PASSWORD} -h ${DB_HOST} ${DB_DATABASE} < /var/www/database/bsp.sql; fi" did not complete successfully: exit code: 2
。
Dockerfile
# Set the base image for subsequent instructions
FROM php:8.2-fpm
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
curl \
unzip \
git \
libzip-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
default-mysql-client \
wait-for-it \
libpng-dev && \
docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www
# Remove default server definition
RUN rm -rf /var/www/html
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www
# Change current user to www
USER www-data
ENV DB_HOST=db
ENV DB_PORT=3306
ENV DB_DATABASE=bsp
ENV DB_USERNAME=user
ENV DB_PASSWORD=1993
# Wait for the database to be ready and import SQL dump
USER root
RUN wait-for-it -t 30 ${DB_HOST}:${DB_PORT} \
if [ -f /var/www/database/bsp.sql ]; then \
mysql -u ${DB_USERNAME} -p${DB_PASSWORD} -h ${DB_HOST} ${DB_DATABASE} < /var/www/database/bsp.sql; \
fi
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
这是 RUN 指令的问题,更具体地说是其中的命令:
RUN wait-for-it -t 30 ${DB_HOST}:${DB_PORT} \
if [ -f /var/www/database/bsp.sql ]; then \
mysql -u ${DB_USERNAME} -p${DB_PASSWORD} -h ${DB_HOST} ${DB_DATABASE} < /var/www/database/bsp.sql; \
fi
我们可以看到,这些复合命令确实会导致退出代码 2。
这是一个语法错误的提示,因为在第一行中 wait-for-it 命令没有与后面的 if 分开。
插入分号“;”另外将 sh(1) shell 选项设置为 errexit (-e) 和 xtrace (-x) 以使其更直接:
RUN set -ex; \
wait-for-it -t 30 ${DB_HOST}:${DB_PORT}; \
if [ -f /var/www/database/bsp.sql ]; then \
mysql -u ${DB_USERNAME} -p${DB_PASSWORD} -h ${DB_HOST} ${DB_DATABASE} < /var/www/database/bsp.sql; \
fi
另外查看构建日志中是否有类似的消息
sh:意外标记“then”附近出现语法错误
或类似的。
Dockerfile 中还有一些其他草率的东西,请仔细检查 COPY 行,看起来您正在复制相同的文件两次。在将新功能添加到构建中之前,请先进行清理并将文件提交到版本控制。然后使用 Dockerfile 来处理事情就更容易了。