# deploying go to a vpn ubuntu server with github and ssl

Assumptions:

* root repository contain `` main.go with the package name `aocweb` ``
* we are using small VPS with ubuntu 20.04
* app will be deployed to `/home/web/aocweb`
* App runs HTTP on PORT 8080

### Setup user and home

some VPS have root as default user, if not already we can create a user. In this example `web`

```
adduser web
usermod -aG sudo web
```

### Install NGINX & Letsencrypt

```
sudo apt-get update
sudo apt-get install nginx
sudo ufw allow 'Nginx HTTP'

sudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx
```

Generate certificate

```
sudo certbot --nginx certonly
```

to test auto renewal

```
sudo certbot renew --dry-run
```

Add `/etc/nginx/sites-enabled/`example`.com`

```
server {
       listen         80;
       server_name    example.com;
       return         301 https://$server_name$request_uri;
}

server {
        server_name example.com;
        listen 443 ssl;
        ssl on;
        ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        root /var/www/html;

        location / {
                proxy_pass http://127.0.0.1:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }
	
	location /ws {
		proxy_buffering off;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Real-IP $remote_addr;proxy_pass http://127.0.0.1:8080/ws;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }
}
```

### Install systemd service

if the application requires environment we can put it on `/home/web/aocweb/.env`

```
ENV=prod
CLIENT_ID=abcdef
```

create `/etc/systemd/system/aocweb.service`

```
[Unit]
Description= AocWeb app
After=network.target
After=mysql.service

[Service]
User=web
Group=www-data

EnvironmentFile=/home/web/aocweb/.env
WorkingDirectory=/home/web/aocweb
ExecStart=/home/web/aocweb/aocweb web

[Install]
WantedBy=multi-user.target
```

```
sudo systemctl daemon-reload
```

To make sure we can run systemctl restart with sudo without password. Create sudo configuration file (make sure to use `visudo` so you don't accidentally locked your self.

```
visudo -f /etc/sudoers.d/systemctl
```

With content

```
web ALL=NOPASSWD: /usr/bin/systemctl restart aocweb
web ALL=NOPASSWD: /usr/bin/systemctl status aocweb
```

### Deploy with Github Action

#### Generate SSH key for deployment

```
ssh-keygen -t ed25519 -C "user@email.com"    
```

example with that command I created 2 files on `~/.ssh/` : `aocweb` & `aocweb.pub`

#### add generated public key to server

Copy the content of `aocweb.pub` to `/home/web/.ssh/authorized_key.` This allows login with ssh private key. Test that you can login to the server with that key (check `ssh -v` output)

#### Add secrets

{% embed url="<https://docs.github.com/en/actions/security-guides/encrypted-secrets>" %}

create these secrets on the github repository

* HOST
* KEY
* USERNAME

`KEY` is the content of `aocweb.pub` ssh key

#### Github workflow

create `.github/workflows/release.yaml`

```
name: Release

on:
  push:
    branches:
    - release

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: install go
      uses: actions/setup-go@v2
      with:
        go-version: '1.17.3'

    - name: build
      run: go build .

    - name: send binary
      uses: appleboy/scp-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.KEY }}
        source: "aocweb"
        target: "/home/web/aocweb"

    - name: restart
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.KEY }}
        script: sudo systemctl restart aocweb && sudo systemctl status aocweb
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://til.yulrizka.com/go/deploying-go-to-a-vpn-ubuntu-server-with-github-and-ssl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
