Dockerised NuxtJS app do not reload local changes - docker

I just Dockerised my first NuxtJS app using Docker and Docker-compose.
All run smoothly except that when I make a change on my local, the running docker does not reflect the changes I've made.
How do I configure the Docker container to listen to local changes in my code? Thanks:
Dockerfile:
# Dockerfile
FROM node:11.13.0-alpine
# create destination directory
RUN mkdir /myapp
WORKDIR /myapp
# Add current directory code to working directory
ADD . /myapp/
# update and install dependency
RUN apk update && apk upgrade
RUN apk add git
RUN npm install
EXPOSE 3000
ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000
CMD gunicorn myapp.wsgi:application --bind $NUXT_HOST:$NUXT_PORT
Docker-compose:
version: "3"
services:
nuxt:
build: .
command: npm run dev
ports:
- "3000:3000"
environment:
- NUXT_HOST=0.0.0.0
- NUXT_PORT=3000
volumes:
- /myapp/
Nuxt.config.js:
export default {
// Global page headers (https://go.nuxtjs.dev/config-head)
head: {
title: 'myapp',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
// Global CSS (https://go.nuxtjs.dev/config-css)
css: [],
// Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
plugins: [],
// Auto import components (https://go.nuxtjs.dev/config-components)
components: true,
// Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
buildModules: [
// https://go.nuxtjs.dev/eslint
'#nuxtjs/eslint-module',
// https://go.nuxtjs.dev/stylelint
'#nuxtjs/stylelint-module',
],
// Modules (https://go.nuxtjs.dev/config-modules)
modules: [
// https://go.nuxtjs.dev/buefy
'nuxt-buefy',
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
// https://go.nuxtjs.dev/pwa
'#nuxtjs/pwa',
// https://go.nuxtjs.dev/content
'#nuxt/content',
],
// Axios module configuration (https://go.nuxtjs.dev/config-axios)
axios: {},
// Content module configuration (https://go.nuxtjs.dev/config-content)
content: {},
// Build Configuration (https://go.nuxtjs.dev/config-build)
build: {},
watchers: {
webpack: {
poll: true
}
},
}

Related

BrowserSync Webpack in Docker

I have 3 containers, one for the DB, one for the php/apache and the last one for webpack.
My website is a Wordpress blog. I don't usually use Docker but I wanted to try. So, there is my webpack config that read my css (sass) and js, compile it, it work. But I want to add a BrowserSync for the auto reload. And it's not working the way I want. localhost:3000 is working (my home page) but whenever I go on another page (localhost:3000/whatever) It change my url to php:8080/whatever.
Here is my docker-compose
php:
build: .docker
volumes:
- ./.docker/conf/php/php.ini:/usr/local/etc/php/conf.d/php.ini
- .:/var/www/app
ports:
- "80:80"
depends_on:
- db
user: www-data
db:
image: mysql:5
ports:
- "3307:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
webpack:
build: .docker/webpack
volumes:
- ./:/usr/src/app
ports:
- "3000:3000"
- "3001:3001"
environment:
- LOCAL_DOMAIN=php/
command: sh -c "npm install && npm run dev-server"
depends_on:
- php
My DockerFile (Webpack)
FROM node:16
WORKDIR /usr/src/app
EXPOSE 3000
EXPOSE 3001
# Port pour le devserver de Webpack
EXPOSE 8080
The webpack config
const localDomain = process.env.LOCAL_DOMAIN ? process.env.LOCAL_DOMAIN : 'http://local.websitename.com/';
let baseConfig = {
externals: {
"jquery": "jQuery"
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new BrowserSyncPlugin({
proxy: localDomain,
files: [outputPath + '/*.css', themePath + '**/*.php', outputPath + '/*.js'],
injectCss: true,
}, {
reload: false,
injectCss: true
}),
new CleanWebpackPlugin(),
],
module: {
rules: [{
// CSS SASS SCSS
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true,
},
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.(jpg|jpeg|png|gif|woff|woff2|eot|ttf)$/i,
type: 'asset/resource'
},
{
test: /\.svg$/,
use: ['#svgr/webpack', 'url-loader?limit=1024'],
},
]
}
}
I tried multiple things like but it's not working.
new BrowserSyncPlugin({
host: 'localhost',
port: 3000,
proxy: 'http://localhost:8080/'
},
Can you help me, please ?
(For Info, localhost is working well, I can navigate on my website)

Dockerize Vue.js: hot-reload is not working for vue/cli#4.5 or later versions

I greatly appreciate your effort and the time to solve unresponsive hot-reload function when trying to run Vue.js app on Docker container using Docker engine on Windows 10 while WSL2 active, please take a look at below configurations:
Vue.Setup.Dockerfile
FROM node:17-alpine
EXPOSE 8080
WORKDIR /app/frontend
RUN npm --force install -g #vue/cli#4.5.15
COPY /frontend /app/frontend
ENV PATH /app/frontend/node_modules/.bin:$PATH
CMD [ "npm", "run", "serve" ]
docker-compose.yml
version: "3.8"
services:
vue:
build:
context: .
dockerfile: dockerfiles/Vue.Setup.Dockerfile
restart: always
ports:
- "127.0.0.1:8080:8080"
container_name: vue_ui
volumes:
- ./frontend/:/app/frontend/
- /app/frontend/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
vue.config.js
module.exports = {
publicPath:
process.env.NODE_ENV === "production"
? "/static/dist/"
: "http://127.0.0.1:8080",
pages: {
index: {
entry: 'src/main.js',
template: 'public/index.html',
filename: 'index.html',
title: 'QuestionTime',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
},
// Webpack configuration
devServer: {
host: "0.0.0.0",
port: "8080",
hot: true,
headers: {"Access-Control-Allow-Origin": "*"},
devMiddleware: {
publicPath: "http://127.0.0.1:8080",
writeToDisk: (filePath) => filePath.endsWith("index.html"),
},
static: {
watch: {
ignored: "/node_modules/",
usePolling: true,
},
},
client: {
webSocketURL: {
/* You need to config this option, otherwise the below error will occur
in your browser console when trying to connect to development server
from another Docker container:
WebSocket connection to 'ws://127.0.0.1:<port-number>/ws' failed
*/
hostname: "0.0.0.0",
pathname: "/ws",
port: 8080,
},
},
},
};
Note: When run the command:
docker-compose up
The below message will show:
It seems you are running Vue CLI inside a container.
Since you are using a non-root publicPath, the hot-reload socket
will not be able to infer the correct URL to connect. You should
explicitly specify the URL via devServer.public.
Access the dev server via http://localhost:<your container's
external mapped port>
FYI: the option:
devServer.public
is no longer available in Vue/cli#4 or later versions.
WORKAROUND
solution
Thanks,

Why does my NestJS app try to connect to localhost when it runs inside docker container?

I have a NestJS project (monorepo) and now I'm trying to run all the apps as separate docker containers.
My docker-compose.yml seems like below:
version: '3.8'
services:
app-one:
build:
context: .
dockerfile: ./apps/app-one/Dockerfile
container_name: mono_app-one
ports:
- '3001:3001'
app-two:
build:
context: .
dockerfile: ./apps/app-two/Dockerfile
container_name: mono_app-two
ports:
- '3002:3002'
The Dockerfiles seem like:
FROM node:12.19.0-alpine3.9 AS development
WORKDIR /usr/src
COPY package.json .
RUN npm install --only=development
COPY . .
RUN npm run build --app-one
CMD ["sh", "-c", "npm start --app-one"]
The app.module.ts files seem like:
#Module({
imports: [
ConfigModule.forRoot({
envFilePath: 'development.env',
isGlobal: true,
}),
TypeOrmModule.forRoot({
type: 'mssql',
host: process.env.HOST || 'localhost',
port: parseInt(process.env.PORT, 10) || 1433,
username: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DB_NAME,
entities: [SomeEntity],
synchronize: false,
options: { encrypt: false },
}),
],
...
})
export class AppModule {}
And finaly development.env is:
PORT=1433
HOST=12.34.56.78
USER=admin
PASSWORD=password
DB_NAME=MyDb
When I run docker-compose up --build images are created correctly, containers as well. But when the containers run, I see errors:
Even if I pass port, host, user, pass etc. directly (hardcoded) I see same errors. The question is: Why? In this case I have to look at attempts to connect with 12.34.56.78.
Use ConfigService instead of process.env when initializing TypeOrmModule.
see following doc:
https://docs.nestjs.com/techniques/database#async-configuration
https://docs.nestjs.com/techniques/configuration#using-the-configservice
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mysql',
host: configService.get('HOST'),
port: +configService.get<number>('PORT'),
username: configService.get('USERNAME'),
password: configService.get('PASSWORD'),
database: configService.get('DATABASE'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
inject: [ConfigService],
});

