I have 2 services in docker-compose.yml (here is excerpt; file mostly generated by Laravel Sail):
services:
laravel.test:
build:
context: .
dockerfile: ./docker/8.3/Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: 'sail-8.3/app'
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '800:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- pgsql
pgsql:
image: 'postgres:15'
ports:
- '${FORWARD_DB_PORT:-5432}:5432'
environment:
...
volumes:
- 'sail-pgsql:/var/lib/postgresql/data'
- './docker/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
networks:
- sail
networks:
sail:
driver: bridge
Referenced Dockerfile here contains the following lines near the end:
COPY --link . /var/www/html
WORKDIR /var/www/html
RUN php artisan migrate --seed
Unfortunately, migration ends with the error:
SQLSTATE[08006] [7] could not translate host name "pgsql" to address: Name or service not known
Service laravel.test
depends on pgsql
service, so it knows about it.
But Dockerfile in laravel.test
seems has another scope and cannot see service pgsql
, right?
Whether the way to make migration in docker exists?
Your laravel.test
container doesn't seem to be able to access the pgsql
service during the build phase because Docker's service discovery (i.e., how containers communicate via service names like pgsql
) only works once the containers are running. The build
process in a Dockerfile doesn't have access to the network of running services defined in docker-compose.yml
.
In your case, the migration command (php artisan migrate --seed
) is being executed during the build phase in the Dockerfile.
My suggestion is that you execute the migration happens after both containers are up and running.
You can follow an approach like this:
# Original lines
COPY --link . /var/www/html
WORKDIR /var/www/html
# RUN php artisan migrate --seed (remove this line)
docker-compose.yml
to run the migration after the services are up:services:
laravel.test:
...
depends_on:
- pgsql
command: >
sh -c "php artisan migrate --seed && php artisan serve --host=0.0.0.0 --port=8000"
pgsql:
...
With these changes, the Laravel service will run the migration automatically on startup and then continues to run the development server.
One key thing to note by the way:
Ensure that your application waits for the PostgreSQL service to be ready before running migrations. You can either use Laravel’s built-in retry mechanism for database connections, or a tool like dockerize
to wait for the PostgreSQL service before running the migration.