A minimal React + Vite application created for training purposes to practice a basic DevOps workflow:
- local development
- Git version control
- connecting a project to a GitHub repository
- preparing for deployment
- deployment with Cloudflare Pages
- building a foundation for a CI/CD pipeline
- adding basic CI with GitHub Actions
This project was created as a simplified starter frontend application to help learn the process of:
- creating an application
- working with Git
- pushing code to GitHub
- running a local build
- preparing for automated deployment
- connecting a repository to a hosting platform
- building a foundation for a CI/CD pipeline
The project is intentionally kept simple so that each stage of the process is easy to understand, without unnecessary backend or infrastructure complexity.
- React
- Vite
- JavaScript
- Git
- GitHub
- Cloudflare Pages
- GitHub Actions
The project was initialized as a minimal frontend application.
The application currently contains only a basic heading, making it easier to work with a minimal codebase and follow the deployment flow more clearly.
Example:
import './App.css'
function App() {
return (
<>
<h1>React + Vite Training</h1>
</>
)
}
export default AppThe project was checked locally to confirm that both development mode and production build were working correctly.
Commands used:
npm run dev
npm run buildThis step was important because it confirmed that:
- the application runs locally
- the build process works correctly
- the project is ready for deployment
The local project was connected to a GitHub repository so the code could be versioned, pushed remotely, and prepared for deployment automation.
Typical commands used:
git init
git branch -M main
git add .
git commit -m "init: create Vite React starter app"
git remote add origin <repository-url>
git push -u origin mainThe project was connected to Cloudflare Pages using the GitHub integration flow.
The deployment was configured through the following steps:
The Cloudflare dashboard was opened and the Pages flow was selected instead of the Worker flow.
This was important because the project is currently a simple frontend application built with React + Vite, so Cloudflare Pages is the correct deployment target.
From the available options, the Pages setup was used instead of creating a Worker.
Then the following option was selected:
- Import an existing Git repository
This was the correct choice because the project was already pushed to GitHub and was ready to be connected directly to a hosting platform.
The following repository was selected from GitHub:
ninkov/DevOpsTraining
This step connected the project source code to Cloudflare Pages.
The following deployment settings were used:
- Project name:
devopstraining - Production branch:
main - Build command:
npm run build - Build output directory:
dist
These settings tell Cloudflare:
- which branch should be treated as production
- how the project should be built
- which folder should be published after the build is completed
After saving the settings, Cloudflare automatically:
- pulled the source code from GitHub
- installed the project dependencies
- ran the build command
- published the generated output
The project was successfully deployed and published at:
https://devopstraining.pages.dev
This step introduced a very simple form of Continuous Deployment (CD).
Why this is considered CD:
- the code is stored in GitHub
- the
mainbranch is connected to Cloudflare Pages - Cloudflare automatically builds the project
- Cloudflare automatically deploys the latest version to a live public URL
This is still a basic version of CD, but it already demonstrates the core idea of automated deployment:
a code change pushed to the repository can trigger a new build and a new deployment without manually uploading files.
A new GitHub Actions workflow file was created at:
.github/workflows/ci.yml
The purpose of this workflow is to introduce a basic Continuous Integration (CI) process for the project.
The workflow was configured to run automatically on:
- pushes to
main - pull requests targeting
main
Workflow content:
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
build-and-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Run lint
run: npm run lint --if-present
- name: Build project
run: npm run buildThis workflow performs the following automated checks:
- checks out the repository
- sets up a Node.js environment
- installs dependencies with
npm ci - runs lint if available
- runs the production build
This step is important because it adds an automated validation layer before changes become part of the main branch.
Instead of changing main directly, a separate branch was created for the CI workflow:
git checkout -b feature/add-ciThe new workflow file was staged, committed, and pushed to GitHub:
git add .github/workflows/ci.yml
git commit -m "ci: add GitHub Actions build workflow"
git push -u origin feature/add-ciThis step is important because it introduces a safer Git workflow:
- changes are developed in isolation
mainis kept clean- the new work can be reviewed through a Pull Request
A Pull Request was opened from:
- base:
main - compare:
feature/add-ci
The CI workflow ran automatically after the Pull Request was created.
The checks passed successfully, which confirmed that:
- the workflow file was valid
- dependencies could be installed correctly
- the project could be built successfully
- the CI process was working as expected
This was the first real CI validation for the project inside GitHub.
After all checks passed, the Pull Request was merged into the main branch.
This step officially added the CI workflow to the main version of the project.
After the merge:
- the Pull Request was closed
- the feature branch was no longer needed
- the branch could be deleted safely
Because main is connected to Cloudflare Pages as the production branch, the merge triggered a new production deployment automatically.
This confirmed that the project now has both:
- a basic CI process through GitHub Actions
- a basic CD process through Cloudflare Pages
At this stage, the workflow looks like this:
feature branch → pull request → CI checks → merge to main → Cloudflare production deploy
This is still a simple pipeline, but it already demonstrates a real DevOps workflow with both validation and deployment automation.
- React + Vite app created
- App component simplified
- Local development verified
- Production build verified
- GitHub repository created and connected
- Project pushed to GitHub
- Cloudflare Pages connected
- First live deployment completed
- GitHub Actions CI workflow added
- Pull Request created for CI change
- CI checks passed successfully
- CI workflow merged into
main - Cloudflare production redeployment confirmed
code → commit → push → pull request → CI checks → merge → deploy
More specifically:
feature branch → pull request → GitHub Actions CI → merge to main → Cloudflare Pages production deploy
The following tools and concepts have intentionally not been added at this stage:
- Docker
- Terraform
- backend services
- database
- custom domain
- environment variables
- automated tests
- branch protection rules
Reason: the project is intentionally minimal so the core flow can be learned first.
The next logical improvements for this training project are:
- protect the
mainbranch with required status checks - add a manual trigger (
workflow_dispatch) to the CI workflow - add automated tests in addition to lint and build
- continue improving the README as new phases are completed
- later consider Docker and Terraform as next-stage DevOps topics