Cloud Commander

Cloud file manager with console and editor

View Project on GitHub

Find typo? Help fix it.
Contact

Cloud Commander v19.19.1

MainBlogDemoDeploy

Cloud Commander is a file manager for the web. It includes a command-line console and a text editor. Cloud Commander helps you manage your server and work with files, directories and programs in a web browser from any computer, mobile or tablet.

Cloud Commander

Benefits

Installation

Installation is very simple:

npm i cloudcmd -g

When in trouble, use:

npm i cloudcmd -g--force

Usage

To start the server, just run the global npm binary from your terminal:

cloudcmd

Cloud Commander supports the following command-line parameters:

ParameterOperation
-h, --helpdisplay help and exit
-v, --versiondisplay version and exit
-s, --savesave configuration
-o, --onlineload scripts from remote servers
-a, --authenable authorization
-u, --usernameset username
-p, --passwordset password
-c, --configconfiguration file path
--show-configshow config values
--show-dot-filesshow dot files
--show-file-nameshow file name in view and edit
--editorset editor: “dword”, “edward” or “deepword”
--packerset packer: “tar” or “zip”
--rootset root directory
--prefixset url prefix
--prefix-socketset prefix for url connection
--portset port number
--confirm-copyconfirm copy
--confirm-moveconfirm move
--openopen web browser when server starts
--nameset tab name in web browser
--menuset menu: “supermenu” or “aleman”
--one-file-panelshow one file panel
--keys-panelshow keys panel
--contactenable contact
--config-dialogenable config dialog
--config-authenable auth change in config dialog
--config-portenable port change in config dialog
--consoleenable console
--sync-console-pathsync console path
--terminalenable terminal
--terminal-pathset terminal path
--terminal-commandset command to run in terminal (shell by default)
--terminal-auto-restartrestart command on exit
--vimenable vim hot keys
--columnsset visible columns
--themeset theme ‘light’ or ‘dark’”
--exportenable export of config through a server
--export-tokenauthorization token used by export server
--importenable import of config
--import-tokenauthorization token used to connect to export server
--import-urlurl of an import server
--import-listenenable listen on config updates from import server
--dropboxenable dropbox integration
--dropbox-tokenset dropbox token
--logenable logging
--no-show-configdo not show config values
--no-serverdo not start server
--no-authdisable authorization
--no-onlineload scripts from local server
--no-opendo not open web browser when server started
--no-nameset default tab name in web browser
--no-keys-panelhide keys panel
--no-one-file-panelshow two file panels
--no-confirm-copydo not confirm copy
--no-confirm-movedo not confirm move
--no-config-dialogdisable config dialog
--no-config-authdisable auth change in config dialog
--no-config-portdisable port change in config dialog
--no-consoledisable console
--no-sync-console-pathdo not sync console path
--no-contactdisable contact
--no-terminaldisable terminal
--no-terminal-commandset default shell to run in terminal
--no-terminal-auto-restartdo not restart command on exit
--no-vimdisable vim hot keys
--no-themesset default visible themes
--no-exportdisable export config through a server
--no-importdisable import of config
--no-import-listendisable listen on config updates from import server
--no-show-file-namedo not show file name in view and edit
--no-dropboxdisable dropbox integration
--no-dropbox-tokenunset dropbox token
--no-logdisable logging

For options not specified by command-line parameters, Cloud Commander then reads configuration data from ~/.cloudcmd.json. It uses port 8000 by default.

To begin using the web client, go to this PREFIX in your browser:

http://localhost:8000

Updating the app

If you installed Cloud Commander with npm, stop the server. Then, reinstall it with:

npm install cloudcmd -g

Then, start the server again with cloudcmd and reload the page.

Hot keys

KeyOperation
F1help
F2show user menu
F3view, change directory
Shift + F3view raw file, change directory
F4edit
F5copy
Alt + F5pack
F6rename/move
Shift + F6rename current file
F7new directory
Shift + F7new file
F8, Deleteremove
Shift + Deleteremove without prompt
F9menu
Alt + F9extract
F10config
*select/unselect all
+expand selection
-shrink selection
:open Command Line
Ctrl + Xcut to buffer
Ctrl + Ccopy to buffer
Ctrl + Vpaste from buffer
Ctrl + Zclear buffer
Ctrl + Pcopy path
Ctrl + Rrefresh
Ctrl + Dclear local storage
Ctrl + Aselect all files in a panel
Ctrl + Mrename selected files in editor
Ctrl + Uswap panels
Ctrl + F3sort by name
Ctrl + F5sort by date
Ctrl + F6sort by size
Ctrl + Shift + Llogout
Ctrl + Command + .show/hide dot files
Upmove cursor up
Downmove cursor down
Enterchange directory/view file
Alt + Left/Rightshow content of directory under cursor in target panel
Alt + Ggo to directory
Ctrl + \go to the root directory
Tabmove via panels
Page Upup on one page
Page Downdown on one page
Hometo begin of list
Endto end of list
Spaceselect current file (and get size of directory)
Insertselect current file (and move to next)
F9context menu
~console
Esctoggle vim hotkeys (file manager, editor)

