Adventure in Synology, Docker and Gitea land

I’m not a system administrator. I’m not even a “devops” person. Yet I’ve a small personal network with a Synology NAS. When I bough it, I’ve activated Docker and put Gitea running under it which I tend to use now instead of private repository under GitLab, GitHub or Bickbucket. Not driven by any reasons, I wanted to upgrade Gitea from the 1.13 version it was running to 1.16.

I had some issues… and my main goal here is to document them.

I downloaded gitea/gitea:1.16.2 using the Synology interface.

I stopped the container, back up the data, tested that I could use the backuped data (and it was a very good idea), launched a new container using the 1.16.2 image and using the old data volume. That didn’t work well. From the logs, I understood that the migration of the sqlite3 database failed.

Good, perhaps I needed to migrate it incrementally first to 1.14, then to 1.15 and finally to 1.16. Restore the backup, dowload the 1.14 and 1.15 containers from docker.

Launched a new container using the 1.14 image and the restored backup. That didn’t work. This time, not because of the migration, but gitea could not start on the 80 port (I’m using the macvlan interface so gitea has its own IP address and its webpage don’t need a port to be reached).

Let’s try to launch a new 1.13 container. It doesn’t work for the same reason as the 1.14 one. But the old 1.13 container does work. What’s the difference? To make a long story short, I had given the CAP_NET_BIND_SERVICE capacity to gitea when I first set it up, and I had forgotten about it.

For the next time I’ll try to update (hopefully I’ll remember about this text), here is how I gave the capability to gitea for the upgrade.

  1. Launch the container with dummy data:

     nas$ sudo docker run --detach --ip 192.168.1.192 --name gitea-1.14 --net macvlan --volume=/volume1/docker/dummy-gitea:/data gitea/gitea:1.14
  2. Exec into the container and set the capability

     nas$ sudo docker container exec -ti gitea-1.14 /bin/bash
     container# cd /app/gitea/
     container# setcap CAP_NET_BIND_SERVICE=+eip gitea
  3. Stop the container using the Synology interface.

  4. Use the Synology interface to switch the volume to the true gitea data.

  5. Restart the container.

The migration was correct and I could access the interface.

Repeat from 1.14 to 1.15. And I got the data migration issue. I found a relevant GitHub issue. To solve it, I applied the second method: delete the message column from the task table. Synology has the sqlite3 program available, so that was relatively easy:

nas$ cd /volume1/docker/gitea/gitea
nas$ sudo sqlite3 gitea.db
sqlite> .schema task
CREATE TABLE `task` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `doer_id` INTEGER NULL, `owner_id` INTEGER NULL, `repo_id` INTEGER NULL, `type` INTEGER NULL, `status` INTEGER NULL, `start_time` INTEGER NULL, `end_time` INTEGER NULL, `payload_content` TEXT NULL, "message" TEXT NULL, `created` INTEGER NULL, `errors` TEXT NULL);
CREATE INDEX `IDX_task_status` ON `task` (`status`);
CREATE INDEX `IDX_task_repo_id` ON `task` (`repo_id`);
CREATE INDEX `IDX_task_doer_id` ON `task` (`doer_id`);
CREATE INDEX `IDX_task_owner_id` ON `task` (`owner_id`);
sqlite> CREATE TABLE new_task (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `doer_id` INTEGER NULL, `owner_id` INTEGER NULL, `repo_id` INTEGER NULL, `type` INTEGER NULL, `status` INTEGER NULL, `start_time` INTEGER NULL, `end_time` INTEGER NULL, `payload_content` TEXT NULL, `created` INTEGER NULL, `errors` TEXT NULL);
sqlite> INSERT INTO new_task SELECT id, doer_id, owner_id, repo_id, type, status, start_time, end_time, payload_content, created, errors FROM task;
sqlite> drop table task;
sqlite> alter table new_task rename to task;

Restarting the container, the migration finished correctly and I could run the 1.15 version. The migration to 1.16.2 took place without issue.