We will enable a local development workflow using docker under the hood.
The topic this proposal is shedding light on is how that exactly looks like in the CLI.
gc local up: Pull & Start a local Graphcool instance
gc local start: Start an already intialized local Graphcool instance
gc local pull: Pull the latest Graphcool version
gc local stop: Stop the currently running local Graphcool instance
gc local reset: Reset the local Project
.graphcoolrcThe .graphcoolrc would get a new "kind" of environment, called local:
default: dev
environments:
prod: cj7zy085306i50193k7ox16z4
dev: local
~/.graphcool{
"token": "...",
"local_token": "...",
"local_host": "localhost:60000"
}
So additionaly to token, there will also be local_token and local_host.
These values all can be overwritten by environment variables:
export GRAPHCOOL_TOKEN=...
export GRAPHCOOL_LOCAL_TOKEN=...
export GRAPHCOOL_LOCAL_HOST=...
There can be one local environment at the same time. When multiple local environments are needed, that orchestration can be achieved with managing the environment variables.
Add gc local restart command.
As @kbrandwijk suggested, it makes more sense for the local docker environment information to live in the .graphcoolrc file and not the .graphcool file as .graphcool is global and the local docker env information is project related.
With this change the files look as follows:
.graphcoolrcdefault: dev
environments:
prod: cj7zy085306i50193k7ox16z4
dev:
token: "..."
host: "localhost:60000"
projectId: c27zs08d30ai52683k7mx26a5 # temporary, will be removed soon
~/.graphcool{
"token": "..."
}
In general the proposal looks good to me. 👍 Here are a few questions:
gc local reset: Reset the local Project
What does this do exactly (step-by-step)?
export GRAPHCOOL_LOCAL_HOST=...
What does this refer to? What's the purpose of this hostname? What's the underlying network protocol for the intended usage?
I feel there might be something counter intuitive about the combination of environment definition and command. If the environment definition is: dev: local then I would expect gc up --env:dev or something etc. Unless the gc local commands get a --env parameter, then it also makes sense.
Would you be able to create more than one local enviroment?
Would this local docker environment play a role in automated testing?
How does deploying to this local environment work? Would you be able to do gc deploy --env dev with dev: local? Would the machine need to be up for that? Or would the docker container contain a reference to the local project folder, so explicitly deploying to your local environment would not be necessary?
Would you be able to deploy the docker container to a hosting provider, and would that basically be the self-hosted option?
~/.graphcool is not project specific. I don't think that these project-specific local environment settings belong there. They should probably go into the project directory.
What does this do exactly (step-by-step)?
We currently have 2 mutations for this:
resetProjectSchema
They would both be called. We could have 2 more fine-grained versions of the command with --data and --schema.
What does this refer to? What's the purpose of this hostname? What's the underlying network protocol for the intended usage?
This is the deployment endpoint that the CLI needs in order to deploy the project. Currently all endpoints are available on the :60000, we should separate them.
I feel there might be something counter intuitive about the combination of environment definition and command
The idea is, that you can have multiple local environments. So I agree, adding --env to the gc up command is then necessary. We can think about a default here like we do with the current init command.
Would this local docker environment play a role in automated testing?
That's an interesting question, I think it definitely could.
How does deploying to this local environment work?
Yes, the machine needs to be up for that. The CLI should handle it gracefully when deploy is executed without a running docker instance.
Would you be able to deploy the docker container to a hosting provider, and would that basically be the self-hosted option?
Yes, as people can deploy their docker stuff everywhere, this is the first minimal version of the self-hosted option. However, it's built for ease-of-use and not scalability.
~/.graphcool is not project specific. I don't think that these project-specific local environment settings belong there. They should probably go into the project directory.
That's a good point. We have to think about a better solution there.
I like this, I just want to add here that it's rather frustrating not even knowing the environment where functions are executed and what language features are supported. Especially that obscure "use latest" flag which is not really explained anywhere what it does. Is it a specific NodeJS version that runs that code?
Thanks for bringing that up @FredyC We definitely will make the function workflow much nicer soon :)
After having the first version implemented, we had some learnings that moved us to the following changes:
~/.graphcoolHaving the local docker environment information in the .graphcoolrc file mixes two concerns: The concern of configuring docker locally and the concern of where a project is deployed.
Because if this, we decided to put this information into the .graphcool file (which is now a YAML file):
token: secure-platform-token
targets:
dev-1:
description: This is your local docker dev environment
host: http://localhost:60000
token: my-docker-token
do-2:
host: https://12.235.235.124:60000/
token: my-remote-token
That means the .graphcool file will turn into yaml as well. This makes it more consistent with the .graphcoolrc and graphcool.yml.
gc deployWe will rename the args for gc deploy. Instead of providing a project with -p, we will rename it to --target. This makes it easier to point either to the local docker version or to the hosted version of Graphcool.
With gc deploy --target dev-1 the project will be deployed to the local docker instance.
With gc deploy --target cj8fyu5wl0000jnom2muqv9sl you can point to a normal project id.
gc deploy command interactiveIn order to make choosing the deployment target easy, the gc deploy command will add an interactive dialog asking where to deploy. When enough args are provided, this dialog will be bypassed.
gc env commandTo make things easier, we will remove the gc env command as it is providing more confusion than any value. If you want to edit the local environments setting, just edit the .graphcoolrc directly.
gc localThe following commands will be added:
gc local eject: Puts the docker-compose.yml and .envrc in the current folder. From here on you are on your own and can do customizations if needed.gc local ps INSTANCE_NAME: List all running containers of an instancegc local ls: List all local instances.Update: ~/.graphcool and .graphcoolrc file will be merged into a global & local .graphcoolrc file.
interface Root {
platformToken?: string
defaultTarget?: string
targets: { [name: string]: Target }
}
type Target = ServiceId | DockerTarget | PlatformTarget
type ServiceId = string
interface DockerTarget {
description?: string
host: string
token: string
}
interface PlatformTarget {
description?: string
serviceId: ServiceId
}
gc authWrites platformToken to global .graphcoolrc file
gc local up --target/-tSets up a new local docker service (or docker-compose ups the existing one) with the target name -t.
Warning when override global property and used (e.g. platformToken or concrete target)
A target name (e.g. digitalocean or prod - see below) can reference other already existing targets. The default target has a special role here since it will be used when running gc deploy and specified in the .graphcoolrc file.
.graphcoolrc fileplatformToken: secure-platform-token # retrieved via `gc auth`
targets:
dev:
description: This is your local docker dev environment
host: http://localhost:60000
token: my-docker-token
digitalocean:
host: https://12.235.235.124:60000/
token: my-remote-token
targets:
default: dev # `default` is a magic key that can reference other targets
prod: cj8g62nxg0000um3t0z64ls08
# deploy to default target
gc deploy
# deploy to prod
gc deploy --target prod
# deploy to digitalocean via shortcut argument
gc deploy -t digitalocean
What's the difference between platformToken and token?
What's the difference between platformToken and token?
token will be renamed to platformToken to avoid confusion with the token needed for "Docker Targets".
Regarding removal of the graphcool env command. The only part of that command I find useful is setting the default environment, because it is used in many commands (including graphcool playground and graphcool console). For graphcool deploy, I think the environment/stage should always be explicitly specified, but for other commands, a default environment is still very useful, and there should be an easy way to set it, other than manually editing the environment file.
I want to get one thing straight here. You are using gc everywhere in here. Does it mean that current cli command graphcool will be replaced by gc or are us using it like alias here for brevity?
You can already use both graphcool and gc, ever since the first cli version.
Interesting, where is that actually mentioned? Should be in official beta docs ... https://docs-next.graph.cool/reference/graphcool-cli/commands-aiteerae6l
Although it feels strange to have two identical commands, I guess it's not a big deal. I am wrapping all important tasks in package.json scripts anyway, so I don't care about saving couple of extra characters :)
A lot of cli commands have a 'shorthand' version, like wt is shorthand for wt-cli for webtasks, serverless has serverless, slss and sls etc.
Yet another update: Given the multi-service cluster format (see #748) we're adjusting the .graphcoolrc file and gc deploy command to work with clusters.
.graphcoolrc root fieldsinterface Root {
platformToken?: string
clusters?: { [name: string]: Cluster }
// example target: `shared-eu-west-1/cj8g62nxg0000um3t0z64ls08`
targets?: { [name: string]: string }
}
interface Cluster {
host: string
token: string
}
.graphcoolrc fileplatformToken: secure-platform-token # retrieved via `gc auth`
clusters:
default: local
# This is your local docker dev cluster
local:
host: http://localhost:60000
token: my-docker-token
digitalocean:
host: https://12.235.235.124:60000/
token: my-remote-token
targets:
default: dev # `default` is a magic key that can reference other targets
dev: dev/cj8g62nxg0000um3t0z64ls08
prod: shared-eu-west-1/cj8g62nxg0000um3t0z64ls08
# deploy to default target
gc deploy
# deploy to prod
gc deploy --target prod
gc deploy -t dev/cj8irw8v20000jm3t7fvalhfg
gc deploy -t shared-eu-west-1/cj8irw8v20000jm3t7fvalhfg
gc deploy --new-service my-service name --new-service-cluster shared-eu-west-1
.graphcoolrc and ~/.graphcool files.I completely lost it with regards to the 'services' and 'clusters' concepts. I've read #748 and #730, but I'm missing a substantial amount of pieces of the puzzle here.
This proposal is now implemented and released with version v0.7.0.
You can install it with npm install -g graphcool@next.
@kbrandwijk we will release more docs around this in the coming days!
Is gc local reset not supported yet?
$ gc --version
graphcool-framework/0.11.5 (linux-x64) node-v9.7.1
$ gc local reset
▸ local reset is not a graphcool-framework command.
▸ Perhaps you meant local restart
▸ Run graphcool-framework help local for a list of available commands.
Get in touch if you need help: https://www.graph.cool/forum
To get more detailed output, run $ export DEBUG="*"
Most helpful comment
This proposal is now implemented and released with version
v0.7.0.You can install it with
npm install -g graphcool@next.@kbrandwijk we will release more docs around this in the coming days!