Beginner's Codebase To Deployment
Tags: beginners, devops, aws, docker
Published: 2023-05-19 10:38:01

Codebase to Deployment is a process that involves the development and deployment of software applications. It involves a series of steps that take the source code from a repository and transform it into a fully deployed application.

The first step in the process is the creation of a codebase. This involves writing code that will form the foundation of the application. The codebase is typically stored in a version control system such as Git.

Once the codebase is complete, the next step is to compile the code and test it to ensure that it is functioning as expected. This is typically done in a development environment.

After testing, the next step involves deploying the application to a staging environment. This is an environment that is nearly identical to the production environment and is used to test the application in a real-world scenario.

Once the application has been tested in the staging environment and any issues have been resolved, it is ready to be deployed to the production environment. This is the final step in the process and involves making the application available to end-users.

Deploying code from your development environment to a production server is a critical step in the software development lifecycle. However, it can often be a complex and error-prone process. In this blog post, we will explore three scenarios for streamlining code deployment using popular tools: Docker, Jenkins, and GitHub Actions. We will also provide code examples for deploying to an AWS Linux server. The Base code we decided to adopt is a Node application.

**Scenario 1: Docker**
Docker is a widely adopted containerization platform that allows you to package your application and its dependencies into a standardized unit called a container. Here's a step-by-step guide on deploying your codebase to an AWS Linux server using Docker:

1. Dockerize your application:
    - Create a Dockerfile specifying the base image, dependencies, and build steps.

```
# Base image
FROM node:14-alpine

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package.json package-lock.json ./

# Install dependencies
RUN npm install

# Copy the application code
COPY . .

# Build the React app
RUN npm run build

# Set the environment variable
ENV PORT=80

# Expose the port
EXPOSE $PORT

# Start the React app
CMD [ "npm", "start" ]
```
- Build the Docker image using the Docker Desktop.
2. Push the Docker image to a container registry:
    - Create an account on a container registry like Docker Hub or Amazon ECR.
    - Tag your Docker image with the registry URL and version.
```
docker tag your-image-name registry-url/repository-name:version
```
   - Push the image to the container registry.
```
docker push dockerhubusername/my-app:v1.0
```
3. Deploy the Docker container to AWS Linux server:
    - Install Docker on the AWS Linux server.

```
# Step 1: Connect to your AWS Linux server via SSH

# Step 2: Update the package manager cache
sudo yum update -y

# Step 3: Install the required packages to set up the Docker repository
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# Step 4: Add the Docker repository to your system
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# Step 5: Install Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io

# Step 6: Start the Docker service
sudo systemctl start docker

# Step 7: Enable Docker to start on server boot
sudo systemctl enable docker

# Step 8: Verify that Docker is installed and running correctly
sudo docker info
```
 - Pull the Docker image from the container registry.

```
docker pull registry-url/repository-name:version
```
 - Run the container on the server using the Docker CLI.

```
docker run -d --name container-name -p host-port:container-port image-name
```
**Scenario 2: Jenkins**
Jenkins is a popular open-source automation server that enables continuous integration and continuous delivery (CI/CD). Here's how you can leverage Jenkins for code deployment:

1. Set up Jenkins:
    - Install and configure Jenkins on a server.

```
# Step 1: Connect to your server via SSH

# Step 2: Update the package manager cache
sudo apt update

# Step 3: Install Java Development Kit (JDK)
sudo apt install -y default-jdk

# Step 4: Add the Jenkins repository key to your system
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -

# Step 5: Add the Jenkins repository to the package manager
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

# Step 6: Update the package manager cache again
sudo apt update

# Step 7: Install Jenkins
sudo apt install -y jenkins

# Step 8: Start the Jenkins service
sudo systemctl start jenkins

# Step 9: Enable Jenkins to start on server boot
sudo systemctl enable jenkins

# Step 10: Check the status of the Jenkins service
sudo systemctl status jenkins

# Step 11: Open a web browser and navigate to Jenkins setup page

# Step 12: Retrieve the Jenkins initial administrator password
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

# Step 13: Copy the provided password and paste it into the Jenkins setup page

# Step 14: Follow the prompts to complete the Jenkins setup, including installing suggested plugins

# Step 15: Create an admin user and provide other necessary information during the setup process

# Step 16: Once the setup is complete, start using Jenkins through the web browser
```
 -Install any necessary plugins for Docker and AWS integration.
