magento2 icon indicating copy to clipboard operation
magento2 copied to clipboard

[Bug]: VSF2 not working with docker-compose

Open drew-webscale opened this issue 3 years ago • 12 comments

Expected Behavior

A working Vue Storefront application on port 3000 of my local machine.

Actual Behavior

No responses when visiting http://localhost:3000/ or https://localhost:3000/.

Possible Solution

I am not sure, seems like maybe the nuxt server is not getting started with the right binding to 0.0.0.0.

Steps to reproduce

Dockerize the Vue Storefront application and then attempt to start it with docker-compose. Here is the Dockerfile:

FROM node:16

WORKDIR /var/www

COPY . .

RUN yarn install

RUN yarn build && yarn cache clean --all

EXPOSE 3000

CMD ["yarn","start"]

Here is the docker-compose.yml:

version: "3"

services:
    nginx:
        image: nginx:1.21.6
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./config/nginx.conf:/etc/nginx/conf.d/default.conf:ro
            - type: bind
              source: ./certs/magento.test.crt
              target: /etc/ssl/certs/magento.test.crt
            - type: bind
              source: ./certs/magento.test.key
              target: /etc/ssl/private/magento.test.key
            - type: bind
              source: ./pub/static
              target: /var/www/shared/magento.test/pub/static
            - type: bind
              source: ./pub/media
              target: /var/www/shared/magento.test/pub/media
        links:
            - magento

    magento:
        image: magento:2.4.4
        env_file: env/phpfpm.env
        ports:
            - "9000:9000"
        volumes:
            - ./pub/static:/var/www/html/pub/static
            - ./pub/media:/var/www/html/pub/media
            - ./app:/var/www/html/app
            - ./composer.json:/var/www/html/composer.json
            - ./composer.lock:/var/www/html/composer.lock
            - ./config/ssmtp.conf:/etc/ssmtp/ssmtp.conf:ro
        depends_on:
            - redis
            - mailcatcher
        links:
            - elasticsearch
            - mailcatcher
    
    vuesf:
        image: vue-storefront:2
        volumes:
            - ./certs/localhost.pem:/var/www/localhost.pem:ro
            - ./certs/localhost-key.pem:/var/www/localhost-key.pem:ro
        env_file: env/vue.env
        ports:
            - "3000:3000"
        depends_on:
            - redis
            - nginx
        links:
            - nginx
    
    db:
        image: mariadb:10.4.13
        command: --max_allowed_packet=64M
        ports:
            - "3306:3306"
        env_file: env/db.env
        volumes:
            - dbdata:/var/lib/mysql

    redis:
        image: redis
        ports:
            - "6379:6379"

    elasticsearch:
        image: elasticsearch:7.16.3
        environment:
          - cluster.name=docker-cluster
          - bootstrap.memory_lock=true
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
          - node.name=node-1
          - cluster.initial_master_nodes=node-1
        ulimits:
          memlock:
            soft: -1
            hard: -1
        ports:
          - 9200:9200

    rabbitmq:
        image: rabbitmq:3.9.20-management-alpine
        ports:
            - "15672:15672"
            - "5672:5672"
        volumes:
            - rabbitmqdata:/var/lib/rabbitmq
        env_file: env/rabbitmq.env

    mailcatcher:
        image: mailhog/mailhog
        ports:
            - "8025:8025"

volumes:
  dbdata:
  rabbitmqdata:

What version of Magento 2 integration are you using?

2.4.4

What version of Node.js are you using?

16

What browser (and version) are you using?

Chrome Version 103.0.5060.134 (Official Build) (arm64)

What operating system (and version) are you using?

macOS Monterey 12.2.1

Relevant log output

Here are the logs from the Vue Storefront Docker container when it starts:

(node:1) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)

> @vue-storefront/[email protected] start
> nuxt start --modern=client


 WARN  extractCSS cannot work with parallel build due to limited work pool in thread-loader

ℹ Middleware starting....
ℹ VSF Helmet middleware added
ℹ Loading integrations...
ℹ - Loading: magento @vue-storefront/magento-api/server
✔ - Integration: magento init function Start!
✔ - Integration: magento init function Done!
ℹ - Loading: magento extension: tokenExtension
✔ - Integration: magento loaded!
✔ Integrations loaded!
✔ Middleware created!
ℹ Listening on: https://localhost:3000/

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

drew-webscale avatar Jul 21 '22 15:07 drew-webscale

FWIW I had this working okay with rc10 so something about the newest version seems to be causing the issue. Also, I can run the same codebase locally and it works but if I try to run it in a Docker container it does not.

drew-webscale avatar Jul 21 '22 15:07 drew-webscale

Can you please post the .env file you're building the container with (blur out secrets if you need)

There's a new VSF_MIDDLEWARE_URL env var due to the new VSF core version aswell https://github.com/vuestorefront/magento2/blob/develop/packages/theme/.env.example#L5 though this should fallback to just http://localhost:3000/api if not set

sethidden avatar Jul 22 '22 11:07 sethidden

