All checks were successful
Build and Deploy Hugo Site / build-and-deploy (push) Successful in 14s
168 lines
5.0 KiB
Markdown
168 lines
5.0 KiB
Markdown
# Sometimes Code Blog
|
|
|
|
A personal blog built with Hugo, designed for longevity and simplicity.
|
|
|
|
## Quick Start
|
|
|
|
1. **Install Hugo**: `brew install hugo`
|
|
2. **Clone with submodules**: `git clone --recurse-submodules <repo-url>`
|
|
3. **Start development server**: `hugo server --buildDrafts`
|
|
4. **View at**: http://localhost:1313
|
|
|
|
## Writing Content
|
|
|
|
### New Post
|
|
```bash
|
|
hugo new content posts/my-new-post.md
|
|
```
|
|
|
|
### Categories
|
|
- Use `categories = ['programming']` for technical posts
|
|
- Use `categories = ['family']` for personal/family posts
|
|
|
|
### Publishing
|
|
- Set `draft = false` in the frontmatter to publish
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
├── content/
|
|
│ ├── posts/ # Blog posts
|
|
│ └── pages/ # Static pages (resume, etc.)
|
|
├── themes/
|
|
│ └── sometimescode/ # Custom theme
|
|
├── hugo.toml # Site configuration
|
|
└── .gitea/workflows/ # Gitea Actions for CI/CD
|
|
```
|
|
|
|
## Deployment
|
|
|
|
### Automatic Deployment (Gitea Actions)
|
|
|
|
The site automatically builds and deploys when you push to the `main` branch using Gitea Actions.
|
|
|
|
#### Required Gitea Secrets
|
|
|
|
Configure these secrets in your Gitea repository settings (Settings → Secrets):
|
|
|
|
1. **`SSH_KEY`**: Private SSH key for deployment authentication
|
|
```bash
|
|
# Generate a new SSH key pair on the host server
|
|
ssh-keygen -t ed25519 -C "gitea-deploy@sometimescode.com" -f ~/.ssh/gitea_deploy
|
|
|
|
# Copy the PRIVATE key content (this goes in Gitea secrets)
|
|
cat ~/.ssh/gitea_deploy
|
|
|
|
# Add the PUBLIC key to authorized_keys on the host
|
|
cat ~/.ssh/gitea_deploy.pub >> ~/.ssh/authorized_keys
|
|
chmod 600 ~/.ssh/authorized_keys
|
|
```
|
|
|
|
2. **`HOST`**: IP address to reach the host from the Docker worker
|
|
- **Same-host deployment**: Use `172.17.0.1` (Docker bridge gateway IP)
|
|
- **Remote server**: Use the actual server IP or hostname
|
|
|
|
3. **`USERNAME`**: SSH username on the deployment server
|
|
- Example: `www-data`, `ubuntu`, or `deploy`
|
|
|
|
**Important for same-host deployment**: When your Gitea worker runs in Docker on the same machine as your web server, use `172.17.0.1` as the HOST. This is the default Docker bridge network IP that allows containers to reach the host machine.
|
|
|
|
#### How It Works
|
|
|
|
1. Push to `main` branch triggers the workflow
|
|
2. Gitea worker (Docker container) checks out the code
|
|
3. Hugo extended is installed via the peaceiris/actions-hugo action
|
|
4. Site is built with `hugo --minify`
|
|
5. SSH connection is established to the host (via `172.17.0.1` for same-host)
|
|
6. Built files in `public/` are copied via SCP to `/var/www/sometimescode.com/`
|
|
7. SSH keys are cleaned up after deployment
|
|
|
|
### Server Setup
|
|
|
|
1. **Server Requirements**:
|
|
- Ubuntu 22.04+ or similar Linux server
|
|
- Nginx or Caddy web server
|
|
- SSL certificate (automatic with Caddy, or use certbot with Nginx)
|
|
|
|
2. **Prepare deployment directory**:
|
|
```bash
|
|
# Create web directory
|
|
sudo mkdir -p /var/www/sometimescode.com
|
|
|
|
# Set appropriate permissions for your deploy user
|
|
sudo chown -R deploy-user:deploy-user /var/www/sometimescode.com
|
|
```
|
|
|
|
3. **Configure Web Server**:
|
|
|
|
**Option A: Caddy (Recommended - automatic HTTPS)**
|
|
```bash
|
|
# Install Caddy if not already installed
|
|
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
|
|
sudo apt update
|
|
sudo apt install caddy
|
|
|
|
# Edit Caddyfile
|
|
sudo nano /etc/caddy/Caddyfile
|
|
```
|
|
|
|
Add this configuration:
|
|
```caddy
|
|
sometimescode.com {
|
|
root * /var/www/sometimescode.com
|
|
file_server
|
|
encode gzip
|
|
}
|
|
```
|
|
|
|
```bash
|
|
# Reload Caddy
|
|
sudo systemctl reload caddy
|
|
```
|
|
|
|
**Option B: Nginx (manual SSL setup)**
|
|
```bash
|
|
# Create nginx config
|
|
sudo nano /etc/nginx/sites-available/sometimescode.com
|
|
|
|
# Enable site
|
|
sudo ln -s /etc/nginx/sites-available/sometimescode.com /etc/nginx/sites-enabled/
|
|
|
|
# Get SSL certificate
|
|
sudo certbot --nginx -d sometimescode.com -d www.sometimescode.com
|
|
|
|
# Restart nginx
|
|
sudo systemctl restart nginx
|
|
```
|
|
|
|
### Manual Deployment
|
|
|
|
If needed, you can still deploy manually:
|
|
|
|
```bash
|
|
# Build site
|
|
hugo --minify
|
|
|
|
# Upload to server
|
|
scp -r public/* user@server:/var/www/sometimescode.com/
|
|
```
|
|
|
|
## Development
|
|
|
|
- **Theme**: Custom "sometimescode" theme
|
|
- **Hugo Version**: 0.139.4+ (extended version)
|
|
- **Content Format**: Markdown with YAML frontmatter
|
|
- **Dark Mode**: Custom CSS and JavaScript implementation with toggle button
|
|
- **CI/CD**: Gitea Actions for automated build and deployment
|
|
|
|
## Philosophy
|
|
|
|
This blog is built for longevity:
|
|
- **Markdown files**: Human-readable, future-proof content
|
|
- **Static generation**: No database dependencies
|
|
- **Simple theme**: Minimal dependencies, maximum compatibility
|
|
- **Git history**: Complete version control of all content
|
|
|
|
The goal is for this blog to be readable and maintainable for decades to come. |