I have 4 Docker containers:
- php-fpm for Laravel API
- node for Next.js frontend
- mysql
- nginx
Until now I was using nginx only to serve the Laravel API for testing - so I can directly call the API with Postman, and the Next.js frontend pages (the node container) were accessed directly by the host via localhost:3000. But now I want nginx to serve the frontend Next.js project, and then the node container will call the Laravel API, but I still want to leave the testing server for Postman, so I added a second server block to my default.conf file, and adjusted the docker-compose.yml file but it broke everything, now nothing is working.
This was my setup (that worked) until now:
The docker-compose.yml:
networks:
laravel:
driver: bridge
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
volumes:
- ./laravel-api:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- mysql
- node
networks:
- laravel
mysql:
image: mysql
container_name: mysql
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- laravel
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./laravel-api:/var/www/html
ports:
- "9000:9000"
networks:
- laravel
node:
build:
context: ./nextjs
dockerfile: Dockerfile
container_name: next
volumes:
- ./nextjs:/var/www/html
ports:
- "3000:3000"
- "49153:49153"
networks:
- laravel
and nginx default.conf file:
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
So what is happening is that I access the node container directly on port 3000, and any call to the Laravel API is handled by nginx - redirecting requests from the host on port 8088 to the container of nginx on port 80.
What I tried to do was to add server block for reverse proxy from localhost:3000 to the nginx container like I do with the Laravel API calls:
This is the updated default.conf, added second server block:
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
server {
listen 80;
server_name nextjs;
access_log logs/nextjs.access.log main;
location /nextjs {
proxy_pass node:3000;
}
}
And adjusted the docker-compose.yml file:
networks:
laravel:
driver: bridge
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
- "3000:80"
volumes:
- ./nextjs:/var/www/html/nextjs
- ./laravel-api:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- mysql
- node
networks:
- laravel
mysql:
image: mysql
container_name: mysql
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- laravel
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./laravel-api:/var/www/html
ports:
- "9000:9000"
networks:
- laravel
node:
build:
context: ./nextjs
dockerfile: Dockerfile
container_name: next
volumes:
- ./nextjs:/var/www/html
ports:
- "49153:49153"
networks:
- laravel
I removed the port 3000 from the node container, and added to the nginx and mapped to the port 80 of the nginx container, so any requests to port 3000 from my host will be handled by port 80 of nginx - just like Laravel, so now both Laravel and Nextjs are redirected to port 80 on the nginx container (Again, I leave the Laravel server so I can test API directly from the host as well - and not only from the Next.js website)
Also, I created a link for the nextjs project on the nginx container: - ./nextjs:/var/www/html/nextjs
But now nothing works when I go to either localhost:3000 or localhost:8088 from my host