Giter Site home page Giter Site logo

tryghost / ghost-cli Goto Github PK

View Code? Open in Web Editor NEW
445.0 35.0 219.0 5.81 MB

CLI Tool for installing & updating Ghost

Home Page: https://ghost.org

License: MIT License

JavaScript 100.00%
ghost ghost-cli nodejs cms publishing headless-cms jamstack journalism blogging javascript

ghost-cli's Introduction

Ghost-CLI

CI Status Coverage Status npm version

Basic Setup

  • npm install -g ghost-cli@latest
  • ghost install (for a production linux setup, including Nginx, SSL, and Systemd)
  • ghost install local (for a local setup, useful for theme development/testing)

NOTE: This CLI is not designed to work with any Ghost versions < 1.0.0

Documentation

Project Goals

The objective of the Ghost CLI project is to make setting up and maintaining a Ghost site as straight forward as possible for people who do not want to use Ghost(Pro).

Ghost-CLI is aimed at people who are comfortable in a command line environment, and therefore some technical knowledge is assumed. The design goal of Ghost CLI was to make it possible to install or update Ghost in a single command.

In order to keep these goals obtainable & maintainable by Ghost's small team, we have a recommended system stack that Ghost-CLI works with, and minimal configuration options.

Recommended stack

We officially recommend the stack described here for production installs.

The team behind Ghost CLI only supports this stack. This restriction is very deliberate, as every additional option for configuration or divergent piece of code required to support an additional environment creates exponential complexity and maintenance overhead.

Our primary focus for the project is ensuring that everyone that uses the recommended system stack is able to install, configure, start, stop, restart, update & list their Ghost sites. This includes developing better testing to ensure we are able to prevent regressions, and stabilising the code to ensure that edge cases within the recommended stack are accounted for.

The secondary focus is on improving the CLI itself. We want to ensure that the UI, configuration options, flags, flows, prompts, messages and other behaviours are working for both manual and programmatic use. This also includes improving the documentation to make it easy to use the tool, discover advanced options & debug any common issues.

Anything that falls outside of these two areas is not being actively worked on at present.

Triaging & prioritisation

  • Issues which affect many users with our recommended stack are given first priority
  • Issues which affect small numbers of users are prioritised based on the impact vs the difficulty - i.e. quick fixes will be prioritised, complex issues may be closed and labelled with later & recommended-stack.
  • Issues around documented & understood environment or configuration issues will be closed and labelled with known-issue, users will be directed to the docs & forum.
  • Issues that request modifications in order to support other stacks stack will be closed and labelled with later & other-stack.
  • Issues proposing new features or enhancements will be labelled as such, and in most cases also closed with later.

Help & Support

We aren't able to provide support in GitHub, but we do keep track of common issues with the known-issue label and regularly update documentation & error messages to be clearer.

The documentation for Ghost-CLI can be found at https://ghost.org/docs/ghost-cli/. Community support can be found in our forum.

Developer Setup (for contributing)

  1. Fork this repo
  2. git clone https://github.com/<your-username>/Ghost-CLI path/to/your/workspace
  3. cd path/to/your/workspace
  4. yarn install

To run the CLI for testing:

  • yarn link
  • ghost <command> (can run anywhere on the system)

Running tests

yarn test

Publishing a new version

  1. yarn ship -- -r patch/minor/major
  2. git push
  3. npm publish
  4. Go to https://github.com/TryGhost/Ghost-CLI/releases/new and create a new release
  5. Use Generate release notes and publish

Copyright & License

Copyright (c) 2013-2023 Ghost Foundation - Released under the MIT license. Ghost and the Ghost Logo are trademarks of Ghost Foundation Ltd. Please see our trademark policy for info on acceptable usage.

ghost-cli's People

Contributors

acburdine avatar adrian5 avatar aileen avatar bertant avatar charizard avatar cheahkhing avatar cmraible avatar daniellockyer avatar erisds avatar gompa avatar greenkeeperio-bot avatar isqua avatar johnonolan avatar kevinansfield avatar kieranajp avatar kirrg001 avatar markstos avatar nilsbrychzy avatar phoenixpeca avatar raspberrycoulis avatar renovate-bot avatar renovate[bot] avatar ronaldlangeveld avatar sakulstra avatar sam-lord avatar sebgie avatar snarlynarwhal avatar thomasqbrady avatar tomchantler avatar vikaspotluri123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ghost-cli's Issues

Upgrade to use the `ora` module once node 0.12 has reached end-of-life

Currently there is a re-implemented/copied version of the ora package sitting inside of the CLI.

The reasoning behind this is that the ora module does not support any node version < 4. Because we need to support node 0.10 and 0.12 until they have reached end of life, the library needed to be re-implemented in a backwards-compatible way.

Once support for Node 0.12 is dropped in December (see the node lts schedule) this reimplementation can be swapped out for the actual package.

CLI Version Resolver should take into account currently installed versions

