Writing a blog could be much easier with a blogging platform like Wordpress, but then there wouldn't be a reason to create this post. I prefer writing my blog posts like I write documentation in markdown, versioned and self hosted. There's no need to have a big platform running just to serve simple static files.
I use hexo, gitlab and rsync in my build process.
Blogging with Hexo
Hexo is a simple, blog-aware static website framework built on top of Node.js.
Installation
$ npm install hexo-cli -g
Quick Start
Setup your blog
$ hexo init blog
$ cd blog
Start the server
$ hexo server
Generate static files
$ hexo generate
Versioning and Continuous Deployment with Gitlab
Create repository
Initialize a repository in blog and push your first commit.
git init
git remote add origin [email protected]:<user>/<project_name>.git
git add .
git commit -m "Initial commit"
git push -u origin master
Setup Continuous Deployment
Whenever you push new commits, gitlab looks for a file named .gitlab-ci.yml and fires CI/CD pipelines that build, test and deploy your code. Read rest on Gitlab.
- Create .gitlab-ci.yml file. And fill like in example:
image: node:latest
cache:
paths:
- node_modules/
stages:
- build
- deploy
job 1:
stage: build
script:
- npm install
- npm run generate
artifacts:
paths:
- public/
job 2:
stage: deploy
script:
- sshpass -V
- sshpass -e rsync -r -a -v -e 'ssh -o StrictHostKeyChecking=no -p '$SSH_PORT --delete public $REMOTE_SERVER:/var/www/html/$DIR
- Notice that $SSH_PORT, $REMOTE_SERVER, and $DIR are not set. One more variable needed by sshpass is $SSHPASS. To setup environment variables, navigate to your repository Settings > CI / CD..
- Git commit and push. Head over to your repository CI / CD > Jobs to check on deployment progress..
Serve static files
I use nginx to serve https://www.amarjanica.com. Configuration is something like:
server {
listen 80;
server_name .<host_name>;
root /var/www/html/<my_directory>;
index index.php index.html index.htm;
}
Gitlab Continuous Deployment
Instead of running software installations on each build, you could save your installs and settings to a Dockerfile, and serve the image with Gitlab's container registry.
Create docker file
Create your docker file in root of your project.
FROM node:latest
ENV LANG C.UTF-8
Build image
Log in to GitLab’s Container Registry using your GitLab username and password.
docker login registry.gitlab.com
Once you log in, you’re free to create and upload a container image using the common build and push.
docker build -t registry.gitlab.com/<user>/<repository> .
docker push registry.gitlab.com/<user>/<repository>
Reference image in ci
Edit gitlab-ci.yml
and reference your docker image:
image: registry.gitlab.com/<user>/<repo>:latest
cache:
paths:
- node_modules/
stages:
- build
- deploy
....
Troubleshoot
i/o timeout on docker push
Try changing /etc/resolv.conf nameserver to 8.8.8.8 and try again.
Permission denied
If you get permission denied when trying to rsync with remote server, then you need to add your user to www-data group.
Login to your server and change group ownership and permissions of /var/www/html:
sudo chgrp -R www-data /var/www/html
sudo gpasswd -a www-data
sudo chmod -R 775 /var/www/html
Try creating a file in /var/www/html. If you still get permission denied, you'll probably need a new login session, or a server restart.