For sure! I updated the env file also when testing. Here's what I am using for the Docker setup:

VSF_NUXT_APP_ENV=development
VSF_NUXT_APP_PORT=3000

VSF_STORE_URL=https://localhost:3000
VSF_MIDDLEWARE_URL=https://localhost:3000/api/
VSF_MAGENTO_BASE_URL=magento.test
VSF_MAGENTO_GRAPHQL_URL=https://nginx/graphql

VSF_MAGENTO_EXTERNAL_CHECKOUT_ENABLED=false
VSF_MAGENTO_EXTERNAL_CHECKOUT_URL=https://magento.test
VSF_MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH=/vue/cart/sync

VSF_IMAGE_PROVIDER=ipx
VSF_IMAGE_PROVIDER_BASE_URL=https://res-4.cloudinary.com/{YOUR_ID}/image/upload/
VSF_IMAGE_PROVIDER_DOMAIN=https://res-4.cloudinary.com

VSF_REDIS_ENABLED=true
VSF_REDIS_HOST=redis
VSF_REDIS_PORT=6379
VSF_REDIS_KEY_PREFIX=
VSF_REDIS_CACHE_INVALIDATE_URL=/cache-invalidate

VSF_RECAPTCHA_ENABLED=false
VSF_RECAPTCHA_SITE_KEY=
VSF_RECAPTCHA_SECRET_KEY=
VSF_RECAPTCHA_HIDE_BADGE=
VSF_RECAPTCHA_SIZE=invisible
VSF_RECAPTCHA_MIN_SCORE=0.5
VSF_RECAPTCHA_VERSION=3

NODE_TLS_REJECT_UNAUTHORIZED=0

drew-webscale avatar Jul 22 '22 14:07 drew-webscale

hello @drew-webscale ,

I have the same problem with Docker and my configuration is quite similar to yours. Did you find any solution or workaround to fix this problem ?

jeromecx avatar Aug 01 '22 12:08 jeromecx

Hi @jeromecx ,

I have not gotten this to work yet :(

drew-webscale avatar Aug 01 '22 15:08 drew-webscale

Hey guys! Try to remove VSF_MIDDLEWARE_URL=

and remove a default value from nuxt.config.js

replace this

publicRuntimeConfig: {
  middlewareUrl: process.env.VSF_MIDDLEWARE_URL || 'http://localhost:3000/api/',
},

with this

publicRuntimeConfig: {
  middlewareUrl: process.env.VSF_MIDDLEWARE_URL,
},

sequensucks avatar Aug 03 '22 06:08 sequensucks

Hello and thank you @sequensucks for your help, we will try this today !

jeromecx avatar Aug 03 '22 08:08 jeromecx

Hello Thanks for your reply @sequensucks Same issue here, with a similar config I tried this solution, but looks like nothing changed In the starting logs, I now have the info : "✔ Applied middlewareUrl as https://localhost:3000/api", but I still can't connect I'll try to investigate more on this

aagez avatar Aug 03 '22 14:08 aagez

You try to connect from container nginx to localhost:3000/api. But your api in a vuesf container You need a same network for it. I can't test it now. But i can try to help with a config and you will test it solution. Try to add to bottom of your docker-compose.yml

networks:
  vue-network:
    driver: bridge
    attachable: true
    external: false

And add networks for a nginx container and a vuesf container. Like this

networks:
      - vue-network

sequensucks avatar Aug 03 '22 15:08 sequensucks

I tried the update to nuxt.config.js and removing that environment variable so I now get this in the Vue container logs:

yarn run v1.22.19
$ nuxt start --modern=client

 WARN  extractCSS cannot work with parallel build due to limited work pool in thread-loader

ℹ Middleware starting....
ℹ VSF Helmet middleware added
ℹ Loading integrations...
ℹ - Loading: magento @vue-storefront/magento-api/server
✔ - Integration: magento init function Start!
✔ - Integration: magento init function Done!
ℹ - Loading: magento extension: tokenExtension
✔ - Integration: magento loaded!
✔ Integrations loaded!
✔ Middleware created!
✔ Applied middlewareUrl as  https://localhost:3000/api
ℹ Listening on: https://localhost:3000/

I tied updating the docker-compose.yml with that network info. I had to add the network to all the containers so they could communicate. I still get ERR_CONNECTION_CLOSED on the Vue app. Here's my new docker-compose.yml:

version: "3"

services:
    nginx:
        image: nginx:1.21.6
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./config/nginx.conf:/etc/nginx/conf.d/default.conf:ro
            - type: bind
              source: ./certs/magento.test.crt
              target: /etc/ssl/certs/magento.test.crt
            - type: bind
              source: ./certs/magento.test.key
              target: /etc/ssl/private/magento.test.key
            - type: bind
              source: ./pub/static
              target: /var/www/shared/magento.test/pub/static
            - type: bind
              source: ./pub/media
              target: /var/www/shared/magento.test/pub/media
        links:
            - magento
        networks:
            - vue-network

    magento:
        image: magento:2.4.4
        env_file: env/phpfpm.env
        ports:
            - "9000:9000"
        volumes:
            - ./pub/static:/var/www/html/pub/static
            - ./pub/media:/var/www/html/pub/media
            - ./app:/var/www/html/app
            - ./composer.json:/var/www/html/composer.json
            - ./composer.lock:/var/www/html/composer.lock
            - ./config/ssmtp.conf:/etc/ssmtp/ssmtp.conf:ro
        depends_on:
            - redis
            - mailcatcher
        links:
            - elasticsearch
            - mailcatcher
        networks:
            - vue-network
    
    vuesf:
        image: vue-storefront:2
        volumes:
            - ./certs/localhost.pem:/var/www/localhost.pem:ro
            - ./certs/localhost-key.pem:/var/www/localhost-key.pem:ro
        env_file: env/vue.env
        ports:
            - "3000:3000"
        depends_on:
            - redis
            - nginx
        links:
            - nginx
        networks:
            - vue-network
    
    db:
        image: mariadb:10.4.13
        command: --max_allowed_packet=64M
        ports:
            - "3306:3306"
        env_file: env/db.env
        volumes:
            - dbdata:/var/lib/mysql
        networks:
            - vue-network

    redis:
        image: redis
        ports:
            - "6379:6379"
        networks:
            - vue-network

    elasticsearch:
        image: elasticsearch:7.16.3
        environment:
          - cluster.name=docker-cluster
          - bootstrap.memory_lock=true
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
          - node.name=node-1
          - cluster.initial_master_nodes=node-1
        ulimits:
          memlock:
            soft: -1
            hard: -1
        ports:
          - 9200:9200
        networks:
            - vue-network

    rabbitmq:
        image: rabbitmq:3.9.20-management-alpine
        ports:
            - "15672:15672"
            - "5672:5672"
        volumes:
            - rabbitmqdata:/var/lib/rabbitmq
        env_file: env/rabbitmq.env
        networks:
            - vue-network

    mailcatcher:
        image: mailhog/mailhog
        ports:
            - "8025:8025"
        networks:
            - vue-network

volumes:
  dbdata:
  rabbitmqdata:

networks:
  vue-network:
    driver: bridge
    attachable: true
    external: false

drew-webscale avatar Aug 03 '22 17:08 drew-webscale

The same here, it still doesn't work

jeromecx avatar Aug 04 '22 12:08 jeromecx

Any updates on this? It doesn't work in docker-compose.yml nor does it work if I run it this way as just a single container:

docker run -d -v $(pwd)/.env:/var/www/.env -p 3000:3000 vue-storefront:2

The container starts and says it is listening but nothing will load on localhost:3000:

yarn run v1.22.19
$ nuxt start --modern=client

 WARN  extractCSS cannot work with parallel build due to limited work pool in thread-loader

ℹ Middleware starting....
ℹ VSF Helmet middleware added
ℹ Loading integrations...
ℹ - Loading: magento @vue-storefront/magento-api/server
✔ - Integration: magento init function Start!
✔ - Integration: magento init function Done!
ℹ - Loading: magento extension: tokenExtension
✔ - Integration: magento loaded!
✔ Integrations loaded!
✔ Middleware created!
ℹ Listening on: https://localhost:3000/

drew-webscale avatar Aug 12 '22 17:08 drew-webscale

Hello

Little update on this After some investigation, we discovered that VSF is reachable from the INSIDE of the container, but we have to add /default to the URL for VSF to respond :

/var/www/html $ curl --insecure https://localhost:3000/default
<!doctype html>
// Lots of html stuffs, looks like the homepage
/var/www/html $

Without appending /default, VSF react, we can see hits on Magento Graphql in the logs, but there's no response from VSF

/var/www/html $ curl --insecure https://localhost:3000/
/var/www/html $ 

However, from the outside of the container, still the same result : no response and no hit visible in the logs

$ curl --insecure https://localhost:3000/default
curl: (35) Encountered end of file
$

It does looks like a docker-compose problem, but I still can't figure it out. Hope this can bring ideas

I tried @sequensucks solution about the network, didn't change anything

aagez avatar Aug 18 '22 09:08 aagez

Hello @drew-webscale,

I found the issue. The problem is that at the very end of nuxt.config.js, there is a conditional SSL setup. Unfortunately, instead of merging it replaces the server configuration. So, for now, you have either fix the logic inside to merge the server config or add variables inside of the Dockerfile. In nuxt.config.js

if (process.env.NODE_ENV === 'development' || process.env.VSF_NUXT_APP_ENV === 'development') {
    baseConfig.server = {
      ...baseConfig.server, 
      https: {
        key: fs.readFileSync(path.resolve(__dirname, 'localhost-key.pem')),
        cert: fs.readFileSync(path.resolve(__dirname, 'localhost.pem')),
      },
    };
  }

In Dockerfile

ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000

bartoszherba avatar Aug 18 '22 09:08 bartoszherba

Hello @bartoszherba

Thanks a lot, tried it, it works :)

aagez avatar Aug 18 '22 09:08 aagez