|
| 1 | +--- |
| 2 | +title: Configure CI/CD for your React.js application |
| 3 | +linkTitle: Configure CI/CD |
| 4 | +weight: 60 |
| 5 | +keywords: CI/CD, GitHub( Actions), React.js, Next.js |
| 6 | +description: Learn how to configure CI/CD using GitHub Actions for your React.js application. |
| 7 | + |
| 8 | +--- |
| 9 | + |
| 10 | +## Prerequisites |
| 11 | + |
| 12 | +Complete all the previous sections of this guide, starting with [Containerize React.js application](containerize.md). |
| 13 | + |
| 14 | +You must also have: |
| 15 | +- A [GitHub](https://github.com/signup) account. |
| 16 | +- A [Docker Hub](https://hub.docker.com/signup) account. |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## Overview |
| 21 | + |
| 22 | +In this section, you'll set up a **CI/CD pipeline** using [GitHub Actions](https://docs.github.com/en/actions) to automatically: |
| 23 | + |
| 24 | +- Build your React.js application inside a Docker container. |
| 25 | +- Run tests in a consistent environment. |
| 26 | +- Push the production-ready image to [Docker Hub](https://hub.docker.com). |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +## Connect your GitHub repository to Docker Hub |
| 31 | + |
| 32 | +To enable GitHub Actions to build and push Docker images, you’ll securely store your Docker Hub credentials in your new GitHub repository. |
| 33 | + |
| 34 | +### Step 1: Connect your GitHub repository to Docker Hub |
| 35 | + |
| 36 | +1. Create a Personal Access Token (PAT) from [Docker Hub](https://hub.docker.com) |
| 37 | + 1. Go to your **Docker Hub account → Account Settings → Security**. |
| 38 | + 2. Generate a new Access Token with **Read/Write** permissions. |
| 39 | + 3. Name it something like `docker-reactjs-sample`. |
| 40 | + 4. Copy and save the token — you’ll need it in Step 4. |
| 41 | + |
| 42 | +2. Create a repository in [Docker Hub](https://hub.docker.com/repositories/) |
| 43 | + 1. Go to your **Docker Hub account → Create a repository**. |
| 44 | + 2. For the Repository Name, use something descriptive — for example: `reactjs-sample`. |
| 45 | + 3. Once created, copy and save the repository name — you’ll need it in Step 4. |
| 46 | + |
| 47 | +3. Create a new [GitHub repository](https://github.com/new) for your React.js project |
| 48 | + |
| 49 | +4. Add Docker Hub credentials as GitHub repository secrets |
| 50 | + |
| 51 | + In your newly created GitHub repository: |
| 52 | + |
| 53 | + 1. Navigate to: |
| 54 | + **Settings → Secrets and variables → Actions → New repository secret**. |
| 55 | + |
| 56 | + 2. Add the following secrets: |
| 57 | + |
| 58 | + | Name | Value | |
| 59 | + |-------------------|--------------------------------| |
| 60 | + | `DOCKER_USERNAME` | Your Docker Hub username | |
| 61 | + | `DOCKERHUB_TOKEN` | Your Docker Hub access token (created in Step 1) | |
| 62 | + | `DOCKERHUB_PROJECT_NAME` | Your Docker Project Name (created in Step 2) | |
| 63 | + |
| 64 | + These secrets let GitHub Actions to authenticate securely with Docker Hub during automated workflows. |
| 65 | + |
| 66 | +5. Connect Your Local Project to GitHub |
| 67 | + |
| 68 | + Link your local project `docker-reactjs-sample` to the GitHub repository you just created by running the following command from your project root: |
| 69 | + |
| 70 | + ```console |
| 71 | + $ git remote set-url origin https://github.com/{your-username}/{your-repository-name}.git |
| 72 | + ``` |
| 73 | + |
| 74 | + >[!IMPORTANT] |
| 75 | + >Replace `{your-username}` and `{your-repository}` with your actual GitHub username and repository name. |
| 76 | +
|
| 77 | + To confirm that your local project is correctly connected to the remote GitHub repository, run: |
| 78 | + |
| 79 | + ```console |
| 80 | + $ git remote -v |
| 81 | + ``` |
| 82 | + |
| 83 | + You should see output similar to: |
| 84 | + |
| 85 | + ```console |
| 86 | + origin https://github.com/{your-username}/{your-repository-name}.git (fetch) |
| 87 | + origin https://github.com/{your-username}/{your-repository-name}.git (push) |
| 88 | + ``` |
| 89 | + |
| 90 | + This confirms that your local repository is properly linked and ready to push your source code to GitHub. |
| 91 | + |
| 92 | +6. Push Your Source Code to GitHub |
| 93 | + |
| 94 | + Follow these steps to commit and push your local project to your GitHub repository: |
| 95 | + |
| 96 | + 1. Stage all files for commit. |
| 97 | + |
| 98 | + ```console |
| 99 | + $ git add -A |
| 100 | + ``` |
| 101 | + This command stages all changes — including new, modified, and deleted files — preparing them for commit. |
| 102 | + |
| 103 | + |
| 104 | + 2. Commit your changes. |
| 105 | + |
| 106 | + ```console |
| 107 | + $ git commit -m "Initial commit" |
| 108 | + ``` |
| 109 | + This command creates a commit that snapshots the staged changes with a descriptive message. |
| 110 | + |
| 111 | + 3. Push the code to the `main` branch. |
| 112 | + |
| 113 | + ```console |
| 114 | + $ git push -u origin main |
| 115 | + ``` |
| 116 | + This command pushes your local commits to the `main` branch of the remote GitHub repository and sets the upstream branch. |
| 117 | + |
| 118 | +Once completed, your code will be available on GitHub, and any GitHub Actions workflow you’ve configured will run automatically. |
| 119 | + |
| 120 | +> [!NOTE] |
| 121 | +> Learn more about the Git commands used in this step: |
| 122 | +> - [Git add](https://git-scm.com/docs/git-add) – Stage changes (new, modified, deleted) for commit |
| 123 | +> - [Git commit](https://git-scm.com/docs/git-commit) – Save a snapshot of your staged changes |
| 124 | +> - [Git push](https://git-scm.com/docs/git-push) – Upload local commits to your GitHub repository |
| 125 | +> - [Git remote](https://git-scm.com/docs/git-remote) – View and manage remote repository URLs |
| 126 | + |
| 127 | +--- |
| 128 | + |
| 129 | +### Step 2: Set up the workflow |
| 130 | + |
| 131 | +Now you'll create a GitHub Actions workflow that builds your Docker image, runs tests, and pushes the image to Docker Hub. |
| 132 | + |
| 133 | +1. Go to your repository on GitHub and select the **Actions** tab in the top menu. |
| 134 | + |
| 135 | +2. Select **Set up a workflow yourself** when prompted. |
| 136 | + |
| 137 | + This opens an inline editor to create a new workflow file. By default, it will be saved to: |
| 138 | + `.github/workflows/main.yml` |
| 139 | + |
| 140 | + |
| 141 | +3. Add the following workflow configuration to the new file: |
| 142 | + |
| 143 | +```yaml |
| 144 | +name: CI/CD – React.js Application with Docker |
| 145 | + |
| 146 | +on: |
| 147 | + push: |
| 148 | + branches: [main] |
| 149 | + pull_request: |
| 150 | + branches: [main] |
| 151 | + types: [opened, synchronize, reopened] |
| 152 | + |
| 153 | +jobs: |
| 154 | + build-test-push: |
| 155 | + name: Build, Test and Push Docker Image |
| 156 | + runs-on: ubuntu-latest |
| 157 | + |
| 158 | + steps: |
| 159 | + # 1. Checkout source code |
| 160 | + - name: Checkout source code |
| 161 | + uses: actions/checkout@v4 |
| 162 | + with: |
| 163 | + fetch-depth: 0 # Fetches full history for better caching/context |
| 164 | + |
| 165 | + # 2. Set up Docker Buildx |
| 166 | + - name: Set up Docker Buildx |
| 167 | + uses: docker/setup-buildx-action@v3 |
| 168 | + |
| 169 | + # 3. Cache Docker layers |
| 170 | + - name: Cache Docker layers |
| 171 | + uses: actions/cache@v4 |
| 172 | + with: |
| 173 | + path: /tmp/.buildx-cache |
| 174 | + key: ${{ runner.os }}-buildx-${{ github.sha }} |
| 175 | + restore-keys: ${{ runner.os }}-buildx- |
| 176 | + |
| 177 | + # 4. Cache npm dependencies |
| 178 | + - name: Cache npm dependencies |
| 179 | + uses: actions/cache@v4 |
| 180 | + with: |
| 181 | + path: ~/.npm |
| 182 | + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} |
| 183 | + restore-keys: ${{ runner.os }}-npm- |
| 184 | + |
| 185 | + # 5. Extract metadata |
| 186 | + - name: Extract metadata |
| 187 | + id: meta |
| 188 | + run: | |
| 189 | + echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> "$GITHUB_OUTPUT" |
| 190 | + echo "SHORT_SHA=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" |
| 191 | + |
| 192 | + # 6. Build dev Docker image |
| 193 | + - name: Build Docker image for tests |
| 194 | + uses: docker/build-push-action@v6 |
| 195 | + with: |
| 196 | + context: . |
| 197 | + file: Dockerfile.dev |
| 198 | + tags: ${{ steps.meta.outputs.REPO_NAME }}-dev:latest |
| 199 | + load: true # Load to local Docker daemon for testing |
| 200 | + cache-from: type=local,src=/tmp/.buildx-cache |
| 201 | + cache-to: type=local,dest=/tmp/.buildx-cache,mode=max |
| 202 | + |
| 203 | + # 7. Run Vitest tests |
| 204 | + - name: Run Vitest tests and generate report |
| 205 | + run: | |
| 206 | + docker run --rm \ |
| 207 | + --workdir /app \ |
| 208 | + --entrypoint "" \ |
| 209 | + ${{ steps.meta.outputs.REPO_NAME }}-dev:latest \ |
| 210 | + sh -c "npm ci && npx vitest run --reporter=verbose" |
| 211 | + env: |
| 212 | + CI: true |
| 213 | + NODE_ENV: test |
| 214 | + timeout-minutes: 10 |
| 215 | + |
| 216 | + # 8. Login to Docker Hub |
| 217 | + - name: Log in to Docker Hub |
| 218 | + uses: docker/login-action@v3 |
| 219 | + with: |
| 220 | + username: ${{ secrets.DOCKER_USERNAME }} |
| 221 | + password: ${{ secrets.DOCKERHUB_TOKEN }} |
| 222 | + |
| 223 | + # 9. Build and push prod image |
| 224 | + - name: Build and push production image |
| 225 | + uses: docker/build-push-action@v6 |
| 226 | + with: |
| 227 | + context: . |
| 228 | + file: Dockerfile |
| 229 | + push: true |
| 230 | + platforms: linux/amd64,linux/arm64 |
| 231 | + tags: | |
| 232 | + ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:latest |
| 233 | + ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:${{ steps.meta.outputs.SHORT_SHA }} |
| 234 | + cache-from: type=local,src=/tmp/.buildx-cache |
| 235 | +``` |
| 236 | + |
| 237 | +This workflow performs the following tasks for your React.js application: |
| 238 | +- Triggers on every `push` or `pull request` targeting the `main` branch. |
| 239 | +- Builds a development Docker image using `Dockerfile.dev`, optimized for testing. |
| 240 | +- Executes unit tests using Vitest inside a clean, containerized environment to ensure consistency. |
| 241 | +- Halts the workflow immediately if any test fails — enforcing code quality. |
| 242 | +- Caches both Docker build layers and npm dependencies for faster CI runs. |
| 243 | +- Authenticates securely with Docker Hub using GitHub repository secrets. |
| 244 | +- Builds a production-ready image using the `prod` stage in `Dockerfile`. |
| 245 | +- Tags and pushes the final image to Docker Hub with both `latest` and short SHA tags for traceability. |
| 246 | + |
| 247 | +> [!NOTE] |
| 248 | +> For more information about `docker/build-push-action`, refer to the [GitHub Action README](https://github.com/docker/build-push-action/blob/master/README.md). |
| 249 | +
|
| 250 | +--- |
| 251 | + |
| 252 | +### Step 3: Run the workflow |
| 253 | + |
| 254 | +After you've added your workflow file, it's time to trigger and observe the CI/CD process in action. |
| 255 | + |
| 256 | +1. Commit and push your workflow file |
| 257 | + |
| 258 | + Select "Commit changes…" in the GitHub editor. |
| 259 | + |
| 260 | + - This push will automatically trigger the GitHub Actions pipeline. |
| 261 | + |
| 262 | +2. Monitor the workflow execution |
| 263 | + |
| 264 | + 1. Go to the Actions tab in your GitHub repository. |
| 265 | + 2. Click into the workflow run to follow each step: **build**, **test**, and (if successful) **push**. |
| 266 | + |
| 267 | +3. Verify the Docker image on Docker Hub |
| 268 | + |
| 269 | + - After a successful workflow run, visit your [Docker Hub repositories](https://hub.docker.com/repositories). |
| 270 | + - You should see a new image under your repository with: |
| 271 | + - Repository name: `${your-repository-name}` |
| 272 | + - Tags include: |
| 273 | + - `latest` – represents the most recent successful build; ideal for quick testing or deployment. |
| 274 | + - `<short-sha>` – a unique identifier based on the commit hash, useful for version tracking, rollbacks, and traceability. |
| 275 | + |
| 276 | +> [!TIP] Protect your main branch |
| 277 | +> To maintain code quality and prevent accidental direct pushes, enable branch protection rules: |
| 278 | +> - Navigate to your **GitHub repo → Settings → Branches**. |
| 279 | +> - Under Branch protection rules, click **Add rule**. |
| 280 | +> - Specify `main` as the branch name. |
| 281 | +> - Enable options like: |
| 282 | +> - *Require a pull request before merging*. |
| 283 | +> - *Require status checks to pass before merging*. |
| 284 | +> |
| 285 | +> This ensures that only tested and reviewed code is merged into `main` branch. |
| 286 | +--- |
| 287 | + |
| 288 | +## Summary |
| 289 | + |
| 290 | +In this section, you set up a complete CI/CD pipeline for your containerized React.js application using GitHub Actions. |
| 291 | + |
| 292 | +Here's what you accomplished: |
| 293 | + |
| 294 | +- Created a new GitHub repository specifically for your project. |
| 295 | +- Generated a secure Docker Hub access token and added it to GitHub as a secret. |
| 296 | +- Defined a GitHub Actions workflow to: |
| 297 | + - Build your application inside a Docker container. |
| 298 | + - Run tests in a consistent, containerized environment. |
| 299 | + - Push a production-ready image to Docker Hub if tests pass. |
| 300 | +- Triggered and verified the workflow execution through GitHub Actions. |
| 301 | +- Confirmed that your image was successfully published to Docker Hub. |
| 302 | + |
| 303 | +With this setup, your React.js application is now ready for automated testing and deployment across environments — increasing confidence, consistency, and team productivity. |
| 304 | + |
| 305 | +--- |
| 306 | + |
| 307 | +## Related resources |
| 308 | + |
| 309 | +Deepen your understanding of automation and best practices for containerized apps: |
| 310 | + |
| 311 | +- [Introduction to GitHub Actions](/guides/gha.md) – Learn how GitHub Actions automate your workflows |
| 312 | +- [Docker Build GitHub Actions](/manuals/build/ci/github-actions/_index.md) – Set up container builds with GitHub Actions |
| 313 | +- [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions) – Full reference for writing GitHub workflows |
| 314 | +- [Compose file reference](/compose/compose-file/) – Full configuration reference for `compose.yaml` |
| 315 | +- [Best practices for writing Dockerfiles](/develop/develop-images/dockerfile_best-practices/) – Optimize your image for performance and security |
| 316 | + |
| 317 | +--- |
| 318 | + |
| 319 | +## Next steps |
| 320 | + |
| 321 | +Next, learn how you can locally test and debug your React.js workloads on Kubernetes before deploying. This helps you ensure your application behaves as expected in a production-like environment, reducing surprises during deployment. |
0 commit comments