# Static Publishing Platform created at: 2023-02-09. if you are reading this file years later, it is very probably obsolete. based on: - Nginx as the reverse proxy (would be tricot in production) - Gitea: https://github.com/superboum/gitea - Teabag: https://github.com/denyskon/teabag - Static CMS: https://www.staticcms.org/ - Drone: https://github.com/harness/drone - Garage: https://git.deuxfleurs.fr/Deuxfleurs/garage/ ## DNS Configure a CNAME wildcard pointing to your deployment machine. My wildcard is : `*.vimaire.machine.dufour.io`. ## Launch the reverse proxy ``` docker-compose up -d reverse ``` ## Install Gitea The recommended docker-compose is a good start for this toy example: https://docs.gitea.io/en-us/install-with-docker/ You need to configure CORS: ```ini [cors] ENABLED=true ALLOW_DOMAIN=* ALLOW_CREDENTIALS=true SCHEME=* HEADERS=Content-Type,User-Agent,Authorization ``` The last entry is required but ignored in Gitea version < 1.19, you must instead use a patched image to allow the custom header `Content-Type`. For example, I am using this one: `superboum/gitea:1.17.4-cors`. Now you are ready to start your gitea instance: ``` docker-compose up -d gitea ``` Now go to `http://git.vimaire.machine.dufour.io` and configure your Gitea instance. Create an administrator account by unfolding the last section. ## Install Teabag The first step is to create some tokens for Teabag in Gitea. Go to this page: http://localhost:3000/user/settings/applications And create an Oauth2 application with the following parameters: - name: `Teabag` - callback: `http://localhost:3001/callback` Now, use the example env file from the official repo as a template. Mine look like that: ```ini HOST=0.0.0.0 PORT=3001 SESSION_SECRET=JdNF... GITEA_KEY=968c9... GITEA_SECRET=gto_65p GITEA_BASE_URL=http://localhost:3000 GITEA_AUTH_URI=login/oauth/authorize GITEA_TOKEN_URI=login/oauth/access_token GITEA_USER_URI=api/v1/user CALLBACK_URI=http://localhost:3001/callback ``` This file is fetched from `./env/teabag.env` or `/etc/teabag/teabag.env`, so pick one of this path. Check that teabag is running: ``` $ curl -I http://localhost:3001 HTTP/1.1 200 OK Date: Thu, 09 Feb 2023 13:32:15 GMT Content-Length: 73 Content-Type: text/html; charset=utf-8 ``` ## Create a blog with Jekyll I don't really like CDNs so we will locally download the javasript file once and for all. For this example, we will create a basic jekyll blog. ``` nix-shell -p bundler bundler install jekyll bundle exec jekyll new my-blog cd my-blog bundle install bundle exec jekyll serve ``` Now you website should be available at: `http://localhost:4000`. You must now create a repository for your website on our target gitea instance. Mine is `quentin/my-blog`. Use the gitea UI and then: ``` git init git add . git commit git remote add origin http://localhost:3000/quentin/my-blog.git git push -u origin main ``` ## Add "Static CMS" to your blog In your blog folder (`my-blog`), create a file at this path `admin/index.html` with this content: ```html Content Manager ``` And now, we must get the file `static-cms-app.js`. We will pull it from their CDN: ``` wget https://unpkg.com/@staticcms/app@^1.0.0/dist/static-cms-app.js ``` OR you can also build it: ``` git clone git@github.com:StaticJsCMS/static-cms.git yarn yarn build cp packages/app/dist/static-cms-app.js . ``` and finally, we need a configuration file: ```yml backend: name: gitea repo: quentin/my-blog base_url: http://localhost:3001 api_root: http://localhost:3000/api/v1 branch: main media_folder: 'assets/' site_url: http://my-blog.web.localhost display_url: http://my-blog.web.localhost locale: 'en' collections: - name: 'article' label: 'Article' folder: '_posts/' editor: preview: true create: true slug: '{{year}}-{{month}}-{{day}}-{{slug}}' fields: - { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' } - { label: 'Title', name: 'title', widget: 'string' } - { label: 'Publish Date', name: 'date', widget: 'datetime' } - { label: 'Body', name: 'body', widget: 'markdown' } ``` So, your blog folder should look like that (note the admin folder and its 3 files): ``` $ tree . ├── 404.html ├── about.markdown ├── admin │   ├── config.yml │   ├── index.html │   └── static-cms-app.js ... ``` And now you are ready to test your CMS admin interface! ``` bundle exec jekyll serve ``` And then go to: http://localhost:4000/admin/ Click on "Login with Gitea". Now you must see a dashboard, you should be able to create new articles too. That's perfect, now you can commit your admin folder, you have a basic CMS integration. ``` git add admin git commit -a git pull && git push ``` ## Install Drone Now we will want to automate the building of your website. We will need to create an Oauth2 client for Drone, similarly to Teabag. As in our example we are running Drone on `localhost:3002`, the callback URL is `http://localhost:3002/login`. (fixme: mount the sqlite db on the host) Once you have your credentials, you can launch the Drone daemon with the recommended parameters. Simply follow this doc: https://docs.drone.io/server/provider/gitea/ Then go to: http://localhost:3002 Authenticate yourself. And activate your blog repo (mine is `quentin/my-blog`). You will also need a runner to execute your builds. Check this page: https://docs.drone.io/runner/overview/ I will use a docker runner on my side. (note: I am currently using `iptables -F` as a dangerous workaround to docker's network firewalling) ## Configure Drone on your repo We will now create a `.drone.yml` file that will tell to Drone how to generate our static website. Due to my strange deployment, I need a custom cloning logic. But this is not required in a normal deployment. ```yml --- kind: pipeline name: default clone: disable: true steps: - name: clone image: alpine/git commands: - git clone http://172.17.0.1:3000/quentin/my-blog.git . - git checkout $DRONE_COMMIT - name: build image: ruby commands: - bundle install - bundle exec jekyll build - name: publish image: ruby commands: - echo pretend we publish something ``` So, great, we know how to build our website! The last step is to publish it! ## Install Garage See: https://garagehq.deuxfleurs.fr/download/ ``` docker pull dxflrs/garage:v0.8.1 ``` We will use a simple config file you can generate as follow: ```toml cat > garage.toml < /tmp/index.html aws s3 cp /tmp/index.html s3://my-blog/ curl -I http://my-blog.web.localhost:3902 ``` ## Configure Drone to deploy your website on Garage Add your keys as a drone secret in your repository. See here: https://docs.drone.io/secret/repository/ And then add this to your `.drone.yml`: ```yaml - name: upload image: plugins/s3 settings: bucket: guide endpoint: http://s3.vimaire.machine.dufour.io region: garage access_key: from_secret: aws_access_key_id secret_key: from_secret: aws_secret_acess_key source: public/**/* target: / strip_prefix: public/ ``` ## Profit Your blog should be available at this URL: http://guide.web.vimaire.machine.dufour.io You can administrate it at this URL: http://guide.web.vimaire.machine.dufour.io/admin/ ## TODO - [X] Nettoyer les inter-connexions entre les services pour ne pas avoir à drop iptables -> passé en IPv6 avec un network dédié - [ ] Voir comment speed up le build - [ ] Peut-être passer la démo sur Hugo (aiderait le point précédent) - [ ] Tester avec des templates plus complexes (avec des images en bannière) - [X] Porter ce test sur le guide Zola avec les nested collections -> Failed, trop buggy encore