Vim

When the --vim option is provided, or the configuration parameter vim is set, the following hotkeys become available:

KeyOperation
jnavigate to next file
knavigate to previous file
ddremove current file
G or $navigate to bottom file
gg or ^navigate to top file
vvisual mode
ycopy (selected in visual mode files)
ppaste files
Escunselect all
/find file in current directory
nnavigate to next found file
Nnavigate to previous found file
mdmake directory
mfmake file
ttshow terminal
eedit file
cccopy
mmmove
rrrename file

Commands can be joined, for example:

Drag and drop

These file operations are accessible with “drag and drop”.

Drag Mouse ButtonKeyOriginDestinationOperation
LeftPanelPanelcopy files
LeftShiftPanelPanelrename/move files
LeftPanelDesktopdownload files
LeftDesktopPanelupload files

View

View

Features

Hotkeys

KeyOperation
F3open
Escclose

Edit

Edit

Hot keys

KeyOperation
F4open
Shift + F4open in “vim” mode
Escclose

For more details see Edward hotkeys.

Console

Console

Hot keys

KeyOperation
~open
Ctrl + Ppaste path of current directory
Escclose

For more details see console hot keys.

Terminal

Terminal

Install

The terminal is disabled and not installed by default. To use it, you should install gritty with:

npm i gritty -g

and then set the path for the terminal with:

cloudcmd --terminal--terminal-path`gritty --path`--save

Windows

If you can’t install gritty on Windows, try to install windows-build-tools first:

npm install windows-build-tools -g

Then get the path of gritty with:

gritty --path

It will returns something like:

C:\Users\coderaiser\AppData\Roaming\npm\node_modules\gritty

Set this path as --terminal-path with:

cloudcmd --save--terminal--terminal-path"C:\Users\coderaiser\AppData\Roaming\npm\node_modules\gritty"

After that, you can use Cloud Commander’s terminal in the same way as a normal shell console.

Hotkeys

KeyOperation
Shift + ~open
Shift + Escclose

Environment Variables

Every program executed in Cloud Commander’s terminal has these environment variables:

On Unix, you can use it this way:

~> echo$CURRENT_PATH
/home/coderaiser/cloudcmd/bin/cloudcmd.js

Configuration

Config

Hot keys

KeyOperation
F10open
Escclose

When you change any options, the ~/.cloudcmd.json file is automatically updated. It can also be edited manually with any text editor. Here’s a description of all options:

