Docker环境下如何用localhost连接MariaDB(无需修改生产代码)
问题描述
我的docker-compose.yml配置如下:
version: '3' services: web: build: context: . dockerfile: './apache/Dockerfile' restart: always ports: - '8100:80' env_file: - ./env/db.env - ./env/modx.env volumes: - './public_html:/var/www/html' - './elements:/var/www/html/elements' db: image: 'mariadb:10.3.38' networks: - my-mariadb-net volumes: - ./db-data:/var/lib/mysql env_file: - ./env/db.env ports: - '3307:3306' command: mysqld --sql-mode=NO_ENGINE_SUBSTITUTION restart: always phpmyadmin: image: phpmyadmin/phpmyadmin environment: PMA_HOST: db PMA_PORT: 3306 PMA_ARBITRARY: 1 restart: always ports: - 8110:80
生产环境中,我用PHP连接MySQL的代码是:
$database_dsn = 'mysql:host=localhost;dbname=dbname;charset=utf8mb4';
我在Linux本地装了Docker,想复现生产环境配置且不用改代码。现在只能通过服务名db连接数据库,但希望用生产环境的localhost来连接,不担心安全风险(仅本地使用),求可行的实现方法。
解决方案
以下几种方法都能满足你的需求,根据自身情况选择:
方法一:修改数据库端口映射到本地3306
当前db服务把容器的3306端口映射到了本地3307,直接改成映射到本地3306端口即可。修改docker-compose.yml中db服务的ports配置:
ports: - '3306:3306'
修改后重启容器,PHP代码里的localhost就会直接访问本地3306端口,转发到容器内的MariaDB。注意如果本地已经有MySQL/MariaDB占用3306端口,需要先停止该服务。
方法二:让web容器使用主机网络模式
给web服务添加network_mode: host配置,这样容器内的网络和主机完全共享,容器里的localhost就等同于主机的localhost。修改后的web服务配置如下:
web: build: context: . dockerfile: './apache/Dockerfile' restart: always # 主机网络模式下不需要端口映射,直接用主机的80端口 # ports: # - '8100:80' env_file: - ./env/db.env - ./env/modx.env volumes: - './public_html:/var/www/html' - './elements:/var/www/html/elements' network_mode: host
同时确保db服务的端口映射是3306:3306,这样web容器内的PHP代码用localhost就能直接连接到数据库。
方法三:用socat做端口转发(适合本地3306被占用的情况)
如果本地3306端口被其他服务占用,不想停止它,可以用socat把本地3306端口转发到容器的3307端口:
socat TCP-LISTEN:3306,fork TCP:localhost:3307
运行这个命令后,本地3306的请求会转发到3307端口,PHP代码里的localhost就能正常连接容器内的数据库。可以把这个命令配置成系统服务,实现开机自动运行。
内容的提问来源于stack exchange,提问作者Maciej Koson
相关产品推荐
相关产品推荐