Nextjs: The page does not render when the URL is entered directly from the browser, 404 error

My problem is as follows.
I made a project with Next.js. My project works fine on Local, Local Docker, Heroku and Vercel. However, I have a problem when I go to production environment and publish Docker under the domain. When the address is entered from the browser, the page corresponding to the Router gives 404. But when I navigate through the menu, I don't have a problem. In other words, when the URL is entered directly, it does not render. How can i solve this problem. Domain for those who want to review. Original URL: https://beta.ardictech.com/ and this is Vercel URL: https://ardic-web.vercel.app/
For example, it gives 404 when directly entered with the URL, but when you click on the logo in the upper left and go to the "/" address, the page can be rendered. Or, the pages are rendered while navigating the menu, but if you enter the same address directly or press F5, it does not render.
next.config.js
module.exports = {
webpackDevMiddleware: (config) => {
config.watchOptions = {
polls: 1000,
aggregateTimeout: 300,
};
return config;
},
async headers() {
return [
{
// matching all API routes
source: "/api/:path*",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
{
key: "Access-Control-Allow-Methods",
value: "GET,OPTIONS,PATCH,DELETE,POST,PUT",
},
{
key: "Access-Control-Allow-Headers",
value:
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
},
],
},
];
},
trailingSlash: true,
reactStrictMode: true,
generateEtags: false,
i18n: {
locales: ["en", "tr"],
defaultLocale: "en",
localeDetection: false,
},
env: {
VERSION: process.env.VERSION,
MODE: process.env.MODE,
APP_NAME: process.env.APP_NAME,
HOST: process.env.HOST,
BASE_URL: process.env.BASE_URL,
HOSTNAME: process.env.HOSTNAME,
PORT: process.env.PORT,
GA_TRACKING_ID: process.env.GA_TRACKING_ID,
},
generateBuildId: async() => {
return new Date().toDateString();
},
eslint: {
ignoreDuringBuilds: false,
},
};
docker-compose.yml
version: "2"
services:
ui:
container_name: beta.ardictech.com
hostname: beta.ardictech.com
restart: always
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
volumes:
- ./:/app
- /app/node_modules
- /app/.next
env_file:
- .env
Dockerfile
FROM node:current-alpine as base
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
FROM base AS build
ENV NODE_ENV=production
WORKDIR /build
COPY --from=base /app ./
RUN npm run build
FROM node:current-alpine AS production
ENV NODE_ENV=production
WORKDIR /app
COPY --from=build /build/package*.json ./
COPY --from=build /build/.next ./.next
COPY --from=build /build/public ./public
RUN npm install
EXPOSE 3000
CMD npm run start

