# Deployment  All Gadget apps come with a single, performant production environment that hosts the version of your application that your end users interact with. The production environment is fully separate from development, and has its own database, configuration, and snapshot of your code. You cannot directly edit the production environment's code, models, or settings. Instead, you can make changes in a development environment and deploy them to the production environment. This allows you to safely update your app without affecting your users. You can deploy from any development environment to the production environment with just one click. For more details, refer to the [environment documentation](https://docs.gadget.dev/guides/environments). ## Deploying changes to production  There are two ways to deploy changes from a development environment to production: 1. Using the Gadget editor * Click the **Deploy** button in the header of the Gadget editor. * Click the **Deploy** button in the header of the Gadget editor. 2. Using the CLI * Run `ggt deploy` in your terminal. For more details on using the CLI, refer to the ggt documentation. * Run `ggt deploy` in your terminal. For more details on using the CLI, refer to the ggt documentation. ```bash // in deploy using the ggt CLI ggt deploy --app= --env= ``` For more information on deploying with `ggt`, [read the reference docs](https://docs.gadget.dev/reference/ggt#ggt-deploy). ### What happens during deployment  When you deploy, Gadget will: * check for issues with database consistency, for example, a newly added uniqueness validation that would fail on production data * run any required database migrations * bundle and minify frontend assets * build containers for your app frontend and backend * deploy these new containers * restart your production app Your app's users will not experience downtime during this process. New features and bug fixes will be delivered to your production app immediately after deployment has completed. ## Issues found  Gadget flags potential issues that could break your app if you deploy to production. These issues are found in the Gadget editor's deploy modal. You can choose to **Force deploy** in the deploy modal to ignore these issues and continue with the deployment. If deploying using `ggt`, a deployment with problems will fail unless the `--allow-problems` flag is used. The following sections detail the issues you can encounter before deploying and how to fix them. ### Issue: Problems in development  The _Problems in development_ issue highlights any broken code or errors found in your development environment that you are about to deploy to production. Click on the issue in the deploy modal to open the problems drawer. The problems drawer will list the issues found in the development environment that you are about to deploy to production. #### Addressing production problem  If you have deployed problems to your production environment a red icon appears next to the Deploy button. 1. Click on the icon to view the problems. 2. Resolve the issues in your development environment and deploy your fix. ### Issue: Avoid Gadget development credentials in production  Gadget offers development API keys/client credentials to help you kickstart your projects. These keys and credentials should be replaced with your own for the production environment. We recommend using your own credentials in production for the following reasons: | Credential | Reason to use your own in production | | --- | --- | | Google OAuth credentials | Shared among all Gadget users, the auth approval will say "Gadget development apps". | | OpenAI API key | Has a $50 credit limit which can quickly run out in production. | Click on the issue in the deploy modal to redirect to the appropriate interface in production to add your own keys or credentials. ### Issue: Missing credentials in production  Credentials powering plugins are unique to each environment. If you have recently added a plugin with credentials to your development environment, you need to make sure production has the credentials to run that plugin before you deploy. ### Issue: TOML does not match your production config  The configuration in your production `shopify.app.toml` file does not match your production environment's Shopify connection configuration. This can occur when the TOML file is manually edited. To fix this issue, you can manually edit your production environment's TOML file to match your production Shopify connection configuration. ### Issue: Empty production TOML file  The `shopify.app.toml` file for your production environment is empty and does not match your production environment's Shopify connection configuration. To fix this issue, you can manually edit your production environment's TOML file to match your production Shopify connection configuration. See the [`shopify.app.toml` docs](https://docs.gadget.dev/guides/plugins/shopify/advanced-topics/shopify-app-toml#development-environment-shopify-app-toml-files) for a TOML template. ### Issue: Missing production TOML file  The `shopify.app.toml` file has been deleted in your current development environment. To fix this issue, create a new `shopify.app.toml` file at your Gadget project root. ## Managing environment variables  [Environment variables](https://docs.gadget.dev/guides/development-tools/environment-variables) are unique to each Gadget environment and will not be managed with source control or when deploying to production. Check to make sure your production environment has the required environment variables set up before deploying. ## Data deleted on deploy  Deploying can cause data to be deleted. Before deploying, Gadget will warn you if your deployment will delete data. This can happen due to: 1. Deleting models or fields: Models and fields are tied to the database tables. Deleting them deletes the associated data. 2. Deleting and re-adding models or fields: Gadget assigns a unique identifier called a `storageKey` to every model and field, which is used to manage the underlying data. When you delete and re-add a model or field, Gadget creates a new `storageKey`, treating it as a completely new entity. On deploy, this results in the creation of a new, empty table or column in production, even if the API identifier is the same as before. * To manage `storageKeys`, run Gadget locally using `ggt`. Each model has its own `schema.gadget.ts` file where the `storageKeys` are listed. Keeping track of these keys will help ensure that your data remains intact during deployment. * To manage `storageKeys`, run Gadget locally using `ggt`. Each model has its own `schema.gadget.ts` file where the `storageKeys` are listed. Keeping track of these keys will help ensure that your data remains intact during deployment. Contact support to retrieve your production `storageKeys`. 3. Mismanaged `storageKey`: If you are using `ggt` to run Gadget locally, the `storageKey` set on fields and models found in `schema.gadget.ts` is used to serve its data. Editing or deleting this value will delete data from the associated table or column. ### Mitigating data deletion risks  To help prevent data deletion during deployment, we recommend the following: * Use source control: Run `ggt` and keep track of `storageKeys` to prevent unwanted data deletion. For more details, refer to the [source control documentation](https://docs.gadget.dev/guides/source-control). * Export production data: Before deploying, you can export your production data so it can be re-imported if necessary. ## Rollback a deployment  Gadget does not have built-in support for rolling back deployments. You can still rollback deployments by using `ggt` and git-based source control to manage your Gadget projects. To make sure that you can rollback to the previous state of production, you need to make sure that each production deployment has an associated commit in source control. If you have commits for each of your deployments and need to rollback to a previous deployment, you can: 1. Pull down the commit of the previous deployment you would like to rollback to on your local machine. 2. Use `ggt push` to apply all code and configuration to a Gadget development environment. 3. Deploy these changes using `ggt deploy` or the button in the Gadget editor. Data associated with model `storageKey` values is not fully deleted until 7 days after a `storageKey` is changed. This means that you can safely rollback with no data loss up to 7 days after making changes to a model. ### Rolling back with CI/CD  If you use a [CI/CD pipeline](https://docs.gadget.dev/guides/environments/ci-cd) to automate deployments, you can rollback by reverting to a previously deployed commit.