Next.js API URL problem on Docker container - docker

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.

Related

Hot reloading is not working when I use docker compose and webpack-dev-server

there.
I've been struggling with building Docker(Docker Compose) and Webpack environment for months.
What I want to achieve is hot reloading for a webpack-dev-server running inside a docker container with code changes from outside the container.
Here is what I've been able to do so far...
If you run webpack-dev-server in the container and make changes to the code in the container by the vim editor, the changes will take effect and hot reloading will work.
If you start webpack-dev-server locally while the container is running and make code changes locally too, hot reloading will be performed here as well.
Is anyone familiar with Docker and Webpack? If so, I'd like some advice on how to solve this problem.
Here is my Dockerfile.
# Base image
FROM node:lts-buster-slim
# Create working directory
RUN mkdir -p /app/framer
# Set working directory
WORKDIR /app/framer
# Add $PATH
ENV PATH /app/framer/node_modules/.bin:$PATH
Here is my docker-compose.yml.
version: "3.9"
services:
app:
build:
context: .
dockerfile: Dockerfile
tty: true
volumes:
- ./framer:/app/framer
- /framer/node_modules
expose:
- 3002
ports:
- "3002:3002"
environment:
- WATCHPACK_POLLING=true
- WDS_SOCKET_HOST=127.0.0.1
- WDS_SOCKET_PORT=3002
stdin_open: true
restart: unless-stopped
Here is my webpack-dev-server settings.
devServer: {
open: true,
static: {
directory: path.join(__dirname, 'dist'),
},
host: '0.0.0.0',
allowedHosts: 'all',
hot: true,
port: 3002,
historyApiFallback: true,
client: {
webSocketURL: 'ws://0.0.0.0:3002/ws',
reconnect: true,
overlay: {
errors: true,
warnings: false,
},
},
},
watchOptions: {
poll: true,
},
In addition, I will put a link to the GitHub repository that I'm working on for your reference.
https://github.com/Bear29ers/framer-motion
What I want to achieve is hot reloading for a webpack-dev-server running inside a docker container with code changes from outside the container.
First, enter the container like this.
docker compose exec app bash
Then, run webpack-dev-server.
npm run dev
While running webpack-dev-server inside the container, you change some code in src/ directory from outside the container.
I want the browser that accesses localhost:3002 to detect the change and reload automatically.
Best regards.

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,

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

Dockerised NuxtJS app do not reload local changes

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
}
},
}

Docker with Mongo and Express

First of all, give thanks for reading my question and try to help me and apologize for my English.
I'm trying to run a docker with a express server project and mongo, but build Dockerfile perfectly but I do:
docker logs -f name
and show next error:
/usr/local/bin/docker-entrypoint-sh line 340: exec: npm not found
And, I think that mongodb doesnt run
Why doesnt recognize npm if I add node?
How can run npm and launch mongo?
I'm using ubuntu 17.10
Here is my Dockerfile:
# Install Node
FROM node:latest
# Install Mongo
FROM mongo:4.0.0-xenial
# Author
MAINTAINER MachineGun
# Create user Ubuntu 17.10 (64 bits)
RUN adduser --disabled-login dockeruser
# Work Directory
WORKDIR /home/expressserver
# Copy express project to docker
COPY expressserver expressserver
# Defaul user
USER dockeruser
# Config cointainer PORT:
# MongoDB listening on port: 27017
# Server listening on port: 8080
EXPOSE 27017 8080
# Exec MongoDB
CMD [mongo]
# Exec server with custom npm start
CMD ["npm", "run", "start:dev"]
Also, in app.js I use mongoose with next uri: mongodb://localhost:27017/ExpressServer, its ok?
mongoose.connection.openUri('mongodb://localhost:27017/ExpressServer', { useNewUrlParser: true }, (err, res) => {
if (err) {
console.log('Error: Database not running on port 27017: \x1b[31m%s\x1b[0m', 'offline');
// console.log('throw err: ', err);
throw err;
}
console.log('Database running on port 27017: \x1b[32m%s\x1b[0m', 'online');
});
I've solved the problem :D
Thanks a lot :D
Finally I used docker compose...
Here is my docker-compose.yml:
version: '2'
services:
server:
container_name: expressserver
build: ./
ports:
- "8080:8080"
links:
- mongo
mongo:
container_name: mongoDB
image: mongo:latest
volumes:
- /var/lib/mongodb:/data/db
ports:
- "27017:27017"
command: mongod --port 27017
Here is my Dockerfile:
FROM node:carbon
MAINTAINER MachineGun
RUN adduser --disabled-login dockeruser
WORKDIR /home/dockeruser
COPY expressserver expressserver
WORKDIR /home/dockeruser/expressserver
RUN npm install
USER dockeruser
EXPOSE 8080 27017
CMD ["npm", "start"]
And in my app.js to connect with mongoose:
const options = {
autoIndex: false, // Don't build indexes
reconnectTries: 30, // Retry up to 30 times
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
// If not connected, return errors immediately rather than waiting for reconnect
bufferMaxEntries: 0
};
// Database connection
const connectWithRetry = () => {
mongoose.connect("mongodb://mongo/expressdb", options)
.then(()=>{
console.log('Database running on port 27017: \x1b[32m%s\x1b[0m', 'online')
})
.catch( (err) => {
console.log('MongoDB connection unsuccessful on port 27017: \x1b[31m%s\x1b[0m', 'offline');
console.log('Retry after 5 seconds.');
setTimeout(connectWithRetry, 5000)
});
}
connectWithRetry();

Resources