Next.js API URL problem on Docker container

My problem is:
I made a simple web page with Next.js. I take some content from /pages/api/ endpoints with JSON format and show it in pages and components. Compiling locally (npm run dev or npm run start) is fine. When I run it on Docker on Windows 10, I don't have a problem again. And this is working on Heroku and Vercel. The point I'm having trouble with is: I gave the project to the Devops team and they ran it on Docker. They also directed a domain to this project. But the api endpoints are meaninglessly trying to access an ID URL. When I look from Chrome Devtools it looks like this:
http://013cfdde4910:3000/api/en/brands
I get the following errors as console message.
​Mixed Content: The page at 'https://beta..com/technologies' was loaded over HTTPS, but requested an insecure resource 'http://013cfdde4910:3000/api/en/menu'. This request has been blocked; the content must be served over HTTPS.
Actually it should be http://localhost:3000/api/en/brands. I don't understand where 013cfdde4910 here is coming from and why.
I checked to see if it is among the codes. I looked at the Source of the project that is live, that is, published by the Devops team, from Google Devtools.
_next/static > chunk > pages > _app-eac17e226e00cc01a313.js
When I searched here, I found 013cfdde4910 String in 3 places. Why did it come here when it was built?
For example, the minified code continues as follows.
.... return(0,u.useEffect)((function(){fetch("".concat("http://013cfdde4910:3000","/api/").concat(t.locale,"/) brands")).....
I can see it as localhost in my local build and when I publish it in Windows 10 Docker and look there. So what is causing the localhost -> 013cfdde4910 conversion and how can I solve it?
Dockerfile I use:
FROM node:current-alpine as base
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
FROM base AS build
ENV NODE_ENV=production
WORKDIR /build
COPY --from=base /app ./
RUN npm run build
FROM node:current-alpine AS production
ENV NODE_ENV=production
WORKDIR /app
COPY --from=build /build/package*.json ./
COPY --from=build /build/.next ./.next
COPY --from=build /build/public ./public
RUN npm install
EXPOSE 3000
CMD npm run start
I use docker-compose.yml
version: "3"
services:
ui:
container_name: web
restart: always
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
volumes:
- ./:/app
- /app/node_modules
- /app/.next
env_file:
- .env
And this is next.config.js
module.exports = {
webpackDevMiddleware: (config) => {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
return config;
},
async headers() {
return [
{
source: "/api/:path*",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
{
key: "Access-Control-Allow-Methods",
value: "GET,OPTIONS,PATCH,DELETE,POST,PUT",
},
{
key: "Access-Control-Allow-Headers",
value:
"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
},
],
},
];
},
reactStrictMode: true,
generateEtags: false,
i18n: {
locales: ["en", "tr"],
defaultLocale: "en",
localeDetection: false,
},
env: {
VERSION: process.env.VERSION,
MODE: process.env.MODE,
APP_NAME: process.env.APP_NAME,
HOST: process.env.HOST,
HOSTNAME: process.env.HOSTNAME,
PORT: process.env.PORT,
GA_TRACKING_ID: process.env.GA_TRACKING_ID,
},
generateBuildId: async () => {
return new Date().toDateString();
},
eslint: {
ignoreDuringBuilds: false,
},
};
Thanks for posting the config, it appears the hostname is grabbed as the docker container ID - You do not post the actual fetch code but my guess is - this environment variable is used.
`HOSTNAME: process.env.HOSTNAME`
It is either passed as a environment variable or interpreted to be the container ID, you need a way to create a domain:3000/api/brands which could be part of the Docker deploy, maybe a nginx proxy.

Resources