# Publishing your docs > Publish your Fern docs to production and staging sites with automated workflows. Set up custom domains and manage deployments easily. When you are ready for your docs to be publicly accessible, publish them using the Fern CLI. Choose one of the following approaches: publish [only to a production site](#publish-to-production), or [to separate staging and production sites](#publish-to-staging-and-production). Use the [Fern Dashboard](https://dashboard.buildwithfern.com) to manage CLI access, connect your GitHub repository, and monitor analytics and broken links. ## Publish to production For a single production site (no staging environment), run the following command to publish your documentation: ```bash fern generate --docs ``` ```bash Example fern generate --docs [docs]: Found 0 errors and 1 warnings. Run fern check --warnings to print out the warnings. [docs]: ✓ All checks passed [docs]: Published docs to https://plantstore.docs.buildwithfern.com ┌─ │ ✓ https://plantstore.docs.buildwithfern.com └─ ``` Use a GitHub Action workflow to publish your docs when a push is made to the `main` branch. Use `fern token` to generate a token for authenticating the Fern CLI in CI/CD environments. The token is specific to your organization defined in [`fern.config.json`](/learn/sdks/overview/project-structure#fernconfigjson) and doesn't expire. ```bash fern token ``` Add the token as a [repository secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) called `FERN_TOKEN`. Create a Publish Docs workflow ([example](https://github.com/fern-api/docs/blob/main/.github/workflows/publish-docs.yml)), and reference the secret. ```yaml .github/workflows/publish-docs.yml maxLines=7 startLine=21 {21} name: Publish Docs on: push: branches: - main jobs: run: runs-on: ubuntu-latest if: ${{ github.event_name == 'push' && contains(github.ref, 'refs/heads/main') && github.run_number > 1 }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Fern run: npm install -g fern-api - name: Publish Docs env: FERN_TOKEN: ${{ secrets.FERN_TOKEN }} run: fern generate --docs ``` ## Publish to staging and production To preview changes on a staging site before publishing to production, define [multiple instances](/learn/docs/configuration/site-level-settings#instances-configuration) in your `docs.yml` file. Once you configure multiple instances, you must use the `--instance` flag when publishing. Add both staging and production URLs to your `docs.yml` file. Don't include `https://` in the URLs. ```yaml docs.yml instances: - url: plantstore-prod.docs.buildwithfern.com - url: plantstore-staging.docs.buildwithfern.com ``` Use the `--instance` flag to publish to a specific environment: ```bash # Publish to staging fern generate --docs --instance plantstore-staging.docs.buildwithfern.com # Publish to production fern generate --docs --instance plantstore-prod.docs.buildwithfern.com ``` After publishing, both instances will appear in the [Fern Dashboard](https://dashboard.buildwithfern.com). Use GitHub Action workflows to automatically deploy to staging on every push, while keeping production deployments manual. Use `fern token` to generate a token for authenticating the Fern CLI in CI/CD environments. The token is specific to your organization defined in [`fern.config.json`](/learn/sdks/overview/project-structure#fernconfigjson) and doesn't expire. ```bash fern token ``` Add the token as a [repository secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) called `FERN_TOKEN`. This workflow automatically publishes to your staging instance when changes are pushed to the `main` branch: ```yaml .github/workflows/publish-staging.yml maxLines=7 name: Publish Staging Docs on: workflow_dispatch: push: branches: - main jobs: run: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Fern run: npm install -g fern-api - name: Validate configuration run: fern check - name: Publish to Staging env: FERN_TOKEN: ${{ secrets.FERN_TOKEN }} run: fern generate --docs --instance plantstore-staging.docs.buildwithfern.com ``` This workflow allows you to manually trigger a production deployment from the GitHub Actions UI: ```yaml .github/workflows/publish-production.yml maxLines=7 name: Publish Production Docs on: workflow_dispatch: jobs: run: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Install Fern run: npm install -g fern-api - name: Validate configuration run: fern check - name: Publish to Production env: FERN_TOKEN: ${{ secrets.FERN_TOKEN }} run: fern generate --docs --instance plantstore-prod.docs.buildwithfern.com ``` To deploy to production, go to the **Actions** tab in your GitHub repository, select the workflow, and click **Run workflow**. ## Hosting When you publish your docs, Fern takes care of hosting them for you. You can also [publish your docs to a custom domain](/docs/preview-publish/setting-up-your-domain). ### Self-hosting your docs If you need access to your docs offline or would like to host your docs on your own server, Fern [offers that option as well](/docs/self-hosted/overview). Self-hosted docs have limited access to certain features (including Ask Fern and analytics). ## Unpublishing your docs If you need to take down your docs site, you cannot directly unpublish it. However, you can replace your content with an empty site to effectively remove all of your documentation. Replace the `navigation` object in your `docs.yml` file with an empty list. ```yml title="docs.yml"{3} instances: - .docs.buildwithfern.com navigation: [] ``` Publish the updated configuration by running `fern generate --docs`. This will remove all content from your site, and users visiting any page will see a 404 error.