(core) give instructions on using Grist with docker

Summary: cleans up docker build and instructions.

Test Plan: docker image and instructions tested manually

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2648
This commit is contained in:
Paul Fitzpatrick 2020-10-28 13:37:36 -04:00
parent d7802bc7db
commit 9287439e5a
6 changed files with 87 additions and 33 deletions

View File

@ -46,6 +46,9 @@ ADD ormconfig.js ormconfig.js
ADD bower_components bower_components ADD bower_components bower_components
ADD sandbox sandbox ADD sandbox sandbox
# Keep all storage user may want to persist in a distinct directory
RUN mkdir -p /persist/docs
# Set some default environment variables to give a setup that works out of the box when # Set some default environment variables to give a setup that works out of the box when
# started as: # started as:
# docker run -p 8484:8484 -it <image> # docker run -p 8484:8484 -it <image>
@ -53,7 +56,9 @@ ADD sandbox sandbox
ENV GRIST_ORG_IN_PATH=true ENV GRIST_ORG_IN_PATH=true
ENV GRIST_HOST=0.0.0.0 ENV GRIST_HOST=0.0.0.0
ENV APP_HOME_URL=http://localhost:8484 ENV APP_HOME_URL=http://localhost:8484
ENV GRIST_DATA_DIR=docs ENV APP_DOC_URL=http://localhost:8484
RUN mkdir -p docs ENV GRIST_DATA_DIR=/persist/docs
ENV GRIST_SESSION_COOKIE=grist_core
ENV TYPEORM_DATABASE=/persist/home.sqlite3
EXPOSE 8484 EXPOSE 8484
CMD npm run start:prod CMD npm run start:prod

View File

