I am re-re-re-reading the docs on environment variables and am a bit confused.
MWE repo: https://gitlab.com/SumNeuron/docker-nf
I made a plugin /plugins/axios.js which creates a custom axios instance:
import axios from 'axios'
const apiVersion = 'v0'
const api = axios.create({
baseURL: `${process.env.PUBLIC_API_URL}/api/${apiVersion}/`
})
export default api
and accordingly added it to nuxt.config.js
import colors from 'vuetify/es5/util/colors'
import bodyParser from 'body-parser'
import session from 'express-session'
console.log(process.env.PUBLIC_API_URL)
export default {
mode: 'spa',
env: {
PUBLIC_API_URL: process.env.PUBLIC_API_URL || 'http://localhost:6091'
},
// ...
plugins: [
//...
'@/plugins/axios.js'
]
}
I set PUBLIC_API_URL to http://localhost:9061 in the .env file. Oddly, the log statement is correct (port 9061) but when trying to reach the site there is an api call to port 6091 (the fallback)
project/
|-- backend (flask api)
|-- frontend (npx create-nuxt-app frontend)
|-- assets/
|-- ...
|-- plugins/
|-- axios.js
|-- restriced_pages
|-- index.js (see other notes 3)
|-- ...
|-- nuxt.config.js
|-- Dockerfile
|-- .env
|-- docker-compose.yml
version: '3'
services:
nuxt: # frontend
image: frontend
container_name: my_nuxt
build:
context: .
dockerfile: ./frontend/Dockerfile
restart: always
ports:
- "3000:3000"
command: "npm run start"
environment:
- HOST
- PUBLIC_API_URL
flask: # backend
image: backend
container_name: my_flask
build:
context: .
dockerfile: ./backend/Dockerfile
command: bash deploy.sh
environment:
- REDIS_URL
- PYTHONPATH
ports:
- "9061:9061"
expose:
- '9061'
depends_on:
- redis
worker:
image: backend
container_name: my_worker
command: python3 manage.py runworker
depends_on:
- redis
environment:
- REDIS_URL
- PYTHONPATH
redis: # for workers
container_name: my_redis
image: redis:5.0.3-alpine
expose:
- '6379'
FROM node:10.15
ENV APP_ROOT /src
RUN mkdir ${APP_ROOT}
WORKDIR ${APP_ROOT}
COPY ./frontend ${APP_ROOT}
RUN npm install
RUN npm run build
The reason the site fails to load is because the new axios plugin (@/plugins/axios.js) makes a weird call xhr call when the page is loaded, triggered by commons.app.js line 464. I do not know why, this call is no where explicitly in my code.
I see this warning:
WARN Warning: connect.session() MemoryStore is not designed for a production environment, as it will leak memory, and will not scale past a single process.
I do not know what caused it or how to correct it
// Create express router
const router = express.Router()
// Transform req & res to have the same API as express
// So we can use res.status() & res.json()
const app = express()
router.use((req, res, next) => {
Object.setPrototypeOf(req, app.request)
Object.setPrototypeOf(res, app.response)
req.res = res
res.req = req
next()
})
// Add POST - /api/login
router.post('/login', (req, res) => {
if (req.body.username === username && req.body.password === password) {
req.session.authUser = { username }
return res.json({ username })
}
res.status(401).json({ message: 'Bad credentials' })
})
// Add POST - /api/logout
router.post('/logout', (req, res) => {
delete req.session.authUser
res.json({ ok: true })
})
// Export the server middleware
export default {
path: '/restricted_pages',
handler: router
}
which is configured in nuxt.config.js as
serverMiddleware: [
// body-parser middleware
bodyParser.json(),
// session middleware
session({
secret: 'super-secret-key',
resave: false,
saveUninitialized: false,
cookie: { maxAge: 60000 }
}),
// Api middleware
// We add /restricted_pages/login & /restricted_pages/logout routes
'@/restricted_pages'
],
which uses the default axios module:
//store/index.js
import axios from 'axios'
import api from '@/plugins/axios.js'
//...
const actions = {
async login(...) {
// ....
await axios.post('/restricted_pages/login', { username, password })
// ....
}
}
// ...
As you are working in SPA mode, you need your environment variables to be available during build time.
The $ docker run command is therefore already too late to define these variables, and that is what you are doing with your docker-compose's 'environment' key.
So what you need to do to make these variables available during buildtime is to define them in your Dockerfile with ENV PUBLIC_API_URL http://localhost:9061. However, if you want them to be defined by your docker-compose, you need to pass them as build args. I.e. in your docker-compose :
nuxt:
build:
# ...
args:
PUBLIC_API_URL: http://localhost:9061
and in your Dockerfile, you catch that arg and pass it to your build environment like so :
ARG PUBLIC_API_URL
ENV PUBLIC_API_URL ${PUBLIC_API_URL}
If you don't want to define the variable's value directly in your docker-compose, but rather use locally (i.e. on the machine you're lauching the docker-compose command) defined environment variables (for instance with shell $ export PUBLIC_API_URL=http://localhost:9061), you can reference it as you would in a subsequent shell command, so your docker-compose ends up like this :
nuxt:
build:
# ...
args:
PUBLIC_API_URL: ${PUBLIC_API_URL}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With