How to configure NGINX to serve Directus to Nuxt 3 app in Docker container

218 Views Asked by At

I have a Docker container that runs 3 services: NGINX, Nuxt3, and Directus 10.8. I am struggling to get a reverse-proxy to work correctly. I can successfully map Nuxt to "/", but I'm hitting error when mapping Directus to any route (but for argument's sake let's say "/admin"). It appears to partially work at least, but Directus returns a load of errors: directus errors Nuxt isn't hot-reloading either, I guess I need to also reverse proxy port 24678 for Vite, but I'm unsure how to do that.

How do I expose Directus on "/admin" correctly and will that allow Nuxt to consume it (specifically with directus-nuxt)?

All services are contained in subfolders with their own docker-compose.yml files and the whole stack is run from a docker-compose.yml at root level:

/
|__docker-compose.yml
|__nuxt
| |__docker-compose.yml
| |__Dockerfile
| |__ # ...nuxt specific files
|__directus
| |__docker-compose.yml
| |__Dockerfile
| |__ # ...directus specific files
|__nginx
| |__Dockerfile
| |__default.conf

# /docker-compose.yml
version: "3"

include:
  - nuxt/docker-compose.yml
  - directus/docker-compose.yml

services:
  nginx:
    container_name: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - "80:80"
    depends_on:
      - nuxt
      - directus
    volumes:
      - ./nginx:/etc/nginx/conf.d
    networks:
      - stack

networks:
  stack:
# /nuxt/docker-compose.yml
version: "3"

volumes:
  node_modules:
services:
  nuxt:
    container_name: nuxt
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - "3001:3000"
      - "24678:24678"
    volumes:
      - .:/src
      - node_modules:/src/node_modules
    environment:
      - CHOKIDAR_USEPOLLING=true
    networks:
      - stack
# /directus/docker-compose.yml
version: "3"
services:
  directus:
    container_name: directus
    image: directus/directus:10.8.3
    ports:
      - 8055:8055
    volumes:
      - ./extensions:/directus/extensions
    environment:     
      PUBLIC_URL: "http://localhost:8055"
      # ...directus env variables - key, secret, db connection etc
    networks:
      - stack
# NGINX config
server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://nuxt:3000;
    }

    location /admin {
        proxy_pass http://directus:8055;
    }
}
1

There are 1 best solutions below

7
datawookie On

I have simplified your setup to get this working. You can generalise to your specific use case. In the interest of transparency, I know nothing about Directus, so I'm winging that part.

File layout for this to work would be:

├── docker-compose.yml
└── nginx
    └── nginx.conf

docker-compose.yml

version: "3"

services:
  nginx:
    container_name: nginx
    image: nginx
    ports:
      - "80:80"
    depends_on:
      - directus
    volumes:
      - ./nginx:/etc/nginx/conf.d
    networks:
      - stack

  directus:
    container_name: directus
    image: directus/directus:10.8.3
    volumes:
      - ./extensions:/directus/extensions
    environment:     
      PUBLIC_URL: "http://localhost:8055"
      ADMIN_EMAIL: "[email protected]"
      ADMIN_PASSWORD: "d1r3ctu5"
      KEY: "255d861b-5ea1-5996-9aa3-922530ec40b1"
      SECRET: "6116487b-cda1-52c2-b5b5-c8022c45e263"
    networks:
      - stack

networks:
  stack:

The environment variables appear to be essential to get the Directus container running happily.

You don't need to expose port 8055 since presumably you won't be accessing Directus on that port from the host.

nginx/nginx.conf

server {
    listen 80;
    server_name localhost;

    location /directus/ {
        proxy_pass http://directus:8055/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        add_header X-Cache $upstream_cache_status;

        proxy_connect_timeout 30s;
        proxy_read_timeout 86400s;
        proxy_send_timeout 30s;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

I've specified /directus/ as the location for the Directus service. You can choose anything here except /admin/ it would seem, presumably since that generates some sort of redirect loop (Directus already uses the /admin/ path). Somebody more knowledgeable about NGINX might advise here.

Go to http://127.0.0.1/directus/. You'll immediately be redirected to http://127.0.0.1/directus/admin/login.

enter image description here