Context
I have two dockerized apps, one contains the frontend (Sveltekit) and one contains the backend API (Laravel). Both apps are on their own directory and contain separate docker-compose
files. There's a docker-compose
for the frontend app and a docker-compose
for the backend API app. So far, while testing I simply run my frontend app locally (not in a container) and was able to fetch data from the API which was running on a container.
ProblemThe problem I encountered first was when I tried to use the dockerized version of the frontend app. The container built correctly and the UI loaded but it can't fetch data from the API since the API lives in a different container. Remember, both apps have their own docker-compose
file so for each app I run docker-compose up --build
. It makes sense that I cannot access the backend API from the frontend container, after all I guess they are in different networks.So I tried to get rid of the docker-compose
file in my frontend project and simply create a service in the docker-compose
that belongs to the backend to load the frontend by referencing the existing Dockerfile
that belongs to the frontend project. When running:docker-compose up --build
the build seems to be successful (no errors) but now I cannot access the frontend via the URL.
What's going on?
Here's the frontend's Dockerfile
:
# Dockerfile# base stageFROM node:21-alpine AS baseWORKDIR /app# copy everythingCOPY . .# install dependenciesRUN npm install# ----------------------------------------------------------FROM base AS dev# Set the Node environment to development to ensure all packages are installedENV NODE_ENV developmentEXPOSE 5137CMD ["npm", "run", "dev"]# ----------------------------------------------------------FROM base AS build# build the appRUN npm run build# run stage, to separate it from the build stage, to save disk storageFROM node:21-alpine AS prodWORKDIR /app# Set the Node environment to development to ensure all packages are installedENV NODE_ENV production# copy stuff from the build stageCOPY --from=build /app/package*.json ./COPY --from=build /app/build ./build# expose the app's portEXPOSE 3000# run the serverCMD ["node", "./build/index.js"]
And here's the docker-compose
file:
version: "3.9"services: app: build: context: ./ dockerfile: Dockerfile image: dmc container_name: dmc-app restart: unless-stopped working_dir: /var/www/ depends_on: - db - nginx volumes: - ./:/var/www/ - ./docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - ./docker/php/conf.d/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini - ./images:/public/images expose: - "9003" networks: - dmc-net nginx: image: nginx:1.23.2-alpine container_name: dmc-nginx restart: unless-stopped ports: - "8000:80" volumes: - ./:/var/www - ./docker-compose/nginx:/etc/nginx/conf.d networks: - dmc-net supervisor: image: dmc container_name: dmc-supervisor networks: - dmc-net depends_on: - app - nginx command: - supervisord db: image: mysql:8.0.31 container_name: dmc-db restart: unless-stopped # using 3307 on the host machine to avoid collisions in case there's a local MySQL instance installed already. ports: - "3307:3306" # use the variables declared in .env file environment: MYSQL_HOST: ${DB_HOST} MYSQL_DATABASE: ${DB_DATABASE} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_ROOT_PASSWORD: abcd1234 MYSQL_USER: ${DB_USERNAME} SERVICE_TAGS: dev SERVICE_NAME: mysql volumes: - ./docker-compose/mysql:/docker-entrypoint-initdb.d - mysql-data:/var/lib/mysql networks: - dmc-net dmc-web: build: context: . dockerfile: /Users/hansgruber/Desktop/webdev/projects/dundermifflin-ui/Dockerfile target: dev container_name: dmc-web restart: always ports: - "5173:5173" volumes: # it avoids mounting the workspace root # because it may cause OS specific node_modules folder # or build folder(.svelte-kit) to be mounted. # they conflict with the temporary results from docker space. # this is why many mono repos utilize ./src folder - ./src:/app/src - ./static:/app/app/static - ./static:/app/static/ depends_on: - app - nginx - db networks: - dmc-netnetworks: dmc-net: driver: bridgevolumes: mysql-data:
I don't see any port collision and the service also uses the same network.
Any idea what's wrong?
Initially I thought it was perhaps a CORS issue or something like that, but I'd expect to see any output in the console when attempting to access http://localhost:5173/
which is the URL displayed in the build output:
dmc-web | dmc-web | > devdmc-web | > vitedmc-web | dmc-web | dmc-web | VITE v3.2.1 ready in 403 msdmc-web | dmc-web | ➜ Local: http://localhost:5173/dmc-web | ➜ Network: use --host to exposedmc-web | dmc-web | LARAVEL v9.40.1 plugin v0.5.4dmc-web | dmc-web | ➜ APP_URL: http://localhost