Skip to content

Instantly share code, notes, and snippets.

@nil1729
Last active November 27, 2022 20:19
Show Gist options
  • Save nil1729/00549b5c99bc875619ff69510a73e949 to your computer and use it in GitHub Desktop.
Save nil1729/00549b5c99bc875619ff69510a73e949 to your computer and use it in GitHub Desktop.
Server setup for auto deployment

Prerequisites for Deployment

  • A remote server (I am using Digital Ocean)
  • A Gitlab Account (for container registry)

Step 1 (Creating Droplet)

  • Create a droplet (ubuntu) on Digital Ocean and choose your suitable authentication method (ssh or password)
  • log into the droplet using root and go to second step

Step 2 (Creating User)

  • Add a new user with sudo privilages [see user_add.sh]
  • logout and log into with the new user

Step 3 (Nginx installation)

  • enable and setup firewall for ssh, http, https [see firewall_setup.sh]'
  • Install nginx on that VPS [see nginx_install.sh]

Step 4 (docker installation)

  • You can follow official docker installation guide for ubuntu
  • follow this guide to run docker without sudo

Step 5 (docker image)

  • You have to create image for your application which you want to deploy (Dockerfile I mean)
  • as dockerhub allows only one private repository, we will use Gitlab projects as our registry (We can use public registry if our repository is public)
  • Now we have to pull those images and start the container based on those images
  • Build and Test the docker image
    • docker login registry.gitlab.com
    • docker build registry.gitlab.com/<gitlab_username>/<project_name>
    • docker run registry.gitlab.com/<gitlab_username>/<project_name> (run with required parameters which you need)
    • docker push registry.gitlab.com/<gitlab_username>/<project_name>

Step 6 (onboarding application)

  • Now we have to pull those images on our VPS and run and also expose those application to the internet
  • Login to the docker registry and pull required images
  • You have to also setup nginx to load balance the traffic to the coorect backend service
  • first you have to create a <app_name>.nginx.conf file at /etc/nginx/conf.d [See example-app.nginx.conf]
  • Update the nginx configuration at /etc/nginx/sites-available/default [See server.nginx.conf]

Step 7 (sync.sh)

  • now create a bash script which will sync your docker images; pull new image and run the new container and delete the old running container
  • this script will take application name as input and based on the application name it will check the avilable system port which is allocated to that application during step 6 (<app_name>.nginx.conf)

Step 8 (deploy.sh)

  • this script will start the process for our auto-deployment if there is no running containers or our system restarted
  • we have to register a service which will run this script when system restarted
  • Registering deployment.service [see `deployment.service]
      $ sudo cp deployment.service /etc/systemd/system/deployment.service
      $ sudo chmod 644 /etc/systemd/system/deployment.service
      $ sudo systemctl start deployment
      $ sudo systemctl status deployment
      $ sudo systemctl enable deployment
    

Step 9 (Final Step)

  • Now restart your system using sudo reboot
  • it will automatically install all the images and start all your applications
  • DONE!! 🎉

Step 10 (Automate with Gh Actions)

  • You can visit this repo to understand how to integrate this feature with github actions and setup auto deployment
#!/bin/bash
echo "Restarting Applications"
echo
CONTAINER_REGISTRY="registry.gitlab.com"
REGISTRY_USERNAME=""
REGISTRY_PASSWORD=""
#Registry Setup
echo $REGISTRY_PASSWORD | docker login $CONTAINER_REGISTRY -u $REGISTRY_USERNAME --password-stdin
#Image Registry
APPLICATION_EXAMPLE_APP="registry.gitlab.com/example/project"
echo "Starting Example App"
docker pull $APPLICATION_EXAMPLE_APP
docker run \
--rm -d \
-p <any_allocated_port_for_app>:5050 \
-v "<any secret file your want to mount from VPS>" \
$APPLICATION_FOOD_ORDER_APP
# installing another application here
[Unit]
Description=Deployment service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
RemainAfterExit=yes
User=username
TimeoutStartSec=0
ExecStart=bash <absolute path to `deploy.sh`>
[Install]
WantedBy=multi-user.target
# replace app_name with your suitable applicaion name
# choose any two ports of your choice
upstream app_name {
server localhost:5001;
server localhost:5002;
}
sudo ufw enable
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo apt-get update
sudo apt-get nginx
server {
server_name your_app_domain_name;
location / {
proxy_pass http://app_name;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
# replace `your_app_domain_name` with correct domain name
# replace `app_name` with the application name you choose on the last step
#!/bin/bash
#Image Registry
APPLICATION_EXAMPLE_APP="registry.gitlab.com/example/project"
CURRENT_APP_NAME=$1
case $CURRENT_APP_NAME in
"example-app")
echo "Sycing Example Application ..."
echo
RUNNING_CONTAINER_ID=$(docker ps -aq --filter ancestor="$APPLICATION_EXAMPLE_APP")
ALLOCATED_PORT=5001 # step 6 (5001, 5002)
FREE_PORT_COUNT=$(nc -zv localhost $ALLOCATED_PORT 2>&1 >/dev/null | grep -c failed)
if [[ $FREE_PORT_COUNT -gt 0 ]]; then
FREE_PORT=5001
else
FREE_PORT=5002
fi
docker pull $APPLICATION_EXAMPLE_APP
docker run \
--rm -d \
-p $FREE_PORT:5050 \
-v "<any secret file your want to mount from VPS>" \
$APPLICATION_EXAMPLE_APP
docker stop $RUNNING_CONTAINER_ID
;;
"another-app")
# write steps
;;
*)
echo "Application not registered"
exit 1
;;
esac
exit 0
sudo adduser <username>
sudo usermod -aG sudo <username>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment