How to use Laravel docker container & MySQL DB with a Vue one?

Viewed 7718

I have an app which uses Vue CLI as a front-end and Laravel as a back-end. Now I am trying to launch my app on a server using docker.

My docker skills can only allow me one thing: Vue docker container. But as far as I have to use Laravel as a back-end I have to create a container for that too (+ MySQL, of course).

So here what I've got: Dockerfile

FROM node:lts-alpine
WORKDIR /app
COPY package*.json ./
RUN  npm install
EXPOSE 8080
CMD ["npm", "run", "serve"]

docker-compose.yml

version: '3'
services:
    web:
        build: .
        stdin_open: true
        tty: true
        ports: 
            - "8080:8080"
        volumes:
            - "/app/node_modules" 
            - ".:/app"

The problem is that I understand how to connect Laravel into Dockerfile. It just doesn't add up in my mind.

May be I should use Ubuntu, not just node? Anyways, I'm asking once again for your support

2 Answers

According to this article you will need to follow the steps below.

  1. Make your project folder look like this: (d: directory, f: file)
d: backend
d: frontend
d: etc
    d: nginx
        d: conf.d
            f: default.conf.nginx
    d: php
        f: .gitignore
    d: dockerize
        d: backend
            f: Dockerfile
f: docker-compose.yml
  1. Add docker-compose.yml
    version: '3'
    services:
    www:
        image: nginx:alpine
        volumes:
            - ./etc/nginx/conf.d/default.conf.nginx:/etc/nginx/conf.d/default.conf
        ports:
            - 81:80
        depends_on:
            - backend
            - frontend

    frontend:
        image: node:current-alpine
        user: ${UID}:${UID}
        working_dir: /home/node/app
        volumes:
            - ./frontend:/home/node/app
        environment:
            NODE_ENV: development
        command: "npm run serve"

    backend:
        build:
            context: dockerize/backend
        # this way container interacts with host on behalf of current user.
        # !!! NOTE: $UID is a _shell_ variable, not an environment variable!
        # To make it available as a shell var, make sure you have this in your ~/.bashrc (./.zshrc etc):
        # export UID="$UID"
        user: ${UID}:${UID}

        volumes:
            - ./backend:/app
            # custom adjustments to php.ini
            # i. e. "xdebug.remote_host" to debug the dockerized app
            - ./etc/php:/usr/local/etc/php/local.conf.d/
        environment:
            # add our custom config files for the php to scan
            PHP_INI_SCAN_DIR: "/usr/local/etc/php/conf.d/:/usr/local/etc/php/local.conf.d/"
        command: "php artisan serve --host=0.0.0.0 --port=8080"

    mysql:
        image: mysql:5.7.22
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports:
            - "4306:3306"
        volumes:
            - ./etc/mysql:/var/lib/mysql
        environment:
            MYSQL_DATABASE: tor
            MYSQL_USER: root
            MYSQL_PASSWORD: root
            MYSQL_ROOT_PASSWORD: root
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
  1. Add default.conf.nginx
    server {
        listen 81;
        server_name frontend;
        error_log  /var/log/nginx/error.log debug;

        location / {
            proxy_pass http://frontend:8080;
        }

        location /sockjs-node {
            proxy_pass http://frontend:8080;
            proxy_set_header Host $host;
            # below lines make ws://localhost/sockjs-node/... URLs work, enabling hot-reload
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
        }

        location /api/ {
            # on the backend side, the request URI will _NOT_ contain the /api prefix,
            # which is what we want for a pure-api project
            proxy_pass http://backend:8080/;
            proxy_set_header Host localhost;
        }
    }
  1. Add Dockerfile
FROM php:fpm-alpine

RUN apk add --no-cache $PHPIZE_DEPS oniguruma-dev libzip-dev curl-dev \
    && docker-php-ext-install pdo_mysql mbstring zip curl \
    && pecl install xdebug redis \
    && docker-php-ext-enable xdebug redis
RUN mkdir /app
VOLUME /app
WORKDIR /app

EXPOSE 8080
CMD php artisan serve --host=0.0.0.0 --port=8080
  1. DON'T FORGET TO ADD vue.config.js to your frontend folder
// vue.config.js
module.exports = {
    // options...
    devServer: {
        disableHostCheck: true,
        host: 'localhost',
        headers: {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
        },
        watchOptions: {
            poll: true
        },
        proxy: 'http://localhost/api',
    } 
}
  1. Run sudo docker-compose up

  2. If you want to do migrations run this: sudo docker-compose exec backend php artisan migrate

You will need 4 containers, defined in a docker-compose file:

  • frontend (your Vue application, which you already have)
  • backend (Laravel application)
  • web server (eg. Nginx or Apache)
  • database (MySQL)

It is possible to combine the 'web-server' and 'backend' containers into one, but this is generally bad advice. Your compose file would look similar to this:

version: '3'
services:
  frontend:
    build: ./frontend
    ports: 
      - 8080:8080
    volumes:
      - ./frontend:/app

  backend:
    build: ./backend
    volumes:
      - ./backend:/var/www/my_app
    environment:
      DB_HOST=db
      DB_PORT=3306

  webserver:
    image: nginx:alpine
    ports:
      - 8000:8000
    volumes:
      - ./backend:/var/www/my_app

  database:
    image: mariadb:latest
    container_name: db
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: dbname
      MYSQL_ROOT_PASSWORD: dbpass
    volumes:
      - ./sql:/var/lib/mysql

where ./backend contains the Laravel application code, ./frontend contains the Vue application, and both contain a Dockerfile. Refer to Docker Hub for specific instructions on each image needed. This exposes 3 ports to your host system: 8080 (Vue app), 8000 (Laravel app), and 3306 (MySQL).

Alternatively, you can omit the web server if you use the artisan cli's serve command in your Laravel container, similar to what you're already doing in the Dockerfile for your Vue application.

The image would have to include something like CMD php artisan serve --host=0.0.0.0 --port=8000

Related