diff --git a/.gitignore b/.gitignore
index 77507d792ed0798013072dc46c8034d963a5487d..c155004c6b33531a8759d4de8f379b50b009a5f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 miniflux-*
-miniflux
\ No newline at end of file
+miniflux
+*.rpm
\ No newline at end of file
diff --git a/Makefile b/Makefile
index b78930b4fb7096c06fb72495c6747d62a4f724d4..bac90089d7b2e23c96dba484b1562061f802b513 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ export PGPASSWORD := postgres
 	clean-integration-test \
 	docker-image \
 	docker-images \
-	docker-manifest
+	rpm
 
 generate:
 	@ go generate
@@ -95,7 +95,7 @@ run: generate
 	@ LOG_DATE_TIME=1 go run main.go -debug
 
 clean:
-	@ rm -f $(APP)-* $(APP)
+	@ rm -f $(APP)-* $(APP) $(APP)*.rpm
 
 test:
 	go test -cover -race -count=1 ./...
@@ -128,3 +128,12 @@ docker-images:
 		--file packaging/docker/Dockerfile \
 		--tag $(DOCKER_IMAGE):$(VERSION) \
 		--push .
+
+rpm: clean
+	@ docker build \
+		-t miniflux-rpm-builder \
+		-f packaging/rpm/Dockerfile \
+		.
+	@ docker run --rm \
+		-v ${PWD}:/root/rpmbuild/RPMS/x86_64/ miniflux-rpm-builder \
+		rpmbuild -bb --define "_miniflux_version $(VERSION)" /root/rpmbuild/SPECS/miniflux.spec
diff --git a/packaging/miniflux.conf b/packaging/miniflux.conf
new file mode 100644
index 0000000000000000000000000000000000000000..ec6028a53c181edf2e4c86614d71f79734934966
--- /dev/null
+++ b/packaging/miniflux.conf
@@ -0,0 +1,3 @@
+# See https://miniflux.app/docs/configuration.html
+
+RUN_MIGRATIONS=1
diff --git a/packaging/rpm/Dockerfile b/packaging/rpm/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d0344bd9d59952f37146be1323075569271282f7
--- /dev/null
+++ b/packaging/rpm/Dockerfile
@@ -0,0 +1,20 @@
+FROM golang:1 AS build
+ADD . /go/src/app
+WORKDIR /go/src/app
+RUN go generate
+RUN go build \
+    -o miniflux \
+    -ldflags="-s -w -X 'miniflux.app/version.Version=`git describe --abbrev=0`' -X 'miniflux.app/version.Commit=`git rev-parse --short HEAD`' -X 'miniflux.app/version.BuildDate=`date +%FT%T%z`'" \
+    main.go
+
+FROM centos:latest
+RUN dnf install -y rpm-build
+RUN mkdir -p /root/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
+RUN echo "%_topdir /root/rpmbuild" >> .rpmmacros
+COPY --from=build /go/src/app/miniflux /root/rpmbuild/SOURCES/miniflux
+COPY --from=build /go/src/app/LICENSE /root/rpmbuild/SOURCES/
+COPY --from=build /go/src/app/ChangeLog /root/rpmbuild/SOURCES/
+COPY --from=build /go/src/app/miniflux.1 /root/rpmbuild/SOURCES/
+COPY --from=build /go/src/app/packaging/systemd/miniflux.service /root/rpmbuild/SOURCES/
+COPY --from=build /go/src/app/packaging/miniflux.conf /root/rpmbuild/SOURCES/
+COPY --from=build /go/src/app/packaging/rpm/miniflux.spec /root/rpmbuild/SPECS/miniflux.spec
diff --git a/packaging/rpm/miniflux.spec b/packaging/rpm/miniflux.spec
new file mode 100644
index 0000000000000000000000000000000000000000..3967d1aa30adebd87c58a146c6f742ee1c3457ed
--- /dev/null
+++ b/packaging/rpm/miniflux.spec
@@ -0,0 +1,61 @@
+%undefine _disable_source_fetch
+
+Name:    miniflux
+Version: %{_miniflux_version}
+Release: 1.0
+Summary: Minimalist and opinionated feed reader
+URL: https://miniflux.app/
+License: ASL 2.0
+Source0: miniflux
+Source1: miniflux.service
+Source2: miniflux.conf
+Source3: miniflux.1
+Source4: LICENSE
+Source5: ChangeLog
+BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
+BuildArch: x86_64
+Requires(pre): shadow-utils
+
+%{?systemd_requires}
+BuildRequires: systemd
+
+%description
+%{summary}
+
+%install
+mkdir -p %{buildroot}%{_bindir}
+install -p -m 755 %{SOURCE0} %{buildroot}%{_bindir}/miniflux
+install -D -m 644 %{SOURCE1} %{buildroot}%{_unitdir}/miniflux.service
+install -D -m 600 %{SOURCE2} %{buildroot}%{_sysconfdir}/miniflux.conf
+install -D -m 644 %{SOURCE3} %{buildroot}%{_mandir}/man1/miniflux.1
+install -D -m 644 %{SOURCE4} %{buildroot}%{_docdir}/miniflux/LICENSE
+install -D -m 644 %{SOURCE5} %{buildroot}%{_docdir}/miniflux/ChangeLog
+
+%files
+%defattr(755,root,root)
+%{_bindir}/miniflux
+%{_docdir}/miniflux
+%defattr(644,root,root)
+%{_unitdir}/miniflux.service
+%{_mandir}/man1/miniflux.1*
+%{_docdir}/miniflux/*
+%defattr(600,root,root)
+%config(noreplace) %{_sysconfdir}/miniflux.conf
+
+%pre
+getent group miniflux >/dev/null || groupadd -r miniflux
+getent passwd miniflux >/dev/null || \
+    useradd -r -g miniflux -d /dev/null -s /sbin/nologin \
+    -c "Miniflux Daemon" miniflux
+exit 0
+
+%post
+%systemd_post miniflux.service
+
+%preun
+%systemd_preun miniflux.service
+
+%postun
+%systemd_postun_with_restart miniflux.service
+
+%changelog
diff --git a/packaging/systemd/miniflux.service b/packaging/systemd/miniflux.service
new file mode 100644
index 0000000000000000000000000000000000000000..0edc41e0796ebfea95af6b279ad038a164448d40
--- /dev/null
+++ b/packaging/systemd/miniflux.service
@@ -0,0 +1,23 @@
+[Unit]
+Description=Miniflux Feed Reader
+After=network.target postgresql.service
+
+[Service]
+Type=simple
+EnvironmentFile=/etc/miniflux.conf
+User=miniflux
+ExecStart=/usr/bin/miniflux
+Restart=always
+
+# Hardening options:
+NoNewPrivileges=true
+PrivateDevices=true
+ProtectControlGroups=true
+ProtectHome=true
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectSystem=strict
+RestrictRealtime=true
+
+[Install]
+WantedBy=multi-user.target