{"name":"",//settabnameinwebbrowser"auth":false,//enablehttpauthentication"username":"root",//usernameforauthentication"password":"toor",//passwordhashforauthentication"algo":"sha512WithRSAEncryption",//cryptographicalgorithm"editor":"edward",//default,couldbe"dword"or"edward""packer":"tar",//default,couldbe"tar"or"zip""diff":true,//whensave-sendpatch,notwholefile"zip":true,//ziptextbeforesend/unzipbeforesave"buffer":true,//bufferforcopyingfiles"dirStorage":true,//storedirectorylisting"online":false,//donotloadjsfilesfromcdn"open":true,//openwebbrowserwhenserverstarted"oneFilePanel":false,//showonefilepanel"keysPanel":true,//showclassicpanelwithbuttonsofkeys"port":8000,//httpport"ip":null,//ipornull(default)"root":"/",//rootdirectory"prefix":"",//urlprefix"prefixSocket":"",//prefixforsocketconnection"confirmCopy":true,//confirmcopy"confirmMove":true,//confirmmove"showConfig":false,//showconfigatstartup"showDotFiles":true,//showdotfiles"showFileName":false,//donotshowfilenameinviewandedit"contact":true,//enablecontact"configDialog":true,//enableconfigdialog"configAuth":true,//enableauthchangeinconfigdialog"console":true,//enableconsole"syncConsolePath":false,//donotsyncconsolepath"terminal":false,//disableterminal"terminalPath":"",//pathofaterminal"terminalCommand":"",//setcommandtoruninterminal"terminalAutoRestart":true,//restartcommandonexit"vim":false,//disablevimhotkeys"themes":"name-size-date-owner-mode",//setvisiblethemes"export":false,//enableexportofconfigthroughaserver"exportToken":"root",//tokenusedbyexportserver"import":false,//enableimportofconfig"import-url":"http://localhost:8000",//urlofanexportserver"importToken":"root",//tokenusedtoconnecttoexportserver"importListen":false,//listenonconfigupdates"dropbox":false,//disabledropboxintegration"dropboxToken":"",//unsetdropboxtoken"log":true//logging}

Environment Variables

Some config options can be overridden with environment variables, such as:

User Menu

When you press F2 Cloud Commander will read a file .cloudcmd.menu.js by walking up parent directories, if can’t read it will try to read ~/.cloudcmd.menu.js.

Let’s consider example user menu works file:

constRENAME_FILE='Rename file';exportdefault{'__settings':{select:[RENAME_FILE],run:false,},[`F2 - ${RENAME_FILE}`]:async({DOM})=>{awaitDOM.renameCurrent();},'D - Build Dev':async({CloudCmd})=>{awaitCloudCmd.TerminalRun.show({command:'npm run build:client:dev',autoClose:false,// optionalcloseMessage:'Press any button to close Terminal',// optional});awaitCloudCmd.refresh();},'P - Build Prod':async({CloudCmd})=>{awaitCloudCmd.TerminalRun.show({command:'npm run build:client',autoClose:true,// optional});awaitCloudCmd.refresh();},'C - Create User Menu File':async({DOM,CloudCmd})=>{const{CurrentInfo}=DOM;const{dirPath}=CurrentInfo;constpath=`${dirPath}.cloudcmd.menu.js`;const{prefix}=CloudCmd;constdata=awaitreadDefaultMenu({prefix,});awaitcreateDefaultMenu({path,data,DOM,CloudCmd,});},};asyncfunctioncreateDefaultMenu({path,data,DOM,CloudCmd}){const{IO}=DOM;awaitIO.write(path,data);awaitCloudCmd.refresh();DOM.setCurrentByName('.cloudcmd.menu.js');awaitCloudCmd.EditFile.show();}asyncfunctionreadDefaultMenu({prefix}){constres=awaitfetch(`${prefix}/api/v1/user-menu/default`);constdata=awaitres.text();returndata;}

You will have ability to run one of this 3 commands with help of double click, enter, or binded key (F2, D or P in this example). Also you can run commands in terminal, or execute any built-in function of Cloud Commander extended it’s interface. You can find more examples in User Menu Cookbook.

User Menu API

Here you can find API that can be used in User Menu. DOM and CloudCmd two main objects you receive in arguments list using destructuring.

DOM contains all base functions of Cloud Commander (rename, remove, download etc);

CloudCmd contains all modules (Terminal, View, Edit, Config, Console etc);

IO Files API

Distribute

Being able to configure Cloud Commander remotely opens the doors to using it as microservice, and that’s what the “distribute” options set out to do.

There is an export server and an import client, which are enabled with --export and --import respectively. There is a “token”, which should be the same in --import-token and --export-token. To use the import client, you should provide --import-url to the client so it can connect to an export server.

There are two ways that the import client can receive configuration from an export server:

An example - using the “distribute” options to get configuration from a remote instance:

Here’s an export server:

coderaiser@cloudcmd:~$ cloudcmd --port 1234 --export --export-token=cloudcmd

…and an import client:

coderaiser@cloudcmd:~$ cloudcmd --name importer --port 4321 --import-url http://127.0.0.1:1234 --import-token=cloudcmd --no-server --save

Here’s the log output from the export server:

url: http://localhost:1234/
2018.08.23 13:41:45 -> export: try to auth from importer [127.0.0.1:4321]
2018.08.23 13:41:45 -> export: connected to importer [127.0.0.1:4321]
2018.08.23 13:41:45 -> export: config send to importer [127.0.0.1:4321]
2018.08.23 13:41:45 -> export: disconnected importer [127.0.0.1:4321]

…and the log output from the import client:

2018.08.23 13:47:36 -> import: try to auth to http://127.0.0.1:1234
2018.08.23 13:47:36 -> import: connected to http://127.0.0.1:1234
2018.08.23 13:47:36 -> import: config received from http://127.0.0.1:1234
2018.08.23 13:47:36 -> import: disconnected from http://127.0.0.1:1234

When the import client uses --import-listen, a persistent connection is used, and the client receives live updates from the import server.

The export server omits the following configuration fields:

Menu

Right-mouse click to show a context menu with these items:

Hot keys

KeyOperation
F9open
Escclose
Up, jmove cursor up
Down, kmove cursor down
Left, hclose submenu
Right, lopen submenu
G or $navigate to bottom
gg or ^navigate to top

Commands can be joined, for example:

One file panel

Cloud Commander can work in one panel mode when your screen size can’t accommodate a second panel (such as on mobile or tablet), or via the --one-file-panel options flag.

One file panel

Using as middleware

Cloud Commander can be used as middleware for node.js applications based on socket.io and express:

Init package.json:

npm init -y

Install dependencies:

npm i cloudcmd express socket.io -S

And create index.js:

importhttpfrom'node:http';import{cloudcmd}from'cloudcmd';import{Server}from'socket.io';importexpressfrom'express';constapp=express();constport=1337;constprefix='/';constserver=http.createServer(app);constsocket=newServer(server,{path:`${prefix}socket.io`,});constconfig={name:'cloudcmd :)',};constfilePicker={data:{FilePicker:{key:'key',},},};// override option from json/modules.jsonconstmodules={filePicker,};const{createConfigManager,configPath,}=cloudcmd;constconfigManager=createConfigManager({configPath,});app.use(prefix,cloudcmd({socket,// used by Config, Edit (optional) and Console (required)config,// config data (optional)modules,// optionalconfigManager,// optional}));server.listen(port);

Here is example with two Config Managers:

importhttpfrom'node:http';importcloudcmdfrom'cloudcmd';import{Server}from'socket.io';importexpressfrom'express';constapp=express();constport=8000;constprefix1='/1';constprefix2='/2';const{createConfigManager}=cloudcmd;constserver=http.createServer(app);constsocket1=newServer(server,{path:`${prefix1}/socket.io`,});constsocket2=newServer(server,{path:`${prefix2}/socket.io`,});constconfigManager1=createConfigManager();configManager1('name','1');constconfigManager2=createConfigManager();configManager2('name','2');app.use(prefix1,cloudcmd({socket:socket1,configManager:configManager1,}));app.use(prefix2,cloudcmd({socket:socket2,configManager:configManager2,}));server.listen(port);

If you want to enable authorization, you can pass credentials to Cloud Commander with a config. To generate a password, you can install criton with npm i criton --save, and use it (or any other way) to generate a hash of a password.

importcritonfrom'criton';constalgo='sha512WithRSAEncryption';// default// you can generate a hash dynamicallyconstpassword=criton('root',algo);// or use a pregenerated hash as well'2b64f2e..ca5d9a9';constauth=true;constusername='root';constconfig={algo,// optionalauth,username,password,};

Now you’re ready to go!

Authorization

~/.cloudcmd.json contains password hash because of security reason, if someone steal your config, he wouldn’t know your password, because hash is very strong and can be customized.

You should never write your password as plain text to ~/.cloudcmd.json, you can generate password using cloudcmd itself:

cloudcmd --username name --password password --auth --save --no-server

This command will create hash of your password and write it to ~/.cloudcmd.json.

Server

Standard practices dictate that no non-root process get to talk to the internet on a port less than 1024. Despite this, I suggest you start Cloud Commander as a non-root process. How can we get around this limitation? There’s a couple of fast & easy ways. One of them is port forwarding:

Iptables

Just run shell/addtables.sh for default options.

iptables -t nat -L# look rules before
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8000
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 4430
iptables -t nat -L# look rules after

You should see something like this (8000 and 4430 should be in config as port and sslPort)

target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8000
REDIRECT tcp -- anywhere anywhere tcp dpt:https redir ports 4430

If you would want to get things back just clear rules (rule numbers 1 and 2; in your list they could differ).

iptables -t nat -D PREROUTING 2
iptables -t nat -D PREROUTING 1

nginx

Get nginx. On Linux, you can run:

sudo apt-get install nginx #for ubuntu and debian

Then, make a host file /etc/nginx/sites-available/io.cloudcmd.io (where, for example, io.cloudcmd.io is your domain name) with these contents:

server {
listen 80;
client_max_body_size 100m;
server_name io.cloudcmd.io;
access_log /var/log/nginx/io.cloudcmd.io.access.log;
location / {
proxy_pass http://127.0.0.1:8000/;}}

If you want add SSL, add a couple lines to the server block:

server {
listen 443;
client_max_body_size 100m;
ssl on;
ssl_certificate /home/coderaiser/cloudcmd/ssl/ssl.crt;
ssl_certificate_key /home/coderaiser/cloudcmd/ssl/ssl.key;
server_name io.cloudcmd.io;
access_log /var/log/nginx/io.cloudcmd.io.access.log;
location / {
proxy_pass http://127.0.0.1:8000/;}}

For WebSocket support, (nginx >= v1.3.13) modify the server block like so:

 location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:8000/;}

If you need redirection from http to https, simply use:

server {
listen 80;
server_name admin.cloudcmd.io;
rewrite ^ https://io.cloudcmd.io$request_uri? permanent;#301 redirect
access_log /var/log/nginx/io.cloudcmd.io.access.log;}
# create a symlink of this fileln-s ./sites-available/io.cloudcmd.io ./sites-enabled
# restart nginx
/etc/init.d/nginx restart

Deploy

Cloud Commander can be easily deployed to InstaPods. After deploy you receive email with credentials.

Deploy on InstaPods

Docker

Cloud Commander can be used as docker container like so:

docker run -t--rm-v ~:/root -v /:/mnt/fs -w=/root -p 8000:8000 coderaiser/cloudcmd

Configuration will be read from the home directory, the host’s root file system will be mounted to /mnt/fs, and port 8000 port will exposed to the host’s port.

Also, you can use docker compose with docker-compose.yml:

version:'2'services:web:ports:-8000:8000volumes:-~:/root-/:/mnt/fsimage:coderaiser/cloudcmd

When you create this file, run:

docker-compose up

Dropbox

Dropbox support is integrated into Cloud Commander, and you can switch from your local file system to a Dropbox account. All you need to do is set --dropbox option and generate a dropbox token for your account.

This could look like this:

cloudcmd --dropbox--dropbox-token your-dropbox-token

While using Dropbox remember that there is no remote support for the console/terminal. Seeing the progress of file operations is also not supported. There’s only basic support, but you can do the following things with files and directories:

Automatically start cloudcmd on boot for systemd

First, locate the command to run cloudcmd

which cloudcmd

take note of the result and create a systemd entry by executing

sudo nano /etc/systemd/system/cloudcmd.service

and use this template

[Unit]
Description = Cloud Commander
[Service]
TimeoutStartSec = 0
Restart = always
ExecStart = THE RESULT OF which cloudcmd WE'VE EXECUTED EARLIER
User = YOUR_USER
[Install]
WantedBy = multi-user.target

Don’t forget to change the line for ExecStart and User

Save the changes and exit editor.

You may now enable cloudcmd and set it to autostart on boot by running:

sudo systemctl enable--now cloudcmd

Automatically start cloudcmd on boot for FreeBSD

First, locate the command to run cloudcmd

which cloudcmd

take note of the result and create a rc script

vi /usr/local/etc/rc.d/cloudcmd

and use this template

!/bin/sh
#
# PROVIDE: cloudcmd
# REQUIRE: LOGIN
# KEYWORD: shutdown
# Author: IhatemyISP (ihatemyisp.net)
# Version: 1.0.0
# Description:
# This script runs Cloud Commander as a service under the supplied user on boot
# 1) Place file in /usr/local/etc/rc.d/
# 2) Add cloudcmd_enable="YES" to /etc/rc.conf
# 3) (Optional) To run as non-root, add cloudcmd_runAs="user" to /etc/rc.conf
# 4) (Optional) To pass Cloud Commander args, add cloudcmd_args="" to /etc/rc.conf
# Freebsd rc library
. /etc/rc.subr
# General Info
name="cloudcmd" # Safe name of program
program_name="cloudcmd" # Name of exec
title="CloudCommander" # Title to display in top/htop
# RC.config vars
load_rc_config $name # Loading rc config vars
: ${cloudcmd_enable="NO"} # Default: Do not enable Cloud Commander
: ${cloudcmd_runAs="root"} # Default: Run Cloud Commander as root
# Freebsd Setup
rcvar=cloudcmd_enable # Enables the rc.conf YES/NO flag
pidfile="/var/run/${program_name}.pid" # PID file location
# Env Setup
export HOME=$( getent passwd "$cloudcmd_runAs" | cut -d: -f6 ) # Gets the home directory of the runAs user
# Command Setup
exec_path="/usr/local/bin/${program_name}" # Path to the cloudcmd exec, /usr/local/bin/ when installed globally
output_file="/var/log/${program_name}.log" # Path to Cloud Commander output file
# Command
command="/usr/sbin/daemon"
command_args="-r -t ${title} -u ${cloudcmd_runAs} -o ${output_file} -P ${pidfile} ${exec_path} ${cloudcmd_args}"
# Loading Config
load_rc_config ${name}
run_rc_command "$1"

Enable autostart

echo cloudcmd_enable="YES" >> /etc/rc.conf

(Optional) Set user to run Cloud Commander as (default is root)

echo cloudcmd_runAs="user" >> /etc/rc.conf

Start the service (or just reboot)

service cloudcmd start

Get involved

There are a lot of ways to be involved in Cloud Commander development:

Version history

Special Thanks