2. Configure a Jenkins pipeline:
    - Create a Jenkinsfile in your code repository.

```
pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                // Build your Docker image
                script {
                    docker.build('my-app-image')
                }
            }
        }
        
        stage('Test') {
            steps {
                // Run your tests inside a Docker container
                script {
                    docker.image('my-app-image').withRun('-p 8080:8080') {
                        sh 'npm test'
                    }
                }
            }
        }
        
        stage('Deploy') {
            environment {
                AWS_ACCESS_KEY_ID = credentials('aws-access-key')
                AWS_SECRET_ACCESS_KEY = credentials('aws-secret-key')
                AWS_REGION = 'us-west-2'
            }
            
            steps {
                // Install AWS CLI
                sh 'pip install awscli'
                
                // Login to your AWS account
                sh 'aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID'
                sh 'aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY'
                sh 'aws configure set region $AWS_REGION'
                
                // Push the Docker image to ECR
                sh 'aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin <your-ecr-repo-url>'
                sh 'docker tag my-app-image:latest <your-ecr-repo-url>:latest'
                sh 'docker push <your-ecr-repo-url>:latest'
                
                // Deploy the Docker image to the AWS Linux server
                sh 'docker run -d -p 80:8080 <your-ecr-repo-url>:latest'
            }
        }
    }
}
```
- Define stages for building, testing, and deploying your application.
- Specify the Docker and AWS commands for deploying to the AWS Linux server.
3. Trigger the Jenkins pipeline:
    - Connect Jenkins to your code repository (e.g., GitHub) and configure webhooks or polling.
    - Whenever changes are pushed to the repository, Jenkins will automatically trigger the pipeline.

**Scenario 3: GitHub Actions**
GitHub Actions is a built-in CI/CD solution provided by GitHub. It allows you to define custom workflows for building, testing, and deploying your codebase. Let's see how you can use GitHub Actions for deployment:

1. Create a deployment workflow:
    - Define a YAML file (e.g., **`.github/workflows/deploy.yml`**) in your repository.

```
name: Build, Test, and Deploy

on:
  push:
    branches:
      - main

jobs:
  build-test-deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        
      - name: Set up Docker environment
        uses: docker/setup-buildx-action@v1
        
      - name: Build Docker image
        run: docker build -t my-app-image .
        
      - name: Run tests in Docker container
        run: docker run my-app-image npm test
        
      - name: Configure AWS credentials
        run: |
          echo "$AWS_ACCESS_KEY_ID" >> ~/.aws/credentials
          echo "$AWS_SECRET_ACCESS_KEY" >> ~/.aws/credentials
          chmod 600 ~/.aws/credentials
          
      - name: Install AWS CLI
        run: |
          curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
          unzip awscliv2.zip
          sudo ./aws/install
          
      - name: Log in to Amazon ECR
        run: aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin <your-ecr-repo-url>
        
      - name: Tag and push Docker image to ECR
        run: |
          docker tag my-app-image:latest <your-ecr-repo-url>:latest
          docker push <your-ecr-repo-url>:latest
          
      - name: Deploy Docker image to AWS Linux server
        run: docker run -d -p 80:8080 <your-ecr-repo-url>:latest
```
- Specify the workflow triggers, such as pushes to a specific branch.

- Configure steps for building, testing, and deploying using Docker and AWS CLI.
2. Configure AWS credentials:
    - Store your AWS credentials as secrets in the GitHub repository settings.
    - Reference the secrets in your deployment workflow for authentication.
3. Run the deployment workflow:
    - Whenever changes are pushed to the specified branch, GitHub Actions will automatically execute the deployment workflow.
    - The workflow will build a Docker image, push it to a container registry, and deploy it to the AWS Linux server.

**Conclusion:**
Efficient code deployment is crucial for maintaining a streamlined software development process. Docker, Jenkins, and GitHub Actions provide powerful tools to automate and simplify this process. By following the examples provided in this blog post, you can leverage these tools to deploy your codebase to an AWS Linux server reliably and efficiently. Remember to customize the deployment steps according to your specific application requirements and infrastructure setup. **Happy deploying!**