# 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 ```bash 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: ```bash scp -r gitea root@:~/gitea ``` ## 2. Start the stack ```bash 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 ```bash 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: ```bash 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: ```bash 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. ```powershell 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): ```bash 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 ```bash docker compose restart gitea # restart docker compose logs -f gitea caddy # troubleshoot docker compose pull && docker compose up -d # after bumping pinned tags ```