Currently the CLI version resolver (lib/utils/version.js) takes an optionally supplied version and returns a Promise that either rejects (if the version is less than 1.0.0-alpha.1 or does not exist) or resolves with the latest version (if no version is initially supplied) or the version that was initially supplied (if it's valid). It does this by parsing the output of npm view (which can output as JSON).

This should be improved to check with the currently installed versions as well as the available versions on NPM. Doing so will allow better resolution when a ghost update successfully downloads the ghost version but does not update the symlink or the activeVersion value in the config. However, if a force option is passed (see #46), then it will ignore the currently installed versions.

Fix regression in update version checking

This is a reminder to fix this sometime this week before the final alpha.

Before the ES6 refactor, ghost update would check if the current version was already installed, and skip installing/downloading if it was. There is also a --force option that would force a re-install of the new version regardless. Neither of these two things work at the moment 🙈

spawn yarn ENOENT

Issue Summary

What is this?

root@ghost:/opt/test# ghost install
 ✖ Checking for latest Ghost version
   → spawn yarn ENOENT
   Running system checks
   Setting up install directory
   Downloading and installing Ghost
   Moving files
spawn yarn ENOENT

Technical details:

  • Ghost Version: ghost installer
  • Node Version: 6.9.5
  • Browser/OS: Debian Jessie x86_64
  • Database: SQLite

Adapter Installs

With Ghost 0.10 came an update in how storage adapters were handled. The update made it a requirement that all storage adapters for Ghost extend from a base adapter. However, there is no set standard way to install a ghost storage adapter - the only requirement is that it be in the /content/storage folder and have some config parameters be set up.

With Ghost-CLI comes an opportunity to standardize adapter installs, as well as provide for additional benefits such as prompting for various config parameters upon install.

While the standard for adapter installation is still a bit of a WIP, the each storage adapter will need to follow these standards for sure:

  • The adapter MUST be a published npm module
  • The adapter MUST extend the Ghost Base Storage adapter (whether or not it will need to have a separate ghost storage adapter npm module as a dependency is still TBD)

ghost install-adapter <adapter-name> will download and setup a particular adapter. It will initially add it to the config as the configured storage adapter, and there will (likely) be a hook that each storage adapter can use to prompt for different config variables upon install, and check the existence of on ghost start.

Ability to output more info during `ghost install`

ghost install is the way to do a production install and setup.

It would be preferable to be able to output more information about what is happening at each step.

E.g. MySQL step - input server username and password and a database name and the database will be created for you.

I also think this needs a confirm step at the very beginning, explaining that this is a production install etc etc are you ready? [Y/n].

This issue is for the general ability to output more info wherever we need it - would be good to add a couple of examples, link them here with how to add more info if needed.

#181 - a bit related to it, because of more prompts
#188 - related to it, because it prints more information the user needs

Refactor Ghost-CLI Process Management

Current Approach

At the moment, Ghost-CLI process management is a bit hands-off in its approach. Essentially, Ghost-CLI intends to start the ghost process (be it through a detached child process, pm2 process manager, systemd, forever, etc) and then exit, leaving only the one running Ghost process.

However, there are several features needed to make the CLI work well (#61 and #65 are the current open ones), and the current method of starting Ghost does not effectively support them. Better put, to effectively support these features, there would have to be an incredibly strict control over the process manager, making it difficult for third-party process managers (using things like upstart or pm2 or forever) to run Ghost whilst providing the information the CLI needs to run correctly.

A New Approach

The new approach that should solve most of these issues is to tightly integrate the Ghost process with a CLI command. This proposed CLI command (working name: ghost run) would run the Ghost server in a forked child process, and any process manager would start ghost run instead of starting Ghost itself.

Add auth config option

Jotting this down as I'm thinking about it.

Ghost 1.0 uses Patronus by default, but users can set it to use the local password-based authentication if they choose. We should add a config option to allow users to choose password auth.

[Question] Add --silent for install/config

Hello,

I wanna make a dynamic config without user interactions exemple :

ghost install -d blog --ip ${GHOST_IP} --port ${GHOST_PORT} --db ${GHOST_DB} \
        --dbhost ${GHOST_HOST} --dbuser ${GHOST_DB_USER} --dbpass ${GHOST_DB_PASS} \
        --dbname ${GHOST_DB_NAME} --url ${GHOST_URL} --silent ${GHOST_VERSION}

What is expected its an auto-install without prompt and not automatic launch of ghost.

I work on this but my code it's pretty dirty (I'm not a big fan of JS^^).
It's possible to implement this feature for futur releases ?

EDIT : I forget 'url' should be add as parameter

Current directory is not empty, Ghost cannot be installed here

Could we optimise the validation for this error?

Here is the following case:
I run ghost install help and it fails because help is not available. There are for sure other command combinations users uses.

Then i run ghost install and it tells me that Current directory is not empty, Ghost cannot be installed here.. This is quite annoying, because the only file which was created is ghost-cli-debug-2017-03-16T10.log. And as none Ghost developer i might not know what todo.

Possible tasks:

  • improve messaging
  • improve "Ghost cannot be installed here" validation

ghost-cli on Windows

Hi guys!

After installing ghost-cli on Windows 10 as pointed out on http://support.ghost.org/v1-0-alpha/, I have tried to execute the ghost install command without success.

It outputs the following:

PS C:\Users\user\Code\ghost-blog> ghost install
spawn C:\Users\user\AppData\Roaming\npm\node_modules\ghost-cli\node_modules\.bin\npm ENOENT

Am I doing something wrong?

I'm using:

PS C:\Users\user\Code\ghost-blog> node -v
v6.6.0
PS C:\Users\user\Code\ghost-blog npm -v
3.10.3
PS C:\Users\user\Code\ghost-blog>

Thanks!

Improve logging output

Right now ghost-cli starts development mode and production mode in background by spawning a child process.

I am working on logging for ghost and i wonder how this can look like with ghost-cli.
We can create a command like ghost log, which is aware of where the log rotated files are and makes a tail of the newest file. Not sure about development mode, because usually we log in development to stdout/stderr only. That would mean ghost start name=development would not start the process in background and pipes the stdout/stderr to current process.

Detect being inside of Ghost

With all the change around the commands for installing, building, deving & releasing Ghost, mistakes are bound to happen. E.g. today I tried to run ghost setup instead of gulp setup and got the following:

Command 'setup' not found! Type ghost help for usage.

Soon, we'll have a ghost setup command, so this could have done something weird!

At the moment ghost update is smart enough to output the following message:

Working directory is not a valid Ghost installation. Please run 'ghost update' again within a valid Ghost installation.

I think it would be a great enhancement to have ghost-cli tell me when I'm being dumb and trying to run a ghost command inside of ghost itself (e.g. a clone or a download). The simplest marker for this is if there is a package.json file with name ghost. If you find that, I probably didn't mean to run a ghost command.

In this case, it'd be good for all commands to output a message like:

ghost commands don't work inside of a clone or download, did you mean gulp?

Refactor task list to only show one task at a time

After the ES6 refactor, the most complex CLI commands were refactored to use listr - a pretty awesome module for rendering task lists with statuses, as well as cleaning up a lot of the promise chaining behavior.

However, the current rendering module it uses by default (this one) can have UX issues when on a slow terminal connection (e.g. SSH connections to servers overseas). Basically because it renders (and re-renders) the entire task list every cycle, it can sometimes appear to be "flashing", e.g. noticeably disappearing and then reappearing, which isn't super great for UX.

I will open an issue on the relevant repository to see if there's willingness to implement this as a custom option; however if not then it will need to be manually implemented here.

Could be important, because of prompts to the user!

ghost update problem

trying to upgrade to 1.0.0-alpha.10 from 1.0.0-alpha.09 but get the following error with 'ghost update' in my ghost folder
expecting an array or an iterable object but got [object Null]

Linux Ubuntu 16.04 LTS 64-bit
[email protected]
node v4.2.6

Install UX & Handling multiple installs

As I'm testing Ghost-CLI, I have a whole bunch of folders where I've used it to install Ghost.

Whenever I install a fresh version, or start one of my existing versions I don't get any information as to how I can go about accessing the version of Ghost that I just installed or started.

E.g. doing a fresh ghost install local outputs:

✔ System is running supported version of node
✔ Current folder is writeable
✔ Setting up the Ghost installation structure
✔ Downloading and installing Ghost
✔ Starting Ghost instance
Finished!

However, I don't now know how I can access Ghost (and in fact we don't really know if Ghost is running). This is in part due to the fact that the concept of multiple installs isn't really covered just yet.

E.g. because I know Ghost, I know that the version I just created is now running at http://localhost:2368/, and I can visit that and see my brand new blog 🎉 .

If I now test the cli again, in a new directory, running ghost install local again outputs the exact same thing. If I navigate to http://localhost:2368/, I see a blog, but I don't know which one. This has been a problem for me, not knowing where to go to run ghost stop!

I believe that in the current version, the 2nd (or 3rd..) blog won't start because the port is in use. My expectation as a user would be that the cli would start Ghost for me on an available port, and tell me what port it used. I realise that's probably not the simplest thing to implement, so lets start by improving the messaging and the bigger features can be implemented later.

  • When starting Ghost, output the URL that the blog can be accessed from
  • Correctly detect if the blog started (#61) if the blog failed to start due to an already running Ghost instance, output a sensible error message

Optimising for multiple-installs (to do later!!!!)

  • Ensure that when we run Ghost, we use a process name or some other way so that we can find where the managed instances come from (e.g. what folder they were installed in)
  • Add ghost kill-all as a command that will find all managed processes and kill them -> this is ghost stop
  • Implement port-finding when installing Ghost, cycling up from 2368
  • Optimise ghost install to only download ghost once and cache it
  • Optimise ghost install to only download dependencies once (use Yarn?!?)

Fix update command UX

Noticed this when fixing #168 -> there's some odd behavior that's going on with the update command when you pass the --rollback or --force options, or when an version folder already exists.

Also, if there are no versions available for ghost update to install, a more sensible error should be output.

Kate Note: Austin will research again what was odd here.

Update nginx config to handle subdirectory installs

Our configuration of nginx will need to do extra trickery if the url of a blog is configured to use a subdirectory.

Also wanted to leave a note here about the idea of having nginx config template files easily accessible in the repo, and swapping template vars in, instead of programmatically building the file.

This improves readability/understandability of what ghost-cli does, and gives us a very simple logging fall back if we run into an issue where we can't write the config automatically.

E.g. if there's already a config file or the perms are wrong, we can log the template file and tell users to update their config to match this manually.

`ghost uninstall` command

With the introduction of services, the nginx and systemd services now add files elsewhere in the system that complicate uninstalling a blog (meaning you can't just rm -rf /your/ghost/blog).

Ghost uninstall will first stop everything, then call each service that needs to cleanup something, then delete everything from the directory it's in.

Also, ghost uninstall will ask if the user is super-duper mega extra sure if they want to remove their blog because there's no going back afterwards.

The only thing that won't be cleaned up after an installation is the database if it's mysql. In theory we could use knex-migrator reset to do it, but I'm not sure that's really necessary? People might want to delete a blog and keep all the data.

SSL setup is not working

I've tried getting the SSL part of the setup working, but every time I try it, I get the following error:

? Do you want to set up your blog with SSL (using letsencrypt)? Yes
? Enter your email (used for ssl registration) [email protected]
✖ Getting SSL certificate
A ProcessError occured.

Error occurred running command: '/bin/sh -c /usr/bin/nodejs /usr/local/lib/node_modules/ghost-cli/node_modules/.bin/greenlock certonly --agree-tos --email ****@gmail.com --webroot --webroot-path /var/www/ghost/root --config-dir /etc/letsencrypt --domains ******.dk --server https://acme-v01.api.letsencrypt.org/directory'

Exit code: 1

Debug Information:
Node Version: v4.2.6
Ghost-CLI Version: 1.0.0-alpha.14
Environment: production
Command: 'ghost service nginx-ssl ****@gmail.com'

Ghost Doctor improvements

When speccing out the CLI and its requirements, one of the bigger ones was ensuring that the CLI would have the least chance of failure when installing or updating Ghost. This will hopefully reduce the number of support requests that have to be addressed. 😄

First, we are establishing the idea of an "official" Ghost stack (see TryGhost/Ghost#7414). However, because there are still oddities that can happen, even with an official environment, more things are needed to ensure the greatest chance of install/update success.

Thus, the ghost doctor command exists. This command is designed to run several checks on the system before anything major happens, and the hope is to catch any potential errors before they happen so a more clear error message, as well as a path to fixing/avoiding the errors, can be output.

The ghost doctor command also has a concept of "categories", which determine when the specific check is to be run. Essentially, it has one set of checks to be run before installing Ghost for the first time, one set to run before starting ghost, and another set to be run before attempting to update Ghost.

There are already several checks in ghost doctor that were copied over from the Ghosts' startup check file. However, there are more that need to be created. They are sorted by category here for convenience

Install Checks (to be run before ghost install does anything)

  • check system node version (already completed)
  • check file permissions (already completed)

Startup Checks (to be run before ghost start)

  • Validate Config (see #26)

Future improvements!

Although NPM generally does a pretty good job of installing the dependencies that Ghost requires, there are on occasion various glitches that result in different dependencies not being installed correctly. This check would recursively iterate through each dependency and ensure all of the dependencies are installed correctly.

Ghost generally takes ~ 100mb of memory to run well, and just as a sanity check it would probably be a good idea to ensure there is enough free memory on the system to run Ghost. (Node's os module has a freemem() method that should work for this purpose

Update Checks (to be run before ghost update)

- [ ] System has enough memory to run NPM (requires additional research)

NPM itself can eat up a lot of system memory, and what we don't want to happen is for npm to eat up too much memory and end up crashing an already-running Ghost blog. Similar to the above memory check, the os.freemem() method can be used, but additional research is required to see just how much memory npm uses.

With the switch to Yarn in #138 - the install process uses significantly less memory, making the necessity of this probably not as great.

Tasks

See also comment notes.

prio

  • test current state of the permission checks PR #613
  • detect installations with root -> this is wrong (only for install checks, never for update) PR #604
  • detect if somebody is running sudo ghost start PR #604
    • doing this in the Command base class, detect process.uid = 0
  • content folder permission PR #610
    • run on ghost start
    • if content folder is not owned by ghost, skip
    • all subfolders of the content folder need to be owned by ghost
    • all file & folder permissions need to be correct - see #294 for which permissions should be set
    • also, check error messaging when content folder is not owned by ghost

later

  • repair permissions, #317 and #294
  • memory detection before ghost update (relates to #192)
  • [optional] Check installed dependencies -> needs spec cc @acburdine
  • make it possible to run doctor checks for extensions
  • check that cronjob was configured correctly #554
  • auto-run ghost doctor before specific commands (be able to disable it) -> do after we're able to group tasks for different commands
  • be able to skip the doctor (see here and here)
  • similar to root user prevention, detect when a user installed Ghost as ghost and/or is logged in as such. See here -> PR #659 & 657
  • check .ghost-cli permissions and ownership. See here
  • check /versions directory permissions and ownership. When updating ghost and removing older versions, it might fail
  • detect when logged in user is not the owner of the ghost installation folder and/or the logged in user is not part of the group of the owner user. -> PR #659
  • detect wrong symlink permissions (#737)
  • https://forum.ghost.org/t/trying-to-upgrade-from-1-8-6/2318/14

[alpha.19] 'ghost ls' not showing proper status

Issue Summary

'ghost ls' command does not show my production instance running. It works okay for development.

Steps to Reproduce

  1. Install alpha.19 and setup for both production and development
  2. ghost start
  3. ghost ls

Technical details:

Ghost Version: alpha.19
ghost-cli Version: 1.0.0-alpha.16
Node Version: v6.10.0
OS: Debian 3.16.39-1+deb8u1
Database: MariaDB 10.0.29 & SQLite3

Log

ghost@ghost:/var/www/ghost$ ghost start
 ✔ Validating config
✔ Starting Ghost
You can access your blog at http://192.168.1.75:2368/
ghost@ghost:/var/www/ghost$ ghost ls
┌──────────────┬────────────────┬─────────┬─────┬──────┬─────────────────┐
│ Name         │ Location       │ Status  │ Url │ Port │ Process Manager │
├──────────────┼────────────────┼─────────┼─────┼──────┼─────────────────┤
│ 192.168.1.75 │ /var/www/ghost │ stopped │ n/a │ n/a  │ n/a             │
├──────────────┼────────────────┼─────────┼─────┼──────┼─────────────────┤
│ ghost-local  │ /var/www/ghost │ stopped │ n/a │ n/a  │ n/a             │
└──────────────┴────────────────┴─────────┴─────┴──────┴─────────────────┘

ghost@ghost:/var/www/ghost$ ghost stop
✔ Stopping Ghost
ghost@ghost:/var/www/ghost$ ghost -D start
 ✔ Validating config
✔ Starting Ghost
You can access your blog at http://192.168.1.75:2367/
ghost@ghost:/var/www/ghost$ ghost ls
┌──────────────┬────────────────┬───────────────────────┬───────────────────────────┬──────┬─────────────────┐
│ Name         │ Location       │ Status                │ Url                       │ Port │ Process Manager │
├──────────────┼────────────────┼───────────────────────┼───────────────────────────┼──────┼─────────────────┤
│ 192.168.1.75 │ /var/www/ghost │ stopped               │ n/a                       │ n/a  │ n/a             │
├──────────────┼────────────────┼───────────────────────┼───────────────────────────┼──────┼─────────────────┤
│ ghost-local  │ /var/www/ghost │ running (development) │ http://192.168.1.75:2367/ │ 2367 │ local           │
└──────────────┴────────────────┴───────────────────────┴───────────────────────────┴──────┴─────────────────┘
ghost@ghost:/var/www/ghost$ cat ~/.ghost/config
{
  "instances": {
    "192.168.1.75": {
      "cwd": "/var/www/ghost"
    },
    "ghost-local": {
      "cwd": "/var/www/ghost"
    }
  }
}
ghost@ghost:/var/www/ghost$ cat config.production.json
{
  "url": "http://192.168.1.75:2368/",
  "pname": "192.168.1.75",
  "server": {
    "host": "192.168.1.75",
    "port": 2368
  },
  "process": "systemd",
  "database": {
    "client": "mysql",
    "connection": {
      "host": "localhost",
      "user": "root",
      "password": "*******",
      "database": "ghost_prd"
    }
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "auth": {
    "type": "password"
  }
}
ghost@ghost:/var/www/ghost$ cat config.development.json
{
  "url": "http://192.168.1.75:2367/",
  "pname": "ghost-local",
  "server": {
    "host": "192.168.1.75",
    "port": 2367
  },
  "process": "local",
  "database": {
    "client": "sqlite3",
    "connection": {
      "filename": "/var/www/ghost/content/data/ghost-local.db"
    }
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  }
}

Always inform user when sudo is required

Because of the nature of some of the setups (systemd, nginx configuration), sometimes a sudo-level command must be run by the CLI. To be as transparent and clear (e.g. not confusing) as possible, any CLI action that requires sudo access should first log and inform the user as to what is being done.

If verbose output is not turned on, just a basic description should be logged, e.g. "Systemd configuration is being moved into place, you may be prompted for your password". However, if verbose logging is enabled, the actual command should be logged as well.

Move away from commander.js for handling command line args & options

When Ghost-CLI was first designed, commander.js was used to handle args & options because it was one of the more popular solutions out there, and is fully featured.

However, as the CLI has evolved, certain requirements that commander.js enforces make it no longer a useful/viable solution for handling command line params. The main one is that commander must know about all possible arguments and options prior to running the command, leaving little to no room for custom options added by other commands, or by services (for example, the strictness of this requires lines like this one).

It also requires parsing args and options config and then converting it to a string, which then gets converted back into options in commander.js (see this code).

The one big pro that commander.js does provide is automatic generation of help text for commands like ghost help install or ghost install --help. However, it would be trivial to manually implement this in the CLI itself

The two big alternatives to commander that I've seen used in a lot of places are:

  • minimist - This provides very little in the way of automatic enforcement of args/options, but allows for the greatest configurability
  • yargs - This provides the same features as minimist re: basic arg parsing, and also allows for greater enforcement of correct args if wanted. This library also seems to be more active than either commander.js or minimist

Current issues with updating

Warning, I'm not sure of the status of these 2 bugs, they might be fixed in the unreleased master?

  1. I get the following error when trying to run ghost update in a folder where I've already updated:

  1. @frantzypants is getting this error when trying to update:

screen shot 2016-10-03 at 12 07 20 pm

Would be awesome if these are fixed before alpha.3 as both of us are stuck ;)

Check if Ghost process died

I am starting Ghost with ghost start.
It shows me ✔ Starting Ghost instance.
But Ghost is not running, because the process died.

Suggestion: Ensure process is alive for X and show Error if process died.

help dialog

I think it would be great if the "ghost -h" help would we displayed when no parameter is provided.

Error Handling

Currently the method of outputting errors to the console is done using basic console.log/console.error calls.

There should be a utility that all the commands use to report errors. If we ever want to do i18n in the future this will be necessary as well.

It would be even better if this were extended to handle basic output (aka non-error messages) as well.

Standardize NODE_ENV handling across CLI

Currently, there are several places throughout the application where an environment (i.e. 'development' or 'production') is provided via an option or something similar. The environment specification should be done in one place rather than in all the distinct places it's parsed from.

Attempt to start new version of Ghost during `ghost update`

The current update process works as follows:

  • Download new Ghost version & install dependencies
  • Stop current Ghost
  • Update symlinks
  • Start new Ghost

However, if an issue occurred during the installation of the new Ghost version, that issue won't be discovered until the blog is restarted, leaving your blog in an offline state. This is especially critical for automatic/one-click updates, as the user won't be running the update through the traditional means.

So the idea is to start the new version of Ghost on a different port temporarily before stopping & starting Ghost. This should be fairly simple, and there is already a library (portfinder) in Ghost-CLI that can be used to find an open port.

However, this will involve some other thinking - namely how to start the new version of Ghost with the same content, without messing with the current live database. With SQLite this should be pretty easy - just create a copy of the DB file, however if the user is using a MySQL database it might be a little trickier. Definitely needs some thought - as we don't want to just implicitly require that a sqlite database exist.

Kate Note: This is only related to one click updates!

Services API

Within Ghost-CLI there are currently several "concepts":

  • commands - full commands that have arguments and options
    • e.g. ghost install, ghost start etc.
  • tasks - self-contained functions reused between commands
  • process managers - ways of running ghost

These concepts work for most of the usages of the CLI, however there are several things the CLI still needs to do that don't fit into a particular category. The main ones (listed in #64) are setting up nginx and ssl. Both of these things are not super complex, but still need things done at specific times during various commands.

So, to encapsulate & abstract some of the operations and setup of nginx and ssl (and whatever else may come or be needed), there is going to be an additional concept added to the CLI: Services


Design

  • Hooks
    • Services should be able to hook into various CLI commands to do various things
      • example: during ghost setup an nginx/ssl service should be able to set up various config files
  • Commands
    • while adding commands to the root of ghost might be tricky due to the need to resolve external commands, so we should potentially add a ghost service command which could handle installation of external services (ghost service install) as well as any custom commands that a provider might define
      • example: ghost service ssl for an ssl provider might call the letsencrypt renew function. This could be set as a cron task to run every so often.

Resolution

Because services would be installed globally, there needs to be a resolution process that is able to reliably find all of the globally installed services and load them. This is not a trivial process - Yeoman accomplishes it using a sort of "guess and check" method (see this file for how it's done). With the introduction of Yarn, however, there can be now be multiple places that globally installed modules are actually installed. (yarn installs all of its global modules in a different location than that of npm by default)

So, here's the thought for resolution: ghost service install would install a service globally using yarn. Instead of installing it to yarn's default global node_modules folder, it would instead place it inside a folder in the user's HOME directory, as well as adding the service to a config file in the same folder. That way, there is one place that all the providers are installed, making the resolution process much less of a guess, and therefore (hopefully) much faster.

This resolution process would be extended to process managers as well, in a sense making them a special type of service, in a sense.


TODOs

  • Short-term
    • build out initial api in the CLI itself
    • Add nginx and ssl service so that they are present in every install of the CLI (pr - #159)
  • Long-term
    • extract base service into a separate NPM module
    • move nginx and ssl service into separate npm modules - still required by Ghost-CLI though
    • build out resolution process

`ghost ls` process list should maintain list of blogs even if they're stopped

Currently, ghost instances (installed via the CLI) are registered when they are started (via ghost start) and de-registered when they are stopped (via ghost stop). Ultimately, this means that the blogs that show up in ghost ls are only the ones that are running at the given moment.

This works for most single-blog setups, but is difficult when you've installed multiple blogs on the same system, some of which are running and some of which aren't. Currently it's impossible to tell where the blogs are that aren't running.

So, ghost ls should be extended to show blogs regardless of whether or not the blog is running, as well as the actual running status.

More UX Improvements

This issue tracks some of the necessary UX updates that need to go into Ghost-CLI before 1.0

  • ghost start detection of config file.

Currently, ghost start runs in production, and ghost start -D runs in development, which is the same as all of the other ghost commands. While this makes sense, it can be somewhat confusing when you install ghost via ghost install local, run ghost stop and then run ghost start again. While the config validation (see #26) will make ghost start fail should the file not exist, the ghost start command should be smart enough to detect what config files exist, and default to the existing one (be it production or development). If both a production and a development config exist, ghost start will behave as before.

More coming...

Install/Setup/Update UX improvements

(goes side-by-side with #3)

At the moment, the UX of ghost install is somewhat lacking in functionality and ease-of-use. The biggest issues at the moment are:

  • There is no way to bypass the prompts in ghost install - making running the install command autonomously impossible
  • Recovering after a failed update or install is difficult (& confusing) because of some of the checks that ghost update and ghost install have
  • Ghost install is rather complex in what it all covers, and it is impossible to not run various steps, e.g. the config setup and the "Do you want to start Ghost" prompt
  • Viewing any of the internal things that the CLI is doing is difficult (while this is not necessary for general users, it can be helpful for developers when debugging install issues)

There are several steps that need to be taken to solve these three issues:

  • Addition of a --force command line option for ghost update

The biggest problem with failed updates is when npm fails to correctly install. When that happens, there are occasionally leftover artifacts that need to be removed (for example: a package.json file or node_modules directory in the main install root, or a version of Ghost that wasn't symlinked/installed correctly).

A force option would clear all of these potential leftover artifacts and then proceed with a normal install or update. What it would not do is clear any of the content folder or configuration - there could potentially be other commands to do that but we want to preserve all of the user's data. Plus, the content folder normally doesn't cause install or update failures, so there's no need to clear it 😄

  • Split up ghost install into ghost install and ghost setup with a --no-setup flag in ghost-install

ghost install currently sets up the ghost-cli necessary folders, then downloads and installs ghost from npm, then prompts for config & start parameters. In the future, there will need to be more things setup such as an nginx/apache config or ssl configuration. Doing all of this inside of ghost install will be tricky, especially when it becomes necessary to disable any user interaction (for autonomous installation).

So, the idea is to have ghost install take care of only setting up the install structure and downloading/installing Ghost. A second command, ghost setup, will be used to take care of initializing the config (via ghost config) and setting up whatever nginx/apache/ssl/etc configuration needs to be done on install. Additionally, an option would be added to the ghost install command that would allow the ghost setup command to be bypassed.

  • Add additional verbosity to the cli output with a --verbose flag

Currently, ghost-cli outputs only a list of steps along with a spinner to indicate progress. When this new flag is not specified, the behavior will remain the same. However, with the addition of this flag, the steps will be added to by a more verbose output (e.g. outputting the results of npm install to the console instead of suppressing it).

Can't currently get a local install with `ghost install local`

I'm having what I think is a cascading set of problems when trying to run ghost install local.

First I get this error, which is intended for production installs:

Then if I try to run ghost setup --no-stack to try to make it work, I'm being prompted for mysql config, when a local install is intended to use sqlite3.

Finally, if I try to ghost start to see if I can get it running anyway, I get a big ol' error:

/bin/sh: systemctl: command not found
child_process.js:508
    throw err;
    ^

Error: Command failed: systemctl start ghost_localhost
    at checkExecSyncError (child_process.js:465:13)
    at execSync (child_process.js:505:13)
    at CoreObject.start (/usr/local/lib/node_modules/ghost-cli/lib/process/systemd/index.js:45:9)
    at CoreObject.module.exports.Command.BaseCommand.extend.execute (/usr/local/lib/node_modules/ghost-cli/lib/commands/start.js:44:32)
    at Command.wrapCommand (/usr/local/lib/node_modules/ghost-cli/lib/commands/index.js:105:56)
    at Command.listener (/usr/local/lib/node_modules/ghost-cli/node_modules/commander/index.js:301:8)
    at emitTwo (events.js:87:13)
    at Command.emit (events.js:172:7)
    at Command.parseArgs (/usr/local/lib/node_modules/ghost-cli/node_modules/commander/index.js:615:12)
    at Command.parse (/usr/local/lib/node_modules/ghost-cli/node_modules/commander/index.js:458:21)
    at cli (/usr/local/lib/node_modules/ghost-cli/lib/cli.js:28:13)
    at Object.<anonymous> (/usr/local/lib/node_modules/ghost-cli/bin/ghost:10:22)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)

Ensure advanced config parameters are passed correctly from the `ghost install` command

When I try to deploy ghost with somes parameter :

ghost install -d blog --db mysql 1.0.0-alpha.1
output log :
ip undefined
port undefined
db undefined
dbpath undefined
dbhost undefined
dbuser undefined
dbpass undefined
dbname undefined
? What is your blog url? http://test.com
Finished!

$cat config.production.json 
{
  "url": "http://test.com"
}

And when y launch config under the folder previously created :

ghost config --db mysql
output log :
ip undefined
port undefined
db mysql
dbpath undefined
dbhost undefined
dbuser undefined
dbpass undefined
dbname undefined
? What is your blog url? http://test.com
Finished!

$cat config.production.json 
{
  "url": "http://test.com",
  "database": {
    "client": "mysql"
  }
}

`ghost install` default behaviour

The ghost install command is intended to create a fully-working production blog:

I think the main pieces to this are:

  • collect a URL to replace my-ghost-blog.com
  • Parse collected URL to ensure port is set correctly
    - ensure logs go somewhere sensible (preferably /var/log/) see #42
  • use MySQL as the database
  • use systemd to manage starting/stopping Ghost

Nice to haves:

  • Provide for configuring nginx
  • Provide for configuring SSL

RFC: Updating Ghost-CLI to use Yarn rather than NPM

In an effort to speed up install times and reduce issues/errors with npm install (especially where memory usage is considered), I did some research into potentially moving to Yarn instead, and here are the results of that research/experimentation.

The first issue was that yarn doesn't output json correctly on yarn info, but that has been fixed as of yarn 0.18.

The biggest issue/hurdle to overcome is that yarn does not take into account the yarn.lock file of dependencies that it's installing. This makes sense from yarn's perspective, as to do so would mean inspecting the contents of the npm package before downloading, which would be a huge pain. However, this means that any attempt to install Ghost directly would not use the yarn.lock and just install whichever dependencies it finds initially.

The second issue is that a direct yarn install installs each dependency into the root node_modules folder and then links them into all of the subfolders. While this doesn't necessarily prevent things from working, it does make things a bit more complex considering the current method of installing ghost via npm and then copying it into the correct version folder.

To address both these issues, I propose this solution:

The install process would go back to kind of what it was before the switch to npm-installed ghost, and instead of using npm to download the built Ghost file, the download capability would be built directly into the CLI. The download itself could come from npm/yarn itself (the packaged tar.gz file) or Github (the built zip). Personally I'd recommend the npm package, as it's in the same location each time and doesn't require messing around with Github's api. Also, I think yarn has an ability to show the location of a npm package download based on the version and package name? (needs more research).

Once the ghost package is downloaded/placed in the right version folder, then yarn install --production would be run inside of the downloaded Ghost folder.

So, in summary:

Pros:

  • faster install times (in theory)
  • less memory usage (especially when compared to npm@3)
  • bypass npm shrinkwrap idiosyncracies between npm major versions

Cons:

  • Makes the CLI install process a little more complex
  • installing yarn via npm is currently deprecated (I think? needs more research)

TODOs (if this is to be done)

  • Add the yarn.lock file to Ghost itself (and ensure they are included in the release build)
  • Re-build install/update processes
  • all the testing

More needed research:

  • yarn programmatic API (does it exist? any way to get install process completion percentages?)
  • yarn install avenues (npm?)
  • does yarn global add ghost-cli use the lockfile (if one were to be included with ghost-cli)?

Clearer explanation for `ghost start` vs `ghost run`

    restart                         Restart the Ghost instance
    run                             start a managed ghost process
    service <command> [args...]     run a service-defined command
    setup [options]                 setup an installation of Ghost (after it is installed)
    start                           starts an instance of Ghost
    stop [options]                  stops a named instance of Ghost

The difference between run and start isn't very clear. Although start/stop/restart follows the normal pattern, so it's reasonably obvious which one I should use, but I almost think run doesn't need help output?

Surely the only people who ever need run are people developing process managers?

Cannot find module 'lodash/foreach'

npm install -d somedir...
triggered this error : Cannot find module 'lodash/foreach'

I try this on my repo each = require('lodash/foreach'), to each = require('lodash/forEach'),
line updated
and that work fine, I don't make a pr because I update somes others things.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.