Files

4.7 KiB

Gitea Deployment (Assignment 4 / Instructor Manual Chapter 2)

Pinned Gitea (gitea/gitea:1.27.3, SQLite) behind Caddy (caddy:2.11.4-alpine, automatic Let's Encrypt HTTPS) on the DigitalOcean droplet The-Ocean (Ubuntu 24.04, 1 vCPU, 512 MB). No secrets live in this folder.

Hostname: git.yebilly.me (set in docker-compose.yml and Caddyfile). Save the output of every step marked evidence (screenshots or copied terminal text) for the IT manual.

0. Prerequisites (done in web consoles)

  1. Domain: claim a GitHub Student Developer Pack domain. Record the offer, eligibility, first-year cost, renewal cost, and expiry date. evidence
  2. DNS: add an A record git -> droplet IPv4 at the registrar. evidence (DNS screen), then from a laptop: nslookup git.yebilly.me 1.1.1.1 evidence
  3. DigitalOcean Cloud Firewall (Networking -> Firewalls), name gitea-fw, applied to The-Ocean:
    • Inbound TCP 443 All IPv4 + All IPv6
    • Inbound TCP 80 All IPv4 + All IPv6 (redirect + certificate validation)
    • Inbound TCP 22 team public IPs only (add these first and confirm SSH still works before removing any wider SSH rule)
    • Outbound: leave default (all) so apt, Docker Hub, DNS, NTP, and Let's Encrypt remain reachable. evidence (rules screen + date)

1. Prepare the droplet

docker stop color-buttons-app && docker rm color-buttons-app   # frees port 80
# 512 MB RAM: add 1 GB swap
fallocate -l 1G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
docker --version && docker compose version                        # evidence

From the laptop, copy this folder:

scp -r gitea root@<droplet-ip>:~/gitea

2. Start the stack

cd ~/gitea
docker compose up -d
docker compose ps          # evidence: only caddy shows 0.0.0.0:80/443
docker compose logs caddy | grep -i certificate   # evidence: certificate obtained

Open https://git.yebilly.me, keep SQLite3 on the install page, create the admin account. Store its password in a password manager, never in Git or the manual.

3. HTTPS evidence

curl -sI http://git.yebilly.me     # expect 308 + Location: https://...
curl -vI https://git.yebilly.me 2>&1 | grep -Ei "issuer|expire|subject|HTTP/"

Also screenshot the browser certificate viewer (issuer, expiry). evidence

4. Renewal test (forced reissue)

Caddy renews automatically about 30 days before expiry and has no dry-run command, so force a fresh issuance:

date -u
docker compose exec caddy rm -rf /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/git.yebilly.me
docker compose restart caddy
docker compose logs --since 2m caddy | grep -i certificate        # evidence
curl -vI https://git.yebilly.me 2>&1 | grep -Ei "issuer|expire"  # new dates

Do this once; repeated reissues can hit Let's Encrypt rate limits.

5. Persistence test

In Gitea, create a repository and an issue; note the repo name and issue number. Then:

docker ps --filter name=gitea --format '{{.ID}} {{.Image}} {{.CreatedAt}}'   # before
docker compose up -d --force-recreate --no-deps gitea
docker ps --filter name=gitea --format '{{.ID}} {{.Image}} {{.CreatedAt}}'   # after: new ID
docker compose exec gitea ls -l /data/gitea/gitea.db                        # SQLite file
docker volume inspect gitea_gitea-data --format '{{.Mountpoint}}'

Reload the repo and issue in the browser. evidence (before/after screenshots). The named volume outlives the container, so data persists. This is not a backup or restore test.

6. External exposure test

Run from a laptop, not the droplet. Record source network, time, expected and actual result.

Test-NetConnection git.yebilly.me -Port 443    # expect True
Test-NetConnection git.yebilly.me -Port 80     # expect True (redirects)
Test-NetConnection git.yebilly.me -Port 22     # True from approved IP only
Test-NetConnection git.yebilly.me -Port 3000   # expect False

Repeat the port 22 check from a non-approved network (phone hotspot): expect False. Supporting on-droplet view (not proof of public exposure):

ss -tlnp
docker compose ps

7. Team workflow (Gitea UI)

Create the organization and product repository with a README, add at least two members with roles, open at least five issues (product and operations), and for two issues: branch -> pull request with Closes #N -> peer review -> merge -> issue closed. evidence (links/screenshots)

Operate

docker compose restart gitea        # restart
docker compose logs -f gitea caddy  # troubleshoot
docker compose pull && docker compose up -d   # after bumping pinned tags