@ -5,14 +5,34 @@ robustness of a database to organize your data and make you more productive.
> :warning: This repository is in a pre-release state. Its release will be announced when it has > :warning: This repository is in a pre-release state. Its release will be announced when it has
all the planned components, and a solid independent build and test set-up. Currently, stand-alone all the planned components, and a solid independent build and test set-up. Currently, stand-alone
server functionality is present. Release of our web client is planned, along with an extensive server functionality is present, along with a single-user web client.
test suite.
This repository, [grist-core](https://github.com/gristlabs/grist-core), is maintained by Grist This repository, [grist-core](https://github.com/gristlabs/grist-core), is maintained by Grist
Labs. Our flagship product, available at https://www.getgrist.com, is built from the code you see Labs. Our flagship product, available at https://www.getgrist.com, is built from the code you see
here, combined with business-specific software designed to scale it to many users, handle billing, here, combined with business-specific software designed to scale it to many users, handle billing,
etc. etc.
## Opening and editing a Grist document locally
The easiest way to use Grist locally is with [Docker](https://www.docker.com/get-started).
From a terminal, do:
```sh
docker pull gristlabs/grist
docker run -p 8484:8484 -it gristlabs/grist
```
Then visit `http://localhost:8484` in your browser. You'll be able to create and edit documents,
and to import documents downloaded from the https://docs.getgrist.com host. You'll also be able
to use the Grist API.
To preserve your work across docker runs, provide a directory to save it in:
```sh
docker pull gristlabs/grist
docker run -p 8484:8484 -v $PWD/persist:/persist -it gristlabs/grist
```
## Why Open Source? ## Why Open Source?
By opening its source code and offering an [OSI](https://opensource.org/)-approved free license, By opening its source code and offering an [OSI](https://opensource.org/)-approved free license,
@ -38,25 +58,22 @@ Grist benefits its users:
include Grist in your pipeline. And if a feature is missing, you can just take the source code and include Grist in your pipeline. And if a feature is missing, you can just take the source code and
build on top of it! build on top of it!
## How do I start? ## Building from source
For building from source, you can start with this: Here are the steps needed:
npm install ```sh
npm run build:prod npm install
npm run install:python npm run build:prod
npm start npm run install:python
# unauthenticated grist api available at http://localhost:8484/api/ npm start
# unauthenticated grist client available at http://localhost:8484
# unauthenticated grist api available at http://localhost:8484/api/
```
Then you can use the Grist API locally to work on a document. Currently you need Then you can use the Grist client, or the API. You cannot (yet) edit Grist documents
to "upload" a document to work with it. This makes a copy of it that the server in place on your file system. All imported/created documents will appear in the `docs`
controls - you can find it in the `data` directory: subdirectory.
curl -F 'upload=@YourDocument.grist' http://localhost:8484/api/docs
# Note the document ID that is returned.
The [Data-Tables endpoints](https://support.getgrist.com/api/#tag/Data-Tables) are
particularly useful.
For using hosted Grist, just head on over to <https://www.getgrist.com>. For using hosted Grist, just head on over to <https://www.getgrist.com>.

View File

@ -222,6 +222,7 @@ export class FlexServer implements GristServer {
public addLogging() { public addLogging() {
if (this._check('logging')) { return; } if (this._check('logging')) { return; }
if (process.env.GRIST_LOG_SKIP_HTTP) { return; }
// Add a timestamp token that matches exactly the formatting of non-morgan logs. // Add a timestamp token that matches exactly the formatting of non-morgan logs.
morganLogger.token('logTime', (req: Request) => log.timestamp()); morganLogger.token('logTime', (req: Request) => log.timestamp());
// Add an optional gristInfo token that can replace the url, if the url is sensitive // Add an optional gristInfo token that can replace the url, if the url is sensitive
@ -335,7 +336,7 @@ export class FlexServer implements GristServer {
// Allow static files to be requested from any origin. // Allow static files to be requested from any origin.
const options: serveStatic.ServeStaticOptions = { const options: serveStatic.ServeStaticOptions = {
setHeaders: (res, filepath, stat) => { setHeaders: (res, filepath, stat) => {
res.header("Access-Control-Allow-Origin", "*"); res.setHeader("Access-Control-Allow-Origin", "*");
} }
}; };
// Grist has static help files, which may be useful for standalone app, // Grist has static help files, which may be useful for standalone app,
@ -385,7 +386,14 @@ export class FlexServer implements GristServer {
this.dbManager.setPrefix(process.env.GRIST_ID_PREFIX || ""); this.dbManager.setPrefix(process.env.GRIST_ID_PREFIX || "");
await this.dbManager.connect(); await this.dbManager.connect();
await this.dbManager.initializeSpecialIds(); await this.dbManager.initializeSpecialIds();
// If working without a login system, make sure default user exists.
if (process.env.GRIST_DEFAULT_EMAIL) {
const profile: UserProfile = {
name: 'You',
email: process.env.GRIST_DEFAULT_EMAIL,
};
await this.dbManager.getUserByLoginWithRetry(profile.email, profile);
}
// Report which database we are using, without sensitive credentials. // Report which database we are using, without sensitive credentials.
this.info.push(['database', getDatabaseUrl(this.dbManager.connection.options, false)]); this.info.push(['database', getDatabaseUrl(this.dbManager.connection.options, false)]);
} }

View File

@ -64,7 +64,7 @@ function timestamp() {
const fileTransportOptions = { const fileTransportOptions = {
stream: process.stderr, stream: process.stderr,
level: 'debug', level: process.env.GRIST_LOG_LEVEL || 'debug',
timestamp: log.timestamp, timestamp: log.timestamp,
colorize: true, colorize: true,
json: process.env.GRIST_HOSTED_VERSION ? true : false json: process.env.GRIST_HOSTED_VERSION ? true : false

View File

@ -1,16 +1,26 @@
{ {
"name": "grist-core", "name": "grist-core",
"version": "1.0.0", "version": "0.7.1",
"description": "", "license": "Apache-2.0",
"main": "index.js", "description": "Grist is the evolution of spreadsheets",
"homepage": "https://github.com/gristlabs/grist-core",
"repository": "git://github.com/gristlabs/grist-core.git",
"scripts": { "scripts": {
"start": "tsc --build -w --preserveWatchOutput & catw app/client/*.css app/client/*/*.css -o static/bundle.css -v & webpack --config buildtools/webpack.config.js --mode development --watch --hide-modules & NODE_PATH=_build:_build/stubs nodemon -w _build/app/server -w _build/app/common _build/stubs/app/server/server.js & wait", "start": "tsc --build -w --preserveWatchOutput & catw app/client/*.css app/client/*/*.css -o static/bundle.css -v & webpack --config buildtools/webpack.config.js --mode development --watch --hide-modules & NODE_PATH=_build:_build/stubs nodemon -w _build/app/server -w _build/app/common _build/stubs/app/server/server.js & wait",
"install:python": "buildtools/prepare_python.sh", "install:python": "buildtools/prepare_python.sh",
"build:prod": "tsc --build && webpack --config buildtools/webpack.config.js --mode production && cat app/client/*.css app/client/*/*.css > static/bundle.css", "build:prod": "tsc --build && webpack --config buildtools/webpack.config.js --mode production && cat app/client/*.css app/client/*/*.css > static/bundle.css",
"start:prod": "NODE_PATH=_build:_build/stubs node _build/stubs/app/server/server.js" "start:prod": "NODE_PATH=_build:_build/stubs node _build/stubs/app/server/server.js"
}, },
"keywords": [], "keywords": [
"author": "", "grist",
"spreadsheet",
"database"
],
"author": {
"name": "Grist Labs Inc.",
"email": "info@getgrist.com"
},
"private": false,
"devDependencies": { "devDependencies": {
"@types/backbone": "1.3.43", "@types/backbone": "1.3.43",
"@types/content-disposition": "0.5.2", "@types/content-disposition": "0.5.2",

View File

@ -4,6 +4,16 @@
* By default, starts up on port 8484. * By default, starts up on port 8484.
*/ */
// Set log levels before importing anything.
if (!process.env.DEBUG) {
// Be a lot less noisy by default.
setDefaultEnv('GRIST_LOG_LEVEL', 'error');
setDefaultEnv('GRIST_LOG_SKIP_HTTP', 'true');
}
// Use a distinct cookie.
setDefaultEnv('GRIST_SESSION_COOKIE', 'grist_core');
import {updateDb} from 'app/server/lib/dbUtils'; import {updateDb} from 'app/server/lib/dbUtils';
import {main as mergedServerMain} from 'app/server/mergedServerMain'; import {main as mergedServerMain} from 'app/server/mergedServerMain';
import * as fse from 'fs-extra'; import * as fse from 'fs-extra';
@ -19,13 +29,18 @@ function setDefaultEnv(name: string, value: string) {
} }
} }
// tslint:disable:no-console
export async function main() { export async function main() {
// Use a distinct cookie. console.log('Welcome to Grist.');
setDefaultEnv('GRIST_SESSION_COOKIE', 'grist_core'); if (!process.env.DEBUG) {
console.log(`In quiet mode, see http://localhost:${G.port} to use.`);
console.log('For full logs, re-run with DEBUG=1');
}
// There's no login system released yet, so set a default email address. // There's no login system released yet, so set a default email address.
setDefaultEnv('GRIST_DEFAULT_EMAIL', 'support@getgrist.com'); setDefaultEnv('GRIST_DEFAULT_EMAIL', 'you@example.com');
// Set directory for uploaded documents. // Set directory for uploaded documents.
setDefaultEnv('GRIST_DATA_DIR', 'data'); setDefaultEnv('GRIST_DATA_DIR', 'docs');
await fse.mkdirp(process.env.GRIST_DATA_DIR!); await fse.mkdirp(process.env.GRIST_DATA_DIR!);
// Make a blank db if needed. // Make a blank db if needed.
await updateDb(); await updateDb();
@ -34,6 +49,5 @@ export async function main() {
} }
if (require.main === module) { if (require.main === module) {
// tslint:disable-next-line:no-console
main().catch((err) => console.error(err)); main().catch((err) => console.error(err));
} }