API Platform version(s) affected: 3.2
I try to run api platform on production without database service on docker, because I want to use a local database. I start the project with the command provided in api platform docs, bu I run it with a specific compose.yaml and a compose.prod.yaml. I added to compose.prod.yaml file `network_mode: "host"` so I bring to the container the same networking as my host.
But when I run the project, I get this error :
"duration":0.013162129
"err_id":"y7f98si24"
"err_trace":"reverseproxy.statusError (reverseproxy.go:1267)"
"level":"error"` "logger":"http.log.error.log0"
"msg":"dial tcp: lookup pwa on 212.227.123.16:53: no such host"
From what I understand, it doesn't find pwa host. I can't understand why.
I run this command to starting api platform on production :
SERVER_NAME=preprod.website.fr
APP_SECRET=a_secret_key
CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey
docker compose -f compose.yaml -f compose.prod.yaml up --wait
compose.yaml :
services:
php:
image: ${IMAGES_PREFIX:-}app-php
restart: unless-stopped
environment:
PWA_UPSTREAM: pwa:3000
SERVER_NAME: ${SERVER_NAME:-localhost}, php:80
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercure>
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercur>
TRUSTED_PROXIES: ${TRUSTED_PROXIES:-127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,>
TRUSTED_HOSTS: ^${SERVER_NAME:-example\.com|localhost}|php$$
DATABASE_URL: mysql://${MARIADB_USER:-myuser}:${MARIADB_PASSWORD>
MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure}
MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure
MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTS>
volumes:
- caddy_data:/data
- caddy_config:/config
ports:
# HTTP
- target: 80
published: ${HTTP_PORT:-80}
protocol: tcp
# HTTPS
- target: 443
published: ${HTTPS_PORT:-443}
protocol: tcp
# HTTP/3
- target: 443
published: ${HTTP3_PORT:-443}
protocol: udp
pwa:
image: ${IMAGES_PREFIX:-}app-pwa
environment:
NUXT_PUBLIC_ENTRYPOINT: http://php
# Mercure is installed as a Caddy module, prevent the Flex recipe from installi>
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###
volumes:
caddy_data:
caddy_config:
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###
compose.prod.yaml :
# Production environment override
services:
php:
build:
context: ./api
target: frankenphp_prod
environment:
APP_SECRET: ${APP_SECRET}
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
DATABASE_URL: mysql://${MARIADB_USER:-myuser}:${MARIADB_PASSWORD:-mypassword}@127.0.0.1:3306/${MARIADB_DATABASE:-mydatabase}?serverVersion=mariadb-${MARIADB_VERSION:-10.11>
network_mode: "host"
pwa:
build:
context: ./pwa
target: prod
vector:
container_name: vector
image: timberio/vector:0.34.0-alpine
restart: always
volumes:
- ./vector.yaml:/etc/vector/vector.yaml
- /var/run/docker.sock:/var/run/docker.sock:ro
2024/10/01 UPDATE:
Following this article https://dev.to/mjnaderi/accessing-host-services-from-docker-containers-1a97 I was able to solve my problem. Here's my compose.prod.yaml updated:
proxy-relay:
image: alpine/socat:latest
network_mode: host
command: TCP-LISTEN:3306,fork,bind=host.docker.internal TCP-CONNECT:127.0.0.1:3306
extra_hosts:
- host.docker.internal:host-gateway
php:
build:
context: ./api
target: frankenphp_prod
environment:
APP_SECRET: ${APP_SECRET}
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
DATABASE_URL: mysql://${MARIADB_USER:-myuser}:${MARIADB_PASSWORD:-mypassword}@host.docker.internal:3306/${MARIADB_DATABASE:-mydatabase}?serverVersion=mariadb-${MARIADB_VERSION:-10.11.6}&charset=utf8mb4
extra_hosts:
- host.docker.internal:host-gateway
network_mode: host
disables Docker's networking layer. It's almost never necessary, and if you need it then it either suggests your program shouldn't run in a container (because it's trying to manage the host's network interfaces) or is missing network configuration. You should delete this line.
In particular, where the base Compose file sets PWA_UPSTREAM: pwa:3000
, using host networking disables Docker's inter-container DNS and the pwa
host name won't work. The base Compose file also has the ports:
setting that you'd need to make the container reachable from outside Docker.
The one thing in the configuration that isn't likely to work is the DATABASE_URL: ...127.0.0.1...
setting. The best approach here is to add the database as an additional container
services:
db:
image: mariadb:${MARIADB_VERSION:-10.11}
environment:
MARIADB_USER:
MARIADB_PASSWORD:
MARIADB_DATABASE:
MARIADB_RANDOM_ROOT_PASSWORD: "true"
volumes:
- mariadb_data:/var/lib/mysql
php:
...
environment:
DATABASE_URL: mysql://${MARIADB_USER:-myuser}:${MARIADB_PASSWORD:-mypassword}@db:3306/${MARIADB_DATABASE:-mydatabase}?serverVersion=mariadb-${MARIADB_VERSION:-10.11>
# database container name, not 127.0.0.1 ^^
volumes:
mariadb_data:
It's also possible to use a database that exists only on the host machine, though this will be harder to reproduce in other environments; see From inside of a Docker container, how do I connect to the localhost of the machine? for the host names and the setups you can use (again, you usually should not set network_mode:
).