最近心血來潮,想說來挑戰看看,linode $5 方案,可以做哪些事情。剛好之前就一直想把自己 github & gitea 上的服務做一個 CI & CD 整合。

首先,自己的 linode 全面 container 化,所以任何服務在上面都是已 container 化執行。在這裡我們先做 gitea的安裝

GITEA:

sudo docker run -d --name=gitea -p {{YOUR_GIT_SSH_PORT}}:22 -p {{YOUR_GITA_HTTP_PORT}}:3000 -v {{YOUR_PATH}}:/data gitea/gitea:1.7.4

NGINX CONF:

這樣就很輕鬆的啟動了 gitea。雖然我有把 port export 出來,但那是為了一些除錯方便,但基本上我最外層都有掛上一個 nginx 做 reverse_proxy , 下面是我 gitea nginx 的設定檔

server {
       #listen 80;
       #listen [::]:80;
       listen 443 ssl;
       ssl_certificate /etc/letsencrypt/live/syhlion.tw/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/syhlion.tw/privkey.pem;
       server_name {{YOUR_DOMAIN}};

       access_log /tmp/nginx-proxy-access.log;
       error_log /tmp/nginx-proxy-error.log debug;
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_ciphers ECDH+AESGCM:EDCH+AES256:ECDH+AES128:!MD5:!aNULL;
       ssl_prefer_server_ciphers on;
       client_max_body_size 40M;

       ssl_session_cache shared:SSL:10m;
       ssl_session_timeout 1h;
       ssl_stapling on;
       ssl_stapling_verify on;

       location / {
		proxy_pass http://{{YOUR_GITEA_CONTAINER_NAME}}:3000;
       }

}

server {
    listen 80;
    server_name {{YOUR_DOMAIN}};
    return 301 https://$host$request_uri;
}

在這邊順邊連兩套 drone 的 nginx 設定也一併弄一弄,分別如下

為什麼要用兩個 drone instance ,因為 drone 的機制下,一個 instance 只能跟一個 git services 認證,所以今天我要 github & gitlab 都能擁有 drone 的機制,我就必須啟動兩個 instance,相對也必須要有個 domain

GITHUB DRONE NGINX CONF:

server {
       #listen 80;
       #listen [::]:80;
       listen 443 ssl;
       ssl_certificate /etc/letsencrypt/live/syhlion.tw/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/syhlion.tw/privkey.pem;
       server_name {{YOUR_DRONE_DOMAIN_FOR_GITHUB}};

       access_log /tmp/nginx-proxy-access.log;
       error_log /tmp/nginx-proxy-error.log debug;
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_ciphers ECDH+AESGCM:EDCH+AES256:ECDH+AES128:!MD5:!aNULL;
       ssl_prefer_server_ciphers on;
       client_max_body_size 40M;

       ssl_session_cache shared:SSL:10m;
       ssl_session_timeout 1h;
       ssl_stapling on;
       ssl_stapling_verify on;

       location / {
		log_not_found on;

        	proxy_set_header X-Forwarded-For $remote_addr;
        	proxy_set_header X-Forwarded-Proto $scheme;
        	proxy_set_header Host $http_host;
		proxy_redirect off;
        	proxy_http_version 1.1;
        	proxy_buffering off;

        	chunked_transfer_encoding off;

		proxy_pass http://{{YOUR_DRONE_FOR_GITHUB_CONTAINER_NAME}};
       }

}

server {
    listen 80;
    server_name {{YOUR_DRONE_DOMAIN_FOR_GITHUB}};
    return 301 https://$host$request_uri;
}

GITEA NGINX CONF:

server {
       #listen 80;
       #listen [::]:80;
       listen 443 ssl;
       ssl_certificate /etc/letsencrypt/live/syhlion.tw/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/syhlion.tw/privkey.pem;
       server_name {{YOUR_DRONE_DOMAIN_FOR_GITEA}};

       access_log /tmp/nginx-proxy-access.log;
       error_log /tmp/nginx-proxy-error.log debug;
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_ciphers ECDH+AESGCM:EDCH+AES256:ECDH+AES128:!MD5:!aNULL;
       ssl_prefer_server_ciphers on;
       client_max_body_size 40M;

       ssl_session_cache shared:SSL:10m;
       ssl_session_timeout 1h;
       ssl_stapling on;
       ssl_stapling_verify on;

       location / {
		log_not_found on;

        	proxy_set_header X-Forwarded-For $remote_addr;
        	proxy_set_header X-Forwarded-Proto $scheme;
        	proxy_set_header Host $http_host;
		proxy_redirect off;
        	proxy_http_version 1.1;
        	proxy_buffering off;

        	chunked_transfer_encoding off;

		proxy_pass http://{{YOUR_DRONE_FOR_GITEA_CONTAINER_NAME}};
       }

}

