skip to Main Content

I was recently hired on a website development project and I am having trouble deploying it via docker on MacOS. I just can’t connect to the frontend via localhost:8000.
I have temporarily solved this problem by running docker in a virtual machine (Ubuntu), but some things are not working correctly due to this connection.

What are the ways to solve this problem?

Here is the config in dockerfiles:

Dockerfile (frontend)

# pull official base image
FROM node:12-alpine as build


# create and set working directory
WORKDIR /app
# install app dependencies
RUN mkdir frontend
COPY package.json ./frontend/
COPY package-lock.json ./frontend/
COPY frontend_healthchecker.sh ./frontend/
RUN chmod +x /app/frontend/frontend_healthchecker.sh

RUN ls
RUN cd frontend && ls
RUN cd frontend && npm install --only=prod
# RUN cd frontend && npm install --scripts-prepend-node-path=auto

# add app code
COPY . ./frontend/
RUN cd frontend && ls

# start app
RUN cd frontend && npm install && npm run build

FROM nginx:1.16.0-alpine
COPY --from=build /app/frontend/build /usr/share/nginx/html
COPY --from=build /app/frontend/nginx/default.conf /etc/nginx/conf.d/default.conf

COPY --from=build /app/frontend/frontend_healthchecker.sh /home
RUN chmod +x /home/frontend_healthchecker.sh
RUN apk add curl
RUN apk search curl
HEALTHCHECK CMD ["/bin/sh", "/home/frontend_healthchecker.sh"]

EXPOSE  8000

CMD ["nginx", "-g", "daemon off;"]

Dockerfile (backend)

FROM node:12
ENV TZ=Europe/Moscow
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

#install ffmpeg
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y ffmpeg
RUN apt-get install -y mediainfo

RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y python-pip
RUN pip --version
RUN pip install numpy
RUN pip install opencv-contrib-python
RUN pip install urllib3

WORKDIR /app

COPY . /app
COPY backend_healthchecker.sh /app
RUN chmod +x backend_healthchecker.sh

RUN ls
RUN npm install

EXPOSE 8080

WORKDIR /app/bin

HEALTHCHECK CMD ../backend_healthchecker.sh
ENTRYPOINT ["node"]

CMD ["www"]

docker-compose.yaml

version: '3.3'
services:
    kurento:
        network_mode: "host"
        build:
            context: ./kurento
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
            - static-content:/tmp
        container_name: p_kurento
        environment:
            - GST_DEBUG=2,Kurento*:5
    mongo:
        network_mode: "host"
        image: mongo:latest
        restart: always
        container_name: p_mongo
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
            - db-content:/data/db
        healthcheck:
            test: mongo localhost:27017/test | mongo show dbs
            interval: 1m
            timeout: 15m
            retries: 5
    backend:
        network_mode: "host"
        env_file:
            - ./backend/.env
        build:
            context: ./backend
        container_name: p_backend
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
            - static-content:/files
    frontend:
        network_mode: "host"
        env_file:
            - ./frontend/.env
        build:
            context: ./frontend
        container_name: p_frontend
        volumes: 
            - "/etc/timezone:/etc/timezone:ro"
            - "/etc/localtime:/etc/localtime:ro"
    coturn:
        network_mode: "host"
        build:
            context: ./stun
        container_name: p_turn

    portainer:
        #network_mode: "host"
        restart: always
        image: portainer/portainer
        command: --admin-password=somepassword -H unix:///var/run/docker.sock
        ports:
            - "9000:9000"
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
        container_name: portainer

volumes:
  static-content:
  db-content:

2

Answers


  1. network_mode: host doesn’t work on MacOS or Windows systems. The Docker Use host networking documentation notes:

    The host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server.

    It also essentially entirely disables Docker’s networking stack, and is almost never necessary.

    You need to do three things here:

    1. Remove all of the network_mode: host lines from the Compose file. (The container_name: lines are also unnecessary.)
    2. For any of the services you need to access from outside Docker (could be all of them and that’s fine) add ports: to publish their container ports.
    3. When any of these services internally call other services configure their URLs (for example, in the .env files) to use their Compose service names. (See Networking in Compose in the Docker documentation.) (Also note that your frontend application probably actually runs in a browser, even if the code is served from a container, and can’t use these host names at all; this specific point needs to still use localhost or the host name where the system will eventually be deployed.)

    So, for example, the setup for the frontend and backend containers could look like:

    version: '3.8'
    services:
      mongo: { ... }
      backend:
        # no network_mode: host or container_name:
        # if this needs to be accessed from the browser application
        ports:
          - '8080:8080'
        # probably actually put this in .env
        environment:
          - MONGO_HOST=mongo
        # unchanged from the original
        env_file:
          - ./backend/.env
        build:
          context: ./backend
        volumes: 
          - "/etc/timezone:/etc/timezone:ro"
          - "/etc/localtime:/etc/localtime:ro"
          - static-content:/files
      frontend:
        ports:
          - '8000:8000'
        environment:
          - BACKEND_URL=http://localhost:8080 # as would be seen from the browser
        env_file:
          - ./frontend/.env
        build:
          context: ./frontend
        volumes: 
          - "/etc/timezone:/etc/timezone:ro"
          - "/etc/localtime:/etc/localtime:ro"
    
    Login or Signup to reply.
  2. You can try to create a loopback address and use that instead of default localhost.

    Steps:

    1. create a file named loopback-alias.plist in your current directory and use the below content
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist>
    <plist version="1.0">
      <dict>
        <key>Label</key>
        <string>loopback-alias</string>
        <key>ProgramArguments</key>
        <array>
          <string>/sbin/ifconfig</string>
          <string>lo0</string>
          <string>alias</string>
          <string>10.200.10.1</string>
          <string>netmask</string>
          <string>255.255.255.0</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
      </dict>
    </plist>

    You can change the loop-back address.

    1. Copy the file to /Library/LaunchDaemons/
    2. Restart your network
    3. Sample code to use this in Docker-compose
    redis:
        image: redis
        expose: 
            - '6379'
        ports: 
            - '10.200.10.1:6379:6379'
        extra_hosts: 
            - 'localhost:10.200.10.1'

    You can check the following link for more details.
    https://blog.sbaranidharan.online/index.php/2021/05/05/docker-macos-expose-container-ports-to-host-machine/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search