Ghost 블로그를 CLI에서 Docker로 옮기고, Analytics까지 붙였습니다
처음에는 단순히 “Ghost 블로그에 조회수 좀 보고 싶다” 정도였습니다.
그런데 막상 들여다보니 일이 조금 커졌습니다.
Ghost는 CLI 방식으로 떠 있었고, DB는 MariaDB였습니다.
블로그는 잘 돌아가고 있었지만, Ghost 6에서 내장 Web Analytics를 제대로 쓰려면 Docker 기반 구성이 훨씬 자연스러워 보였습니다.
그래서 결국 오늘 한 일은 이겁니다.
Ghost CLI로 돌던 블로그를 Podman Compose 기반 Docker 구조로 옮기고,
MariaDB를 MySQL 8로 이전하고,
마지막으로 Tinybird 기반 Ghost Web Analytics까지 붙였습니다.
대단한 기능을 만든 건 아니지만, 블로그 운영의 밑바닥을 다시 다진 하루였습니다.
시작 상태 확인
먼저 현재 Ghost가 어떻게 떠 있는지 확인했습니다.
처음에는 당연히 /var/www/ghost에서 Ghost CLI 인스턴스가 잡힐 줄 알았습니다.
cd /var/www/ghost
ghost ls
그런데 결과는 이랬습니다.
No installed ghost instances found
순간 조금 찝찝했습니다.
“어? 블로그는 잘 떠 있는데 Ghost CLI 인스턴스가 없다고?”
그래서 프로세스와 systemd를 확인했습니다.
ps -ef | grep -i ghost | grep -v grep
systemctl list-units --type=service | grep -i ghost
sudo ss -lntp | grep -E '2368|ghost|node'
확인해보니 Ghost는 이렇게 떠 있었습니다.
ghost run
/usr/bin/node current/index.js
ghost-blog.service
127.0.0.1:2368
그리고 Caddy는 blog.goodtek.xyz를 127.0.0.1:2368로 프록시하고 있었습니다.
blog.goodtek.xyz {
reverse_proxy 127.0.0.1:2368
}
즉 기존 구조는 이랬습니다.
blog.goodtek.xyz
→ Caddy
→ 127.0.0.1:2368
→ systemd Ghost
→ MariaDB
Ghost 설정 확인
실제 설정 파일을 열어보니 DB 정보와 content 경로가 확인됐습니다.
cat /var/www/ghost/config.production.json
핵심은 이랬습니다.
{
"url": "https://blog.goodtek.xyz",
"server": {
"port": 2368,
"host": "127.0.0.1"
},
"database": {
"client": "mysql",
"connection": {
"host": "localhost",
"user": "ghostuser",
"database": "ghost_prod"
}
},
"paths": {
"contentPath": "/var/www/ghost/content"
}
}
여기서 중요한 건 두 가지였습니다.
DB 이름은 ghost_prod
콘텐츠 경로는 /var/www/ghost/content
즉 게시글 본문은 DB에 있고, 이미지와 테마 파일은 content 디렉터리에 있었습니다.
DB가 MySQL이 아니라 MariaDB였습니다
Ghost 설정에는 client: mysql이라고 되어 있었지만, 실제 DB 버전을 확인해보니 MariaDB였습니다.
mysql -u ghostuser -p -e "SELECT VERSION();"
결과는 이랬습니다.
10.5.29-MariaDB
Ghost가 돌아가고는 있었지만, Docker로 이관하는 김에 MySQL 8로 정리하는 게 맞다고 판단했습니다.
그래서 목표 구조를 이렇게 잡았습니다.
기존 MariaDB 10.5
→ mysqldump
→ Docker MySQL 8
→ Docker Ghost
백업부터 했습니다
이런 작업은 결국 “되돌릴 수 있느냐”가 제일 중요합니다.
먼저 content를 백업했습니다.
sudo mkdir -p /root/ghost-migration-backup
sudo tar -czvf /root/ghost-migration-backup/ghost-content-$(date +%Y%m%d-%H%M%S).tar.gz \
-C /var/www/ghost content
DB도 dump를 뜨려고 했는데, 처음에는 에러가 났습니다.
mysqldump -u ghostuser -p \
--single-transaction \
--quick \
--routines \
--triggers \
--default-character-set=utf8mb4 \
ghost_prod > /tmp/ghost_prod.sql
에러는 이랬습니다.
Cannot load from mysql.proc. The table is probably corrupted
Ghost 이관에는 routines가 꼭 필요한 구조는 아니라고 보고, --routines, --triggers를 빼고 다시 dump를 떴습니다.
mysqldump -u ghostuser -p \
--single-transaction \
--quick \
--default-character-set=utf8mb4 \
ghost_prod > /tmp/ghost_prod.sql
이번에는 성공했습니다.
/tmp/ghost_prod.sql 1.6M
그리고 백업 폴더로 옮겼습니다.
sudo mv /tmp/ghost_prod.sql /root/ghost-migration-backup/ghost_prod-20260601-101756.sql
백업 파일은 이렇게 확보됐습니다.
ghost-content-20260601-101546.tar.gz 52M
ghost_prod-20260601-101756.sql 1.6M
SQL 파일 안에 posts 테이블이 있는지도 확인했습니다.
sudo grep -n "CREATE TABLE.*posts" /root/ghost-migration-backup/ghost_prod-20260601-101756.sql | head
CREATE TABLE `posts`
CREATE TABLE `posts_authors`
CREATE TABLE `posts_meta`
CREATE TABLE `posts_tags`
여기까지 보고 나서야 안심이 됐습니다.
Docker 작업 경로는 /home/web/goodtek/ghost-blog
저는 기존 goodtek 관련 서비스들을 /home/web/goodtek 아래에 모아두고 있어서, Ghost도 이쪽으로 옮겼습니다.
cd /home/web/goodtek
mkdir -p ghost-blog
cd ghost-blog
mkdir -p content mysql backup
백업 파일도 작업 폴더로 복사했습니다.
sudo cp /root/ghost-migration-backup/ghost-content-20260601-101546.tar.gz ./backup/
sudo cp /root/ghost-migration-backup/ghost_prod-20260601-101756.sql ./backup/
sudo chown -R web:web ./backup
그리고 content를 복원했습니다.
tar -xzvf backup/ghost-content-20260601-101546.tar.gz
복원 후 확인해보니:
content 전체: 83M
images: 52M
themes: 1.4M
이미지와 테마까지 잘 들어와 있었습니다.
.env와 docker-compose.yml 작성
DB 비밀번호는 기존 것을 그대로 쓰지 않고 새로 만들었습니다.
cat > .env <<EOF
MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')
MYSQL_DATABASE=ghost_prod
MYSQL_USER=ghostuser
MYSQL_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')
GHOST_URL=https://blog.goodtek.xyz
EOF
chmod 600 .env
처음에는 테스트를 위해 Ghost를 2369 포트로 띄웠습니다.
기존 운영 Ghost가 2368을 쓰고 있었기 때문입니다.
services:
mysql:
image: docker.io/library/mysql:8.0
container_name: ghost-blog-mysql
restart: unless-stopped
env_file:
- .env
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
- ./mysql:/var/lib/mysql
networks:
- ghost-blog-net
ghost:
image: docker.io/library/ghost:6
container_name: ghost-blog-app
restart: unless-stopped
env_file:
- .env
environment:
url: ${GHOST_URL}
database__client: mysql
database__connection__host: mysql
database__connection__user: ${MYSQL_USER}
database__connection__password: ${MYSQL_PASSWORD}
database__connection__database: ${MYSQL_DATABASE}
server__host: 0.0.0.0
server__port: 2368
ports:
- "127.0.0.1:2369:2368"
volumes:
- ./content:/var/lib/ghost/content
depends_on:
- mysql
networks:
- ghost-blog-net
networks:
ghost-blog-net:
driver: bridge
MySQL 8 컨테이너에 DB 복원
먼저 MySQL만 올렸습니다.
podman-compose up -d mysql
접속 확인:
set -a
source .env
set +a
podman exec ghost-blog-mysql \
mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" \
-e "SELECT VERSION(); SHOW DATABASES;"
결과는 MySQL 8이었습니다.
8.0.46
ghost_prod
이제 기존 MariaDB dump를 MySQL 8에 복원했습니다.
podman exec -i ghost-blog-mysql \
mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" \
< backup/ghost_prod-20260601-101756.sql
테이블도 확인했습니다.
podman exec ghost-blog-mysql \
mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" \
-e "SHOW TABLES;" | wc -l
82
게시글 수 역시 기존 MariaDB와 Docker MySQL이 일치했습니다.
SELECT status, COUNT(*) AS cnt FROM posts GROUP BY status;
published 7
Ghost 컨테이너 실행 중 만난 첫 번째 문제: 깨진 테마 링크
Ghost 컨테이너를 실행했더니 처음에는 바로 죽었습니다.
로그는 이랬습니다.
chown: cannot dereference '/var/lib/ghost/content/themes/source': No such file or directory
chown: cannot dereference '/var/lib/ghost/content/themes/casper': No such file or directory
확인해보니 content/themes 안에 깨진 심볼릭 링크가 있었습니다.
ls -al content/themes
casper -> /var/www/ghost/current/content/themes/casper
source -> /var/www/ghost/current/content/themes/source
edition
기존 CLI 설치에서는 유효했지만, Docker 안에서는 /var/www/ghost/current/... 경로가 없으니 깨진 링크가 된 겁니다.
실제로 쓰는 테마는 edition이었기 때문에, 깨진 링크만 삭제했습니다.
sudo rm content/themes/casper
sudo rm content/themes/source
그 후 Ghost 컨테이너가 정상 기동됐습니다.
Ghost is running in production...
Database is in a ready state.
Ghost database ready
테스트 확인
테스트 포트 2369로 API 응답을 확인했습니다.
curl -s \
-H "Host: blog.goodtek.xyz" \
-H "X-Forwarded-Proto: https" \
http://127.0.0.1:2369/ghost/api/content/posts/?key=invalid \
| head -c 300
응답은 JSON이었습니다.
{"errors":[{"message":"Unknown Content API Key"}]}
이건 오히려 정상입니다.
Ghost API가 살아 있고, DB도 읽고 있다는 뜻입니다.
이미지도 확인했습니다.
curl -I \
-H "Host: blog.goodtek.xyz" \
-H "X-Forwarded-Proto: https" \
http://127.0.0.1:2369/content/images/2026/05/blog-thumbnail-1.png
HTTP/1.1 200 OK
Content-Type: image/png
여기까지 확인하고 나서 운영 전환으로 넘어갔습니다.
운영 포트를 2368로 전환
처음에는 Docker Ghost를 계속 2369로 두고 Caddy만 바꿀까도 생각했습니다.
하지만 최종적으로는 더 깔끔하게 2368을 그대로 쓰기로 했습니다.
순서는 이렇게 진행했습니다.
1. Docker compose 백업
2. docker-compose.yml 포트 2369 → 2368 수정
3. Docker Ghost 중지
4. 기존 systemd Ghost 중지
5. Docker Ghost를 2368로 기동
6. Caddy는 그대로 유지
포트 수정:
sed -i 's|127.0.0.1:2369:2368|127.0.0.1:2368:2368|' docker-compose.yml
기존 systemd Ghost 중지:
sudo systemctl stop ghost-blog.service
포트 확인:
sudo ss -lntp | grep 2368 || echo "2368 is free"
Docker Ghost 기동:
podman-compose up -d ghost
최종 확인:
curl -I https://blog.goodtek.xyz
curl -I https://blog.goodtek.xyz/ghost/
둘 다 정상 응답이 나왔습니다.
HTTP/2 200
이제 구조는 이렇게 바뀌었습니다.
blog.goodtek.xyz
→ Caddy
→ 127.0.0.1:2368
→ Docker Ghost
→ Docker MySQL 8
Gmail SMTP 설정 복구
전환 후 로그인은 잘 됐지만, 메일 발송이 실패했습니다.
Ghost Admin에서 보인 메시지는 이랬습니다.
Failed to send email. Please check your site configuration and try again.
원인은 간단했습니다.
기존 config.production.json에는 Gmail SMTP 인증 정보가 있었는데, Docker compose에는 auth.user, auth.pass가 빠져 있었습니다.
.env에 Gmail 앱 비밀번호를 추가했습니다.
read -s -p "GMAIL_APP_PASSWORD: " GMAIL_APP_PASSWORD
echo
printf '\nGMAIL_USER=goodtek.xyz@gmail.com\nGMAIL_APP_PASSWORD=%s\n' "$GMAIL_APP_PASSWORD" >> .env
그리고 compose에 추가했습니다.
mail__options__auth__user: ${GMAIL_USER}
mail__options__auth__pass: ${GMAIL_APP_PASSWORD}
Ghost가 실제로 설정을 읽는지도 확인했습니다.
podman exec ghost-blog-app sh -c 'cd /var/lib/ghost/current && node -e "const config=require(\"./core/shared/config\"); console.log(config.get(\"mail\"))"'
결과:
transport: SMTP
from: Goodtek <goodtek.xyz@gmail.com>
host: smtp.gmail.com
port: 587
secure: false
auth: ...
그 후 메일 발송도 정상 동작했습니다.
기존 CLI 정리
Docker 전환이 끝난 뒤에는 기존 systemd Ghost가 다시 살아나지 않도록 비활성화했습니다.
sudo systemctl disable ghost-blog.service
상태는 이렇게 됐습니다.
ghost-blog.service: disabled
Active: inactive (dead)
이후 기존 /var/www/ghost도 삭제했습니다.
sudo rm -rf /var/www/ghost
systemd 서비스 파일도 삭제했습니다.
sudo rm -f /etc/systemd/system/ghost-blog.service
sudo systemctl daemon-reload
마지막으로 Ghost CLI도 제거했습니다.
sudo npm uninstall -g ghost-cli
그런데 /usr/local/bin/ghost 심볼릭 링크가 남아 있어서 직접 정리했습니다.
sudo rm -f /usr/local/bin/ghost
sudo rm -rf /usr/local/lib/node_modules/ghost-cli
확인 결과:
ghost command removed
ghost-cli node_modules removed
이제 Ghost CLI 기반 흔적은 정리됐습니다.
Ghost Analytics 붙이기