server {
    listen 80;
    server_name {{YOUR_DRONE_DOMAIN_FOR_GITEA}};
    return 301 https://$host$request_uri;
}

我自己的 ssl 是用 letsencrypt,有興趣可以參考我之前的 如何讓 letsencrypt 用在 docker nginx 上面

DRONE:

再來就是啟動 drone image,語法如下

github:

sudo docker run \
  --volume=/var/run/docker.sock:/var/run/docker.sock \
  --volume={{YOUR_DATA_PATH}}:/data \
  --env=DRONE_GITHUB_SERVER=https://github.com \
  --env=DRONE_GITHUB_CLIENT_ID={{YOUR_GITHUB_CLIENT_ID}} \
  --env=DRONE_GITHUB_CLIENT_SECRET={{YOUR_GITHUB_CLIENT_SECRET}} \
  --env=DRONE_RUNNER_CAPACITY=1 \
  --env=DRONE_SERVER_HOST={{YOUR_DRONE_FOR_GITHUB_DOMAIN}} \
  --env=DRONE_SERVER_PROTO=https \
  --env=DRONE_TLS_AUTOCERT=true \
  --publish={{YOUR_DRONE_FOR_GITHUB_EXPORT_80PORT}}:80 \
  --publish={{YOUR_DRONE_FOR_GITHUB_EXPORT_443PORT}}:443 \
  --restart=always \
  --detach=true \
  --name={{YOUR_DRONE_FOR_GITHUB_CONTAINER_NAME}} \
  drone/drone:1.0.0-rc.6

在這邊需要在 github 註冊 oauth app。 github doc

gitea:

sudo docker run \
  --volume=/var/run/docker.sock:/var/run/docker.sock \
  --volume=/home/scott/drone_data2:/data \
  --env=DRONE_GITEA_SERVER=https://git.syhlion.tw \
  --env=DRONE_GIT_ALWAYS_AUTH=false \
  --env=DRONE_RUNNER_CAPACITY=1 \
  --env=DRONE_SERVER_HOST={{YOUR_DRONE_DOMAIN_FOR_GITEA}} \
  --env=DRONE_SERVER_PROTO=https \
  --env=DRONE_TLS_AUTOCERT=false \
  --publish={{YOUR_DRONE_FOR_GITEA_EXPORT_80PORT}}:80 \
  --publish={{YOUR_DRONE_FOR_GITEA_EXPORT_443PORT}}:443 \
  --restart=always \
  --detach=true \
  --name={{YOUR_DRONE_FOR_GITEA_CONTAINER_NAME}} \
  drone/drone:1.0.0-rc.6

NGINX:

最後再啟動 nginx image

sudo docker run --name {{YOUR_NGINX_CONTAINER_NAME}} -p 80:80 -p 443:443 --link {{YOUR_DRONE_FOR_GITEA_CONTAINER_NAME}}:{{YOUR_DRONE_FOR_GITEA_CONTAINER_NAME}} --link {{YOUR_DRONE_FOR_GITHUB_CONTAINER_NAME}}:{{YOUR_DRONE_FOR_GITHUB_CONTAINER_NAME}} --link {{YOUR_GITEA_CONTAINER_NAME}}:{{YOUR_GITEA_COMTAINER_NAME}} -v {{YOUR_NGINX_CONF_PATH}}:/etc/nginx/conf.d/  -v /etc/letsencrypt:/etc/letsencrypt -v {{YOUR_WWW_PATH}}:/usr/share/nginx/html -d nginx

目前使用心得,在 linode $5 美金,只有1 core 的情況下,跑起來還算可以,不愧都是用 golang 寫的服務,除了 build 過程稍慢,但畢竟是自用,只求方便不求效率來說,這個方案的確是非常便宜好用的。