我正在尝试对我的 Laravel 应用程序进行 docker 化。除了数据库连接之外,一切都工作正常。我的应用程序连接到只能通过堡垒服务器访问的 MySQL 数据库。
我已经实现了一个 SSH 隧道来访问数据库,当我手动运行隧道时它工作正常。我使用的命令是:
ssh -N -L 3306:{rds-host-link}:3306 -i {path to ssh key} -p 22 {user}@{ip}
当我在本地服务器上运行此隧道时,Laravel 连接正常,并且我在
DB_HOST=127.0.0.1
文件中设置了 .env
。
当我尝试对 SSH 隧道本身进行 docker 化时,问题就出现了。容器启动成功,但我的 Laravel 应用程序无法连接到数据库。
docker-compose.yml
文件使用 SSH 隧道和 PHP 容器进行设置,如下所示:
php:
build:
context: .
dockerfile: dockerfiles/php.dockerfile
volumes:
- ./src:/var/www/html:delegated
command: >
sh -c "php artisan migrate --force &&
php-fpm"
ssh-tunnel:
build:
context: .
dockerfile: dockerfiles/ssh-tunnel.dockerfile
volumes:
- ./ssh_keys/BastionKey.pem:/root/.ssh/id_rsa:ro
command: >
sh -c "apk add --no-cache openssh && ssh -i /root/.ssh/id_rsa -N -T -L 3333:{rds-host}:3306 {user}@{ip}"
FROM ubuntu:20.04
# Install necessary packages
RUN apt-get update && apt-get install -y \
openssh-client \
mysql-client \
&& rm -rf /var/lib/apt/lists/*
# Copy the SSH private key into the container (for testing purposes)
# Use volumes for production
COPY ssh_keys/BastionKey.pem /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa
# Set up SSH config
RUN echo "Host *\n StrictHostKeyChecking no\n UserKnownHostsFile=/dev/null" > /root/.ssh/config
FROM php:8.1-fpm-alpine
WORKDIR /var/www/html
# Copy application source code
COPY src .
# Install dependencies
RUN apk add --no-cache \
imap-dev \
openssl-dev \
&& docker-php-ext-configure imap --with-imap --with-imap-ssl \
&& docker-php-ext-install pdo pdo_mysql imap
# Add a non-root user for Laravel
RUN addgroup -g 1000 laravel && adduser -G laravel -g laravel -s /bin/sh -D laravel
USER laravel
ssh-tunnel
容器启动成功,但Laravel应用程序无法连接到数据库并抛出以下错误:
Illuminate\Database\QueryException
SQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select table_name as `name`, (data_length + index_length) as `size`, table_comment as `comment`, engine as `engine`, table_collation as `collation` from information_schema.tables where table_schema = 'rio_plus_uat' and table_type in ('BASE TABLE', 'SYSTEM VERSIONED') order by table_name)
我尝试在
DB_HOST=host.docker.internal
文件中设置.env
,但仍然不起作用。这些容器在同一网络中运行,我可以确认在本地服务器上手动运行时 SSH 隧道工作正常。
我之前只使用 docker-compose yml 做过类似的事情。
version: '3'
services:
mysql:
image: alpine:latest
command: sh -c "apk update && apk add openssh-client && while true; do ssh -i ~/.ssh/secretkey.pem -nNT -L *:3306:<server_host>:<server_port> user@ip; done"
volumes:
- ~/.ssh:/root/.ssh:ro
expose:
- 3306
确保使用
mysql
作为数据库连接的服务器名称。
并且您需要将 mysql-client 安装到您的 laravel 应用程序 docker 容器中。