mirror of https://github.com/rancher/dashboard.git
193 lines
7.5 KiB
Markdown
193 lines
7.5 KiB
Markdown
# Building an Image for Container Registries
|
|
|
|
> ⚠️ Documentation in this directory is intended for internal use only. Any information contained here is unsupported.
|
|
|
|
Sometimes you may need to have a custom version of the dashboard that is packaged alongside Rancher to be hosted within Github's [container registry](https://docs.github.com/en/packages). There are a few use cases for this, for instance when developing a package/product for Rancher that doesn't need to be standalone or when it isn't necessary for the package to exist in the Dashboard by default.
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- A branch on the [Dashboard repo](https://github.com/rancher/dashboard) to store the custom dashboard
|
|
- A target repository where the dashboard will be added as a submodule
|
|
- Access to the target repository actions with a [PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) to authenticate from within the action
|
|
|
|
---
|
|
|
|
## Steps
|
|
|
|
### 1. Add branched repo as a submodule
|
|
|
|
Run the following to [add a submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to your target repo:
|
|
|
|
```sh
|
|
git submodule add <branch-repo-path>
|
|
```
|
|
|
|
This will generate a config file `.gitmodules` in the root directory, it will contain the path of the submodule and the url of the repo. In order to target a specific branch you will need to add a `branch` property to this file. For instance:
|
|
|
|
```
|
|
[submodule "dashboard"]
|
|
path = dashboard
|
|
url = https://github.com/rancher/dashboard.git
|
|
branch = <target-branch>
|
|
```
|
|
|
|
Push these changes to the target repo and you will now see the submodule with the `path` you specified in `.gitmodules`.
|
|
|
|
### 2. Create Dockerfile to build Rancher image
|
|
|
|
Create a new [Dockerfile](https://docs.docker.com/engine/reference/builder/) in your branched repo that will build both the frontend from your branch and the main Rancher image. It will need to replace the dashboard files in the Rancher image with the build from the new frontend.
|
|
|
|
```Dockerfile
|
|
# Dockerfile.example
|
|
FROM node:16 AS builder
|
|
|
|
WORKDIR /src
|
|
|
|
COPY . .
|
|
RUN yarn --pure-lockfile install
|
|
|
|
ENV ROUTER_BASE="/dashboard/" \
|
|
RESOURCE_BASE="/dashboard/"
|
|
RUN yarn run build
|
|
|
|
FROM rancher/rancher:v2.8-head
|
|
WORKDIR /var/lib/rancher
|
|
RUN rm -rf /usr/share/rancher/ui-dashboard/dashboard*
|
|
COPY --from=builder /src/dist /usr/share/rancher/ui-dashboard/dashboard
|
|
```
|
|
|
|
This will build the frontend from your branch with `RUN yarn run build` and replace the dashboard in the Rancher image with `COPY --from=builder /src/dist /usr/share/rancher/ui-dashboard/dashboard`.
|
|
|
|
### 3. Create action to dispatch the image
|
|
|
|
In order to make publishing the new package to the Github Registry automatic you will need to create an action that will build the new Rancher image from your submodule's Dockerfile and dispatch the image into a package.
|
|
|
|
Create two new directories in your target repo:
|
|
|
|
```/.github/workflows```
|
|
|
|
Add a new YAML file in the `workflow` directory:
|
|
|
|
```yml
|
|
# /.github/workflows/build-image.yml
|
|
|
|
name: Dispatch Dashboard image
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
env:
|
|
REGISTRY: ghcr.io
|
|
IMAGE_NAME: ${{ github.repository }} # The target repo
|
|
|
|
jobs:
|
|
build:
|
|
name: Build Dashboard image
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
actions: write
|
|
contents: read
|
|
packages: write
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v2
|
|
with:
|
|
token: ${{ secrets.WORKFLOW_PAT }} # The PAT referenced in prerequisites
|
|
submodules: recursive # If the repo has multiple submodules to checkout
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@v1
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v1
|
|
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.actor }} # This is the repo owner
|
|
password: ${{ secrets.GITHUB_TOKEN }} # A token generated during the workflow
|
|
|
|
- name: Build and push Dashboard image
|
|
uses: docker/build-push-action@v2
|
|
with:
|
|
context: ./dashboard # Context for docker to find the Dockerfile in the submodule
|
|
file: ./dashboard/Dockerfile.example # Dockerfile you created
|
|
push: true
|
|
tags: |
|
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
|
```
|
|
|
|
We are using [`docker/build-push-action@v2`](https://github.com/docker/build-push-action#usage) to do the heavy lifting for us. This file will create a new package any time a `push` or `pull request` is made on the `main` branch. It first provides a platform for which to build the image that has permissions to read contents and write packages. We're using `ubuntu-latest` in this case.
|
|
|
|
The steps laid out are mostly self-explanatory, it will first checkout the repository with the given `secrets.WORKFLOW_PAT` you created in the [prerequisites](#prerequisites). The steps for setting up QEMU and Docker Buildx are [recommened](https://github.com/docker/build-push-action#usage) by the `docker/build-push-action`.
|
|
|
|
The final two steps are where the magic happens. First logging into the Github Container Registry with a temporary [`GITHUB_TOKEN`](https://docs.github.com/en/actions/security-guides/automatic-token-authentication), then building and pushing the actual image to be packaged.
|
|
|
|
---
|
|
|
|
## Running the custom build
|
|
|
|
When running your newly built image Rancher will need to know to serve the "locally" installed dashboard. You can do this by setting the `CATTLE_UI_DASHBOARD_INDEX` environment variable in your `docker run` command.
|
|
|
|
For instance:
|
|
|
|
```sh
|
|
docker run -d --name dashboard \
|
|
--restart=unless-stopped \
|
|
--privileged \
|
|
-p 80:80 -p 443:443 \
|
|
-e CATTLE_UI_DASHBOARD_INDEX=https://localhost/dashboard/index.html \
|
|
-e CATTLE_UI_OFFLINE_PREFERRED=true \
|
|
ghcr.io/<example-repo>:latest
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
At the time of writing (February '22), the build time for the Dashboard frontend and Rancher image takes about 8 minutes, so some debugging in place will greatly diminish any frustration while building an action.
|
|
|
|
The simplest way of adding debugging to your action is by [enabling runner diagnostic logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging#enabling-runner-diagnostic-logging). You can do this by adding an environment variable to the beginning of your workflow action `ACTIONS_RUNNER_DEBUG: true`
|
|
|
|
For instance:
|
|
|
|
```yml
|
|
# /.github/workflows/build-image.yml
|
|
|
|
...
|
|
env:
|
|
ACTIONS_RUNNER_DEBUG: true
|
|
REGISTRY: ghcr.io
|
|
IMAGE_NAME: ${{ github.repository }}
|
|
...
|
|
```
|
|
|
|
This way can be a little verbose but can help narrow down which step is causing you trouble. If you want to see the logs for a specific step you can add an environment variable to your step: `ACTIONS_STEP_DEBUG: true`
|
|
|
|
For instance:
|
|
|
|
```yml
|
|
# /.github/workflows/build-image.yml
|
|
|
|
...
|
|
- name: Build and push dashboard image
|
|
uses: docker/build-push-action@v2
|
|
env:
|
|
ACTIONS_STEP_DEBUG: true
|
|
with:
|
|
context: ./dashboard
|
|
...
|
|
```
|
|
|
|
Some actions have unique debugging features that you can utilize container logs to see what is happening behind the scenes. In our `build-image.yml` example we are using `docker/setup-buildx-action` which has [logs you can access](https://github.com/docker/setup-buildx-action#buildkit-container-logs).
|
|
|
|
### Caveats
|
|
|
|
With `docker/build-push-action` there are [a few caveats](https://github.com/docker/build-push-action/blob/master/TROUBLESHOOTING.md) that could cause confusion. Be sure that your repository name is lowercase! |