In modern web development, setting up an efficient CI/CD pipeline for deploying your Angular applications can significantly enhance your workflow. This blog post guides you through setting up a GitHub Actions pipeline to build and deploy an Angular application using Docker, Nginx, and ensuring basic security group configurations in EC2.
Prerequisites
- A GitHub repository containing your Angular application.
- Docker installed on your local machine.
- GitHub Container Registry (GHCR) for storing Docker images.
- An EC2 instance or any server with Docker and Nginx installed.
- Proper security group settings on your EC2 instance.
Step 1: Modify Dockerfile to Accept Build Arguments
First, we need to update our Dockerfile to accept build arguments that specify the Angular environment. This ensures that our build process can dynamically adjust based on the environment.
# Use the official Node.js image as a base
FROM node:14 # Create and set the working directory
WORKDIR /app # Copy package.json and package-lock.json
COPY package*.json ./ # Install dependencies
RUN npm install # Copy the rest of the application files
COPY . . # Set the environment variable to increase memory limit
ENV NODE_OPTIONS=--max_old_space_size=4096 # Build the Angular application based on the provided environment
ARG ANGULAR_ENV=production
RUN npm run build -- --configuration=$ANGULAR_ENV # Expose the port the app runs on
EXPOSE 80 # Command to run the application
CMD ["npm", "start"]
Step 2: Set Up GitHub Actions Workflow
Next, we’ll configure a GitHub Actions workflow to handle the build and deployment process.
name: Build and Deploy Angular on: push: branches: - main # Change this to your main branch name jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Log in to GitHub Container Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # Use GitHub token secret - name: Extract Git Commit Hash id: vars run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Build Docker Image run: | docker build --build-arg ANGULAR_ENV=production -t ghcr.io/yourusername/angular-docker:${{ env.COMMIT_HASH }} . - name: Push Docker Image to GitHub Container Registry run: | docker push ghcr.io/yourusername/angular-docker:${{ env.COMMIT_HASH }} - name: SSH and Deploy to Server env: PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} # This is the private key secret for SSH COMMIT_HASH: ${{ env.COMMIT_HASH }} run: | echo "$PRIVATE_KEY" > private_key.pem chmod 600 private_key.pem ssh -o StrictHostKeyChecking=no -i private_key.pem ubuntu@your-ec2-instance <<EOF echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin docker pull ghcr.io/yourusername/angular-docker:${COMMIT_HASH} docker stop angular-app || true docker rm angular-app || true docker run -d --name angular-app -p 8080:80 ghcr.io/yourusername/angular-docker:${COMMIT_HASH} sudo systemctl restart nginx docker system prune -a -f --volumes EOF rm -f private_key.pem permissions: contents: read packages: write id-token: write
Step 3: Nginx Configuration
Update your Nginx configuration to correctly proxy requests to the Docker container.
server { if ($host = yourdomain.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name yourdomain.com; return 404;
} server { listen 443 ssl http2; server_name yourdomain.com; location / { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # managed by Certbot
}
Step 4: EC2 Security Group Configuration
Ensure your EC2 instance’s security group allows inbound traffic on ports 80 and 443.
- Log in to AWS Management Console.
- Navigate to EC2 Dashboard.
- Select Security Groups under “Network & Security”.
- Find and Select Your Security Group associated with your EC2 instance.
-
Edit Inbound Rules to allow traffic on ports 80 (HTTP) and 443 (HTTPS):
-
HTTP (port 80):
- Type: HTTP
- Protocol: TCP
- Port Range: 80
- Source: 0.0.0.0/0
-
HTTPS (port 443):
- Type: HTTPS
- Protocol: TCP
- Port Range: 443
- Source: 0.0.0.0/0
- Login ghcr.io to pull the iamges from your github
-
HTTP (port 80):
export CR_PAT=YOUR_TOKEN
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
Summary
This setup ensures that:
- Each deployment uses a Docker image tagged with the specific Git commit hash.
- Unused Docker images are removed from your server to free up space.
- Your server runs the latest Docker image without accumulating old images.
Discover more from Coursity
Subscribe to get the latest posts sent to your email.