Docker 전환을 한 이유 중 하나가 Ghost 내장 Web Analytics였습니다.
Ghost Admin에 들어가보니 Analytics 메뉴는 보였지만, Web analytics는 Tinybird 설정이 필요하다고 나왔습니다.
Web analytics
Cookie-free, first party traffic analytics for your site
Web analytics in Ghost is powered by Tinybird and requires configuration
그래서 Tinybird를 붙였습니다.
Tinybird 공식 구성 확인
Ghost 공식 Docker repo를 /tmp에 받아서 analytics 관련 compose 구성을 확인했습니다.
cd /tmp
git clone https://github.com/TryGhost/ghost-docker.git ghost-docker
cd ghost-docker
grep -R "tinybird-login\|traffic-analytics\|tinybird-sync\|tinybird-deploy" -n .
필요한 서비스는 이 네 가지였습니다.
traffic-analytics
tinybird-login
tinybird-sync
tinybird-deploy
공식 compose를 참고해서 현재 운영 compose에 analytics 관련 서비스를 추가했습니다.
그리고 Tinybird helper 파일도 복사했습니다.
cd /home/web/goodtek/ghost-blog
cp -R /tmp/ghost-docker/tinybird ./tinybird
.env에는 Tinybird 값을 넣을 자리를 만들었습니다.
cat >> .env <<'EOF'
# Ghost Web Analytics / Tinybird
TINYBIRD_API_URL=https://api.tinybird.co
TINYBIRD_ADMIN_TOKEN=
TINYBIRD_WORKSPACE_ID=
TINYBIRD_TRACKER_TOKEN=
EOF
Tinybird 로그인과 배포
Tinybird 로그인은 서버 컨테이너 안에서 진행되기 때문에, 처음에는 localhost callback에서 막혔습니다.
Tinybird가 이런 주소를 열려고 했습니다.
http://localhost:49160/...
문제는 이 localhost가 제 Mac이 아니라 서버 쪽 컨테이너 기준이라는 점이었습니다.
그래서 SSH 터널을 열었습니다.
ssh -i "키파일경로" \
-L 49160:127.0.0.1:49160 \
web@서버IP
그 후 Tinybird 로그인에 성공했습니다.
Workspace: goodtek_blog
User: goodtek.xyz@gmail.com
Host: https://api.ap-east-1.aws.tinybird.co
Authentication successful
API URL도 리전 URL로 바꿨습니다.
sed -i 's|^TINYBIRD_API_URL=.*|TINYBIRD_API_URL=https://api.ap-east-1.aws.tinybird.co|' .env
이후 Tinybird sync를 실행했습니다.
podman-compose run --rm tinybird-sync
결과:
Tinybird files synced into shared volume.
그리고 deploy를 실행했습니다.
podman-compose run --rm tinybird-deploy
배포 결과:
Deployment #1 is live!
Tinybird datasource, pipe, endpoint, token이 생성됐습니다.
Tinybird 토큰 반영
토큰은 아래 명령어로 가져왔습니다.
podman-compose run --rm tinybird-login get-tokens
출력된 값은 .env에 반영했습니다.
TINYBIRD_API_URL
TINYBIRD_WORKSPACE_ID
TINYBIRD_ADMIN_TOKEN
TINYBIRD_TRACKER_TOKEN
그리고 Ghost가 Tinybird 설정을 실제로 읽는지도 확인했습니다.
podman exec ghost-blog-app sh -c 'cd /var/lib/ghost/current && node - <<'"'"'NODE'"'"'
const config = require("./core/shared/config");
const keys = [
"tinybird:tracker:endpoint",
"tinybird:adminToken",
"tinybird:workspaceId",
"tinybird:tracker:datasource",
"tinybird:stats:endpoint"
];
for (const k of keys) {
const v = config.get(k);
console.log(k + " = " + (v ? String(v).slice(0, 12) + "..." : ""));
}
NODE'
결과는 모두 값이 들어가 있었습니다.
tinybird:tracker:endpoint = https://blog...
tinybird:adminToken = ...
tinybird:workspaceId = ...
tinybird:tracker:datasource = analytics_ev...
tinybird:stats:endpoint = https://api....
traffic-analytics 컨테이너 추가
Ghost Web Analytics는 브라우저에서 바로 Tinybird로 쏘는 게 아니라, traffic-analytics 서비스가 중간에서 받아서 Tinybird로 넘기는 구조입니다.
처음에는 3000 포트를 쓸까 했지만, 3000은 다른 서비스와 충돌할 가능성이 높아서 13000으로 열었습니다.
127.0.0.1:13000
→ traffic-analytics:3000
포트 확인:
sudo ss -lntp | grep ':13000' || echo "13000 is free"
compose에는 이렇게 추가했습니다.
traffic-analytics:
image: docker.io/ghost/traffic-analytics:1.0.244
container_name: ghost-blog-traffic-analytics
restart: unless-stopped
ports:
- "127.0.0.1:13000:3000"
environment:
NODE_ENV: production
PROXY_TARGET: ${TINYBIRD_API_URL}/v0/events
SALT_STORE_TYPE: file
SALT_STORE_FILE_PATH: /data/salts.json
TINYBIRD_TRACKER_TOKEN: ${TINYBIRD_TRACKER_TOKEN}
LOG_LEVEL: info
volumes:
- traffic_analytics_data:/data
networks:
- ghost-blog-net
실행:
podman-compose up -d traffic-analytics
확인:
podman ps --filter name=ghost-blog-traffic-analytics
127.0.0.1:13000->3000/tcp
Caddy에 Analytics 프록시 추가
Caddy에서 Ghost Analytics 요청만 traffic-analytics로 보내도록 추가했습니다.
기존:
blog.goodtek.xyz {
reverse_proxy 127.0.0.1:2368
}
변경 후:
blog.goodtek.xyz {
handle_path /.ghost/analytics/* {
reverse_proxy 127.0.0.1:13000
}
reverse_proxy 127.0.0.1:2368
}
설정 검증:
sudo caddy validate --config /etc/caddy/Caddyfile
결과:
Valid configuration
그리고 reload:
sudo systemctl reload caddy
프록시 연결도 확인했습니다.
curl -I https://blog.goodtek.xyz/.ghost/analytics/api/v1/page_hit
그리고 traffic-analytics 로그에서 요청이 들어오는 것을 확인했습니다.
IncomingRequest
requestMethod: HEAD
requestUrl: /api/v1/page_hit
실제 방문 이벤트 수집 확인
마지막으로 브라우저에서 블로그를 열고 traffic-analytics 로그를 확인했습니다.
podman logs --tail 120 ghost-blog-traffic-analytics
드디어 실제 POST 이벤트가 찍혔습니다.
requestMethod: POST
requestUrl: /api/v1/page_hit?name=analytics_events
referer: https://blog.goodtek.xyz/
source: https://api.ap-east-1.aws.tinybird.co/v0/events
message: response received
이걸 보고 Analytics 수집이 정상 연결됐다고 판단했습니다.
흐름은 이렇게 됩니다.
방문자 브라우저
→ blog.goodtek.xyz/.ghost/analytics/api/v1/page_hit
→ Caddy
→ 127.0.0.1:13000
→ traffic-analytics
→ Tinybird ap-east-1
→ Ghost Admin Analytics
Ghost Admin에서도 Analytics 화면이 보였습니다.
여기까지 오니 “이제 진짜 붙었다”는 느낌이 들었습니다.
Tinybird 비용 확인

Tinybird는 현재 Free plan이었습니다.
화면 기준으로는:
Free plan
1,000 requests/day
10GB Cloud Storage
Upgrade from $25/mo
현재 사용량은 아주 낮았습니다.
8 / 1,000 requests/day
0GB / 10GB storage
초기 블로그 트래픽에서는 당장 비용 걱정은 크지 않아 보입니다.
다만 방문자가 늘면 page hit, analytics 조회 API 등이 request로 쌓일 수 있으니, Usage는 종종 확인할 예정입니다.
최종 구조
최종적으로 goodtek 블로그는 이렇게 바뀌었습니다.
https://blog.goodtek.xyz
→ Caddy
→ 127.0.0.1:2368
→ ghost-blog-app
→ ghost-blog-mysql
Analytics는 별도 흐름입니다.
/.ghost/analytics/*
→ Caddy
→ 127.0.0.1:13000
→ ghost-blog-traffic-analytics
→ Tinybird
현재 운영 컨테이너는 이렇습니다.
ghost-blog-app
ghost-blog-mysql
ghost-blog-traffic-analytics
운영 명령어는 이 정도만 기억하면 됩니다.
cd /home/web/goodtek/ghost-blog
podman-compose ps
podman-compose logs -f ghost
podman-compose logs -f traffic-analytics
podman-compose restart ghost
podman-compose restart traffic-analytics
podman-compose up -d
백업도 남겨두었습니다.
/root/ghost-migration-backup
/home/web/goodtek/ghost-blog/backup
docker-compose.yml.bak-before-analytics-20260601-113938
/etc/caddy/Caddyfile.bak-before-ghost-analytics-20260601-115552
해보니 느낀 점
처음에는 단순히 “조회수 보고 싶다”였습니다.
그런데 막상 해보니 조회수를 보기 위해 필요한 일은 단순하지 않았습니다.
기존 설치 방식 확인,
DB 종류 확인,
백업,
MariaDB에서 MySQL 8로 이전,
content 경로 복원,
테마 심볼릭 링크 문제 해결,
SMTP 복구,
Tinybird 배포,
Caddy 프록시 수정까지 이어졌습니다.
이런 작업은 겉으로 보기에는 아무 변화가 없어 보입니다.
사용자는 그냥 블로그에 접속합니다.
글도 그대로 보입니다.
관리자 로그인도 그대로 됩니다.
하지만 안쪽은 완전히 바뀌었습니다.
CLI로 어딘가에서 돌던 Ghost가 아니라,
이제는 /home/web/goodtek/ghost-blog 아래에서 Podman Compose로 관리됩니다.
DB도 MariaDB가 아니라 MySQL 8입니다.
Analytics도 Ghost Admin 안에서 볼 수 있습니다.
오늘 한 일은 화려한 기능 개발은 아니었습니다.
하지만 goodtek을 계속 쌓아가려면 이런 작업이 필요합니다.
글을 쓰는 것도 중요하지만, 글이 읽히는지 알 수 있는 구조도 필요합니다.
문제가 생겼을 때 다시 띄울 수 있는 구조도 필요합니다.
다음 서버 작업을 할 때 덜 무서운 구조도 필요합니다.
오늘은 블로그를 조금 더 제품답게 만들었습니다.
겉으로는 똑같은 블로그지만,
안쪽은 꽤 많이 단단해졌습니다.
작은 작업 같지만, 이런 작업들이 쌓이면 나중에 훨씬 덜 흔들릴 거라고 믿습니다.
가장 큰 후회는 설치전에 먼저 찾아볼걸... 이었네요.