Skip to content

Commit

Permalink
Update deploy.md
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Nov 27, 2023
1 parent 2a901bd commit d251bff
Showing 1 changed file with 187 additions and 66 deletions.
253 changes: 187 additions & 66 deletions MyApp/_pages/deploy.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,195 @@
---
title: Deployment Guide
title: GitHub Action Deployments
---

# Introduction
In today's DevOps ecosystem, [GitHub Actions](https://github.com/features/actions) stand out as an invaluable asset for
automating CI/CD workflows directly within your GitHub repository. The introduction of .NET 8 takes this a step further,
offering a streamlined approach to generating Docker images through the `<PublishProfile>DefaultContainer</PublishProfile>`
setting in your `.csproj`. This ensures consistent application packaging, making it deployment-ready by just using `dotnet publish`.

In today's DevOps ecosystem, GitHub Actions stand out as an invaluable asset for automating CI/CD workflows directly within your GitHub repository. The introduction of .NET 8 takes this a step further, offering a streamlined approach to generating Docker images through the `<PublishProfile>DefaultContainer</PublishProfile>` setting in your `.csproj` files. This ensures consistent application packaging, making it deployment-ready by just using `dotnet publish`.
ServiceStack's project templates bring additional flexibility, by utilizing foundational tools like
[Docker](https://www.docker.com) for containerization and [SSH](https://en.wikipedia.org/wiki/Secure_Shell) for secure deployments,
it's able to deploy your Dockerized .NET applications to any Linux server, whether self-hosted or on any cloud provider.

The new ServiceStack templates in .NET 8 bring additional flexibility. They are designed with cloud-agnosticism in mind, utilizing foundational tools like Docker for containerization and SSH for secure deployment. This makes it possible to deploy your applications to any Linux server, irrespective of the cloud provider you're using.
#### Live Demos use their GitHub Actions to deploy themselves

This guide aims to walk you through the hosting setup and the GitHub Actions release process as introduced in the new .NET 8 and ServiceStack templates.
Each template's Live demo are themselves utilizing their included GitHub Actions to deploy itself to a Linux server running
on a **€13.60 /month** shared 8BG RAM [Hetzner Cloud VM](https://www.hetzner.com/cloud) that's currently running 50+ Docker Containers.

This guide aims to walk you through the hosting setup and the GitHub Actions release process as introduced in the
ServiceStack's latest .NET 8 project templates.

## Deployment Files

# The Anatomy of the GitHub Actions Workflow
Deployment files that are included in project templates to facilitate GitHub Actions deployments:

GitHub Actions workflows are defined in YAML files, and they provide a powerful way to automate your development process. This guide will take you through the key sections of the workflow to give you a comprehensive understanding of how it functions.
#### .deploy/
- [nginx-proxy-compose.yml](https://github.com/NetCoreTemplates/blazor/blob/master/.deploy/nginx-proxy-compose.yml) - Manage nginx reverse proxy and Lets Encrypt companion container (one-time setup per server)
- [docker-compose.yml](https://github.com/NetCoreTemplates/blazor/blob/main/.deploy/docker-compose.yml) - Manage .NET App Docker Container

#### .github/workflows/
- [build.yml](https://github.com/NetCoreTemplates/blazor/blob/master/.github/workflows/build.yml) - Build .NET Project and Run Tests
- [release.yml](https://github.com/NetCoreTemplates/blazor/blob/master/.github/workflows/release.yml) - Build container, Push to GitHub Packages Registry, SSH deploy to Linux server, Run DB Migrations and start new Docker Container if successful otherwise revert Migration

## Prerequisites

Before your Linux server can accept GitHub Actions deployments, we need to set up a few things:

### Setup Deployment Server

#### 1. Install Docker and Docker-Compose

Follow [Docker's installation instructions](https://docs.docker.com/engine/install/ubuntu/)
to correctly install the latest version of Docker.

#### 2. Configure SSH for GitHub Actions

Generate a dedicated SSH key pair to be used by GitHub Actions:

:::sh
ssh-keygen -t rsa -b 4096 -f ~/.ssh/github_actions
:::

Add the **public key** to your server's SSH **authorized_keys**:

:::sh
cat ~/.ssh/github_actions.pub >> ~/.ssh/authorized_keys
:::

Then, add the **private key** to your repo's `DEPLOY_KEY` GitHub Action Secret which GitHub Actions will use to
securely SSH into the server.

#### 3. Set Up nginx-reverse-proxy

You should have a `docker-compose` file similar to the `nginx-proxy-compose.yml` in your repository. Upload this file to your server:

:::sh
scp nginx-proxy-compose.yml user@your_server:~/
:::

To bring up the nginx reverse proxy and its companion container for handling TLS certificates, run:

:::sh
docker compose -f ~/nginx-proxy-compose.yml up -d
:::

This will start an nginx reverse proxy along with a companion LetsEncrypt container that will automatically watch for
additional Docker containers on the same network and initialize them with valid TLS certificates.

### Ready to host containerized .NET Apps

Your Linux server is now ready to accept multiple .NET App deployments from GitHub Actions. The guide below walks through
the process of setting up your GitHub repository to deploy new ServiceStack .NET Apps to your Linux server.

## Step-by-Step Guide

### 1. Create Your ServiceStack Application

Start by creating your ServiceStack application, either from [ServiceStack's Start Page](https://servicestack.net/start)
or by using the [x dotnet tool](https://docs.servicestack.net/dotnet-tool):

:::sh
x new blazor ProjectName
:::

Replace `ProjectName` with your desired project name to generate a new ServiceStack application pre-configured
with the necessary Docker compose files and GitHub Action workflows as above.

### 2. Configure DNS for Your Application

You need a domain to point to your Linux server. Create an A Record in your DNS settings that points to the IP address
of your Linux server:

- **Subdomain**: `app.example.org`
- **Record Type**: A
- **Value/Address**: IP address of your Linux server

This ensures that any requests to `app.example.org` are directed to your server.

### 3. Setting Up GitHub Secrets

Navigate to your GitHub repository's settings, find the "Secrets and variables" section, and add the following secrets:

- `DEPLOY_HOST`: IP address or hostname of your Linux server
- `DEPLOY_USERNAME`: SSH Username to use for deployments
- `DEPLOY_KEY`: Private key generated for GitHub Actions to SSH into your server
- `LETSENCRYPT_EMAIL`: Your email address for Let's Encrypt notifications

#### Using GitHub CLI for Secret Management

You can use the [GitHub CLI](https://cli.github.com/manual/gh_secret_set) for a quicker setup of these GitHub Action Secrets, e.g:

```bash
gh secret set DEPLOY_HOST --body="linux-server-host"
gh secret set DEPLOY_USERNAME --body="linux-server-username"
gh secret set DEPLOY_KEY --bodyFile="path/to/ssh-private-key"
gh secret set LETSENCRYPT_EMAIL --body="[email protected]"
```

These secrets will populate environment variables within your GitHub Actions workflow and other configuration files,
enabling secure and automated deployment of your ServiceStack applications.

### 4. Push to Main Branch to Trigger Deployment

With everything set up, pushing code to the main branch of your repository will trigger the GitHub Action workflow, initiating the deployment process:

```bash
git add .
git commit -m "Initial commit"
git push origin main
```

### 5. Verifying the Deployment

After the GitHub Actions workflow completes, you can verify the deployment by:

- Checking the workflow's logs in your GitHub repository to ensure it completed successfully
- Navigating to your application's URL (e.g., `https://app.example.org`) in a web browser. You should see your ServiceStack application up and running with a secure HTTPS connection

## Features

### DB Migrations

The GitHub Actions workflow includes a step to run database migrations on the remote server in the **Run remote db migrations** step
which automatically runs the `migrate` AppTask in the `app-migration` companion Docker container on the Linux Host Server
to validate migration was successful before completing deployment of the new App. A failed migration will cause deployment to fail
and the previous App version to continue to run.

### Patch appsettings.json with production secrets

One way to maintain sensitive information like API keys and connection strings for your Production App outside of its
source code GitHub repository is to patch the `appsettings.json` file with a [JSON Patch](https://jsonpatch.com) that's
stored in your repo's `APPSETTINGS_PATCH` GitHub Action Secret which will be applied with the deployed App's `appsettings.json` file.

For example this JSON Patch below will replace values and objects in your App's **appsettings.json**:

```json
[
{ "op":"add", "path":"/oauth.facebook.AppSecret", "value":"xxxx" },
{ "op":"add", "path":"/oauth.microsoft.AppSecret", "value":"xxxx" },
{ "op":"add", "path":"/smtp", "value":{
"UserName": "xxxx",
"Password": "xxxx",
"Host": "smtp-server.example.org",
"Port": 587,
"From": "[email protected]",
"FromName": "No Reply"
}
}
]
```

You can test your JSON Patch by saving it to `appsettings.json.patch` and applying it with the
[patch feature](https://docs.servicestack.net/dotnet-tool#patch-json-files) of the `x` dotnet tool:

:::sh
x patch appsettings.json.patch
:::

## Anatomy of GitHub Actions Workflow

GitHub Actions workflows are defined in YAML files, and they provide a powerful way to automate your development process.
This guide will take you through the key sections of the workflow to give you a comprehensive understanding of how it functions.

## Permissions

Expand Down Expand Up @@ -102,78 +277,24 @@ Using an **nginx reverse proxy** in this deployment design offers several powerf
With an nginx reverse proxy, you can host multiple ServiceStack (or non-ServiceStack) applications on a single server while providing each with its domain or subdomain.


## Additional Resources

## Step-by-Step Implementation

### 1. Create Your ServiceStack Application

Start by creating your ServiceStack application. You can utilize the .NET `x` tool from ServiceStack or directly use a template from the `NetCoreTemplates` GitHub Organization. Here's how you can do it with the `x` tool:

```bash
dotnet tool install --global x
x new web YourApp
```

Replace `YourApp` with your desired project name. This will generate a new ServiceStack application with the necessary GitHub Action workflows already incorporated.

### 2. Configure DNS for Your Application

You need a domain to point to your Linux server. Create an A Record in your DNS settings that points to the IP address of your Linux server:

- **Subdomain**: e.g., `app.yourdomain.com`
- **Record Type**: A
- **Value/Address**: IP address of your Linux server

This ensures that any requests to `app.yourdomain.com` are directed to your server.

### 3. Setting Up GitHub Secrets

Navigate to your GitHub repository's settings, find the "Secrets and variables" section, and add the following secrets:

- **`DEPLOY_HOST`**: The IP address or hostname of your server.
- **`DEPLOY_USERNAME`**: The username for SSH login.
- **`DEPLOY_KEY`**: The private key you generated for GitHub Actions to SSH into your server.
- **`LETSENCRYPT_EMAIL`**: Your email address for Let's Encrypt notifications.

Use the GitHub CLI for a quicker setup, as illustrated in the previous guidelines.

### 4. Push to Main Branch to Trigger Deployment

With everything set up, pushing code to the main branch of your repository will trigger the GitHub Action workflow, initiating the deployment process:

```bash
git add .
git commit -m "Initial commit"
git push origin main
```

### 5. Verifying the Deployment

After the GitHub Actions workflow completes, you can verify the deployment by:

- Checking the workflow's logs in your GitHub repository to ensure it completed successfully.
- Navigating to your application's URL (e.g., `https://app.yourdomain.com`) in a web browser. You should see your ServiceStack application up and running with a secure HTTPS connection.



# Additional Resources

## ServiceStack
### ServiceStack

- **[Official Documentation](https://docs.servicestack.net/)**: Comprehensive guides and best practices for ServiceStack.
- **[ServiceStack Website](https://servicestack.net/)**: Explore features, templates, and client libraries.

## Docker & Docker-Compose
### Docker & Docker-Compose

- **[Docker Documentation](https://docs.docker.com/)**: Core concepts, CLI usage, and practical applications.
- **[Docker-Compose Documentation](https://docs.docker.com/compose/)**: Define and manage multi-container applications.

## GitHub Actions
### GitHub Actions

- **[GitHub Actions Documentation](https://docs.github.com/en/actions)**: Creating workflows, managing secrets, and automation tips.
- **[Starter Workflows](https://github.com/actions/starter-workflows)**: Templates for various languages and tools.

## SSH & Security
### SSH & Security

- **[SSH Key Management](https://www.ssh.com/academy/ssh/keygen)**: Guidelines on generating and managing SSH keys.
- **[GitHub Actions Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)**: Securely store and use sensitive information.

0 comments on commit d251bff

Please sign in to comment.