According to the Zeit docs
There are no limitations inside Docker deployments when it comes to the file system. It's always writable and readable.
And indeed my little test seems to write files successfully:
app.get('/write', (req, res) => {
console.log({
__dirname,
cwd: process.cwd()
})
const text = `some bit of text`
const dirpath = path.resolve(process.cwd(), 'uploads')
const fullpath = path.resolve(dirpath, `file-${+new Date()}.txt`)
mkdirp(dirpath, function(error) {
if (error) {
console.error(error)
} else {
fs.writeFile(fullpath, text, error => {
if (error) {
console.error('error writing', error)
} else {
console.log(`file written at ${fullpath}`)
fs.readdir(dirpath, function(err, items) {
for (var i = 0; i < items.length; i++) {
console.log(items[i])
}
})
res.send('File written')
}
})
}
})
})
After several refreshes of the /write route, this will print the list of files. However within the Zeit "source" panel, I only see the files copied by my Dockerfile:
For reference, my Dockerfile:
FROM node:carbon
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]
# ^^^^^^^^^^^^ "start": "node ./build/server"
Within the Zeit/Now environment, is there any way to view/intereact with these files, via ssh or some other method?
Nope. And that is because you can't access the state of the deployment, but only its source and logging!
It makes sense, after all, you should be running a stateless application...
Related
I am trying to integrate Snowflake in my Cypress tests but it keeps on throwing error while compiling.
Error:
Error: Webpack Compilation Error
./node_modules/vm2/lib/resolver-compat.js
Module not found: Error: Can't resolve 'async_hooks' in 'C:\snowflake\node_modules\vm2\lib'
resolve 'async_hooks' in 'C:\snowflake\node_modules\vm2\lib'
Parsed request is a module
using description file: C:\snowflake\node_modules\vm2\package.json (relative path: ./lib)
Field 'browser' doesn't contain a valid alias configuration
Tried the following simple steps:
Installed Cypress
Installed snowflake-sdk through npm
Created a spec file and imported:
const snowflake = require("snowflake-sdk");
When I run the spec file, I am getting the error as above.
If I trace the error to the file resolver-compat.js, I can see the import where it fails.
const {AsyncResource} = require('async_hooks');
I have manually done npm install async_hooks but no luck there also.
package.json
"devDependencies": {
"cypress": "^11.2.0"
},
"dependencies": {
"async_hooks": "^1.0.0",
"snowflake-sdk": "^1.6.16"
}
The snowflake-sdk is a NodeJs package, so in Cypress you need to interact with it via a task.
Here's a basic connection task taken from the Snowflake docs.
cypress.config.js
const { defineConfig } = require("cypress");
var snowflake = require("snowflake-sdk");
let connectionId;
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on("task", {
snowflake: () => {
var connection = snowflake.createConnection({
account: "account",
username: "user",
password: "password",
application: "application",
});
connection.connect(function (err, conn) {
if (err) {
console.error("Unable to connect: " + err.message);
} else {
console.log("Successfully connected to Snowflake.");
// Optional: store the connection ID.
connectionId = conn.getId();
}
})
return null
},
});
},
},
})
Test
it('Connect to snowflake', () => {
cy.task('snowflake')
})
Without proper credentials, it produces a connection error but proves the package is working.
Unable to connect: Request to Snowflake failed.
I dont sure what the problem here, mongod process not spawn inside program.exe that create with pkg. i test it first before compile the script can launch mongod process. after i tested it, spawn cant read pkg filesystem ( snapshot ).
const { spawn } = require('child_process');
const { parse } = require('path')
let processPath = parse(process.argv[0]);
let processDir = processPath.dir;
const args = [
'-f', `${__dirname}\\configs\\mongodb.yml`,
'--dbpath', `${processDir}\\database\\data`,
'--logpath', `${processDir}\\database\\log\\system.log`,
];
const options = {
cwd: `${processDir}\\bin`
};
const mongod = spawn('mongod', args, options);
mongod.stdout.on('data', chunk => {
console.log(chunk.toString())
});
mongod.stdout.on('error', chunk => {
console.log(chunk.toString())
});
mongod.on('spawn', () => {
console.log('success')
});
mongod.on('error', function(error) {
console.log(error)
});
Build Dir
build
build/program.exe
build/bin
build/bin/mongod.exe
build/database
build/database/data
build/database/log/system.log
Package.json pkg configurations
"bin": "dist/application.js",
"pkg": {
"targets": ["node16-win-x64"],
"outputPath": "dist/build",
"assets": [
"dist/configs/*"
]
}
Here is my solution to this issue, tested on Linux Ubuntu 22.04 LTS.
Case scenario:
I needed to include an executable file hello_world as an asset into /snapshot/project/bin/hello_world virtual path and based on some conditions execute it inside the Linux environment.
The problem:
I was getting the following error when I've been trying to execute the command via child_process.spawn:
/bin/sh: 1: /snaponshot/project/bin/hello_world: not found
So clearly my OS is trying to execute hello_world command via /bin/sh, however, the system is unable to access to /snapshot virtual filesystem, therefor not able to execute it.
The workaround:
Clearly, the main file system is unable to access the virtual file system, but we can do the opposite, by copying our executable file from the virtual file system into the main file system and executing it from there, basically, this is what I did:
//node packages
const fs = require('fs');
const os = require('os');
const path = require('path');
const {execSync, spawn} = require('child_process');
// executable file name
const executable = 'hello_world';
//file path to the asset executable file
const remoteControlFilePath = path.join(__dirname, `../bin/${executable}`);
let executableFileFullPath = remoteControlFilePath;
// avoid the workaround if the parent process in not pkg-ed version.
if (process.pkg) {
// creating a temporary folder for our executable file
const destination = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
const destinationPath = path.join(destination, executable);
executableFileFullPath = destinationPath;
// copy the executable file into the temporary folder
fs.copyFileSync(remoteControlFilePath, destinationPath);
// on Linux systems you need to manually make the file executable
execSync(`chmod +x ${destinationPath}`);
}
// using {detached: true}, execute the command independently of its parent process
// to avoid the main parent process' failing if the child process failed as well.
const child = spawn(executableFileFullPath, {detached: true});
child.stdout.on('data', (data) => {
console.log(`child stdout:\n${data}`);
});
child.stderr.on('data', (data) => {
console.error(`child stderr:\n${data}`);
});
child.on('exit', (code, signal) => {
console.log(`child process exited with code ${code} and signal ${signal}`);
});
I'm building a website using VueJs and it works perfect with no errors on the localhost, and I can access it locally in the same computer using the IP address as well. I used to be able to open the website within my network to test it using my phone with the IP address using port 8080. For some reason I can't do that anymore, my phone seems to be able to connect correctly because the console shows the firebase development warning but that's about it. It doesn't seem to be rendering the actual website since it shows blank.
last thing I remember installing before this happened was persistedState and I did so using npm like all the other plugins I use. I don't think this is causing the issue but I thought it was worth mentioning.
this is my Vue.config file:
const path = require("path");
module.exports = {
publicPath:
process.env.NODE_ENV === "production" ? "/metronic/vue/demo3/" : "/",
configureWebpack: {
resolve: {
alias: {
// If using the runtime only build
vue$: "vue/dist/vue.runtime.esm.js" // 'vue/dist/vue.runtime.common.js' for webpack 1
// Or if using full build of Vue (runtime + compiler)
// vue$: 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
},
chainWebpack: config => {
config.module
.rule("eslint")
.use("eslint-loader")
.tap(options => {
options.configFile = path.resolve(__dirname, ".eslintrc.js");
return options;
});
},
css: {
loaderOptions: {
postcss: {
config: {
path: __dirname
}
},
scss: {
prependData: `#import "#/assets/sass/vendors/vue/vuetify/variables.scss";`
}
}
},
transpileDependencies: ["vuetify"]
};
this is my main.js (i skipped all the imports):
router.beforeEach(async (to, from, next) => {
console.log("router");
const user = await authf.currentUser;
(user) ? await store.dispatch("fetchUserProfile", user) : "";
const requiresAuth = await to.matched.some(record => record.meta.requiresAuth);
const isAuthenticated = await store.state.userProfile;
if (isAuthenticated.email != null) {
(requiresAuth) ? next() : next("/Dashboard");
} else {
(requiresAuth) ? next("/Login") : next();
}
// reset config to initial state
store.dispatch(RESET_LAYOUT_CONFIG);
// Scroll page to top on every route change
setTimeout(() => {
window.scrollTo(0, 0);
}, 100);
});
let app;
authf.onAuthStateChanged(async(user) => {
if (user) {
await store.dispatch('fetchUserProfile', user)
}
});
new Vue({
router,
store,
i18n,
vuetify,
firebase,
axios,
render: h => h(App)
}).$mount("#application");
when I do npm run serve it gives me the local access through localhost:8080 and the network access through 192.168.1.137:8080 as it always has. I have access with no console errors in my computer, but the app wont render when accessing through network.
I have some Node JS javascript code that reads folders inside of a directory, however it's currently reading folders and files, and I just need it to read folders and can't figure out what U'm missing:
router.get('/check', (req, res) => {
fs.readdir('./directory', function(err, files) {
if (err) {
res.status(500).send({ error: { status: 500, message: 'error' } })
return
}
console.log('success')
})
})
I was thinking about doing something like files[0].length > X for instance to only show names that contain more than X characters, or filter out file extensions etc, I ideally just need directories since I have a .empty file inside.
You can check reference on documentation. readdir() will return contents of the directory. You need to filter folders or files. Simply you can call and create new array files.filter(fileName => fs.statSync(path + fileName).isFile().
ref
Update
Given sample code will filter files and folders into to seperated variables. You can implement into your project.
const fs = require('fs');
const path = require('path');
const dir = fs.readdirSync(__dirname);
const folders = dir.filter(element => fs.statSync(path.join(__dirname, element)).isDirectory());
const files = dir.filter(element => fs.statSync(path.join(__dirname, element)).isFile);
console.log('folders', folders, 'files', files);
So I am using gulp-exec (https://www.npmjs.com/package/gulp-exec) which after reading some of the documentation it mentions that if I want to just run a command I shouldn't use the plugin and make use of the code i've tried using below.
var exec = require('child_process').exec;
gulp.task('server', function (cb) {
exec('start server', function (err, stdout, stderr) {
.pipe(stdin(['node lib/app.js', 'mongod --dbpath ./data']))
console.log(stdout);
console.log(stderr);
cb(err);
});
})
I'm trying to get gulp to start my Node.js server and MongoDB. This is what i'm trying to accomplish. In my terminal window, its complaining about my
.pipe
However, I'm new to gulp and I thought that is how you pass through commands/tasks. Any help is appreciated, thank you.
gulp.task('server', function (cb) {
exec('node lib/app.js', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
exec('mongod --dbpath ./data', function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
})
For future reference and if anyone else comes across this problem.
The above code fixed my problem. So basically, I found out that the above is its own function and therefore, doesn't need to:
.pipe
I thought that this code:
exec('start server', function (err, stdout, stderr) {
was the name of the task I am running however, it is actually what command I will be running. Therefore, I changed this to point to app.js which runs my server and did the same to point to my MongoDB.
EDIT
As #N1mr0d mentioned below with having no server output a better method to run your server would be to use nodemon. You can simply run nodemon server.js like you would run node server.js.
The below code snippet is what I use in my gulp task to run my server now using nodemon :
// start our server and listen for changes
gulp.task('server', function() {
// configure nodemon
nodemon({
// the script to run the app
script: 'server.js',
// this listens to changes in any of these files/routes and restarts the application
watch: ["server.js", "app.js", "routes/", 'public/*', 'public/*/**'],
ext: 'js'
// Below i'm using es6 arrow functions but you can remove the arrow and have it a normal .on('restart', function() { // then place your stuff in here }
}).on('restart', () => {
gulp.src('server.js')
// I've added notify, which displays a message on restart. Was more for me to test so you can remove this
.pipe(notify('Running the start tasks and stuff'));
});
});
Link to install Nodemon : https://www.npmjs.com/package/gulp-nodemon
This solution has stdout/stderr shown as they occur and does not use 3rd party libs:
var spawn = require('child_process').spawn;
gulp.task('serve', function() {
spawn('node', ['lib/app.js'], { stdio: 'inherit' });
});
You can also create gulp node server task runner like this:
gulp.task('server', (cb) => {
exec('node server.js', err => err);
});
If you want your console to output everything that the child process outputs, as well as pass to the child process all environment variables you already have set:
const exec = require('child_process').exec;
function runCommand(command, cb) {
const child = exec(command, { env: process.env }, function (err) {
cb(err);
})
child.stdout.on('data', (data) => {
process.stdout.write(data);
});
child.stderr.on('data', (data) => {
process.stdout.write(`Error: [${data}]`);
});
}
Note that both out and err write to stdout, this is intentional for my case but you can adapt to whatever you need.