fujin-cli 0.5.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fujin-cli might be problematic. Click here for more details.
- fujin_cli-0.7.0/.github/workflows/publish.yml +169 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/.pre-commit-config.yaml +6 -0
- fujin_cli-0.7.0/CHANGELOG.md +18 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/PKG-INFO +28 -13
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/README.md +24 -10
- fujin_cli-0.7.0/docs/changelog.rst +2 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/app.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/config.rst +1 -1
- fujin_cli-0.7.0/docs/commands/deploy.rst +68 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/docs.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/down.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/index.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/init.rst +1 -1
- fujin_cli-0.7.0/docs/commands/printenv.rst +7 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/proxy.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/prune.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/redeploy.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/rollback.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/server.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/commands/up.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/conf.py +1 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/configuration.rst +1 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/index.rst +4 -6
- fujin_cli-0.7.0/docs/installation.rst +23 -0
- fujin_cli-0.7.0/docs/requirements.txt +138 -0
- fujin_cli-0.7.0/docs/secrets.rst +50 -0
- fujin_cli-0.7.0/docs/tutorial.rst +337 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/fujin.toml +3 -6
- fujin_cli-0.7.0/examples/golang/pocketbase/fujin.toml +23 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/justfile +26 -15
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/pyproject.toml +6 -4
- fujin_cli-0.7.0/src/fujin/__init__.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/__main__.py +6 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/deploy.py +22 -12
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/init.py +0 -2
- fujin_cli-0.7.0/src/fujin/commands/printenv.py +16 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/redeploy.py +5 -1
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/config.py +39 -6
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/proxies/nginx.py +17 -20
- fujin_cli-0.7.0/src/fujin/secrets/__init__.py +32 -0
- fujin_cli-0.7.0/src/fujin/secrets/bitwarden.py +62 -0
- fujin_cli-0.7.0/src/fujin/secrets/onepassword.py +26 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/uv.lock +191 -1
- fujin_cli-0.5.0/.github/workflows/publish.yml +0 -36
- fujin_cli-0.5.0/docs/changelog.rst +0 -2
- fujin_cli-0.5.0/docs/commands/deploy.rst +0 -7
- fujin_cli-0.5.0/docs/commands/secrets.rst +0 -7
- fujin_cli-0.5.0/docs/installation.rst +0 -16
- fujin_cli-0.5.0/docs/requirements.txt +0 -6
- fujin_cli-0.5.0/docs/tutorial.rst +0 -2
- fujin_cli-0.5.0/src/fujin/commands/secrets.py +0 -11
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/.gitignore +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/.readthedocs.yaml +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/LICENSE.txt +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/Vagrantfile +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/docs/hooks.rst +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/README.md +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/bookstore/__init__.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/bookstore/__main__.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/bookstore/asgi.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/bookstore/settings.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/bookstore/urls.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/bookstore/wsgi.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/manage.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/pyproject.toml +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/examples/django/bookstore/requirements.txt +0 -0
- /fujin_cli-0.5.0/src/fujin/__init__.py → /fujin_cli-0.7.0/examples/golang/pocketbase/.env.prod +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/__init__.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/_base.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/app.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/config.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/docs.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/down.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/proxy.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/prune.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/rollback.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/server.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/commands/up.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/connection.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/errors.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/hooks.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/process_managers/__init__.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/process_managers/systemd.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/proxies/__init__.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/proxies/caddy.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/proxies/dummy.py +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/templates/simple.service +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/templates/web.service +0 -0
- {fujin_cli-0.5.0 → fujin_cli-0.7.0}/src/fujin/templates/web.socket +0 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
name: Publish package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-python-wheel-and-sdist:
|
|
10
|
+
name: Build a pure Python wheel and source distribution
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout code
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v3
|
|
18
|
+
|
|
19
|
+
- name: Build
|
|
20
|
+
run: uv build
|
|
21
|
+
|
|
22
|
+
- uses: actions/upload-artifact@v4
|
|
23
|
+
with:
|
|
24
|
+
name: wheels
|
|
25
|
+
path: dist/*
|
|
26
|
+
if-no-files-found: error
|
|
27
|
+
overwrite: true
|
|
28
|
+
|
|
29
|
+
build-binaries:
|
|
30
|
+
name: Build binary application for ${{ matrix.job.target }} (${{ matrix.job.os }})
|
|
31
|
+
runs-on: ${{ matrix.job.os }}
|
|
32
|
+
needs: build-python-wheel-and-sdist
|
|
33
|
+
strategy:
|
|
34
|
+
fail-fast: false
|
|
35
|
+
matrix:
|
|
36
|
+
job:
|
|
37
|
+
# Linux
|
|
38
|
+
- target: x86_64-unknown-linux-gnu
|
|
39
|
+
os: ubuntu-latest
|
|
40
|
+
cross: true
|
|
41
|
+
release_suffix: x86_64-linux
|
|
42
|
+
- target: x86_64-unknown-linux-musl
|
|
43
|
+
os: ubuntu-latest
|
|
44
|
+
cross: true
|
|
45
|
+
release_suffix: x86_64-linux-musl
|
|
46
|
+
- target: aarch64-unknown-linux-gnu
|
|
47
|
+
os: ubuntu-latest
|
|
48
|
+
cross: true
|
|
49
|
+
release_suffix: aarch64-linux
|
|
50
|
+
# - target: i686-unknown-linux-gnu
|
|
51
|
+
# os: ubuntu-latest
|
|
52
|
+
# cross: true
|
|
53
|
+
# release_suffix: i686-linux
|
|
54
|
+
# Windows
|
|
55
|
+
- target: x86_64-pc-windows-msvc
|
|
56
|
+
os: windows-2022
|
|
57
|
+
release_suffix: x86_64-windows
|
|
58
|
+
- target: i686-pc-windows-msvc
|
|
59
|
+
os: windows-2022
|
|
60
|
+
release_suffix: i686-windows
|
|
61
|
+
# macOS
|
|
62
|
+
- target: aarch64-apple-darwin
|
|
63
|
+
os: macos-12
|
|
64
|
+
release_suffix: aarch64-osx
|
|
65
|
+
- target: x86_64-apple-darwin
|
|
66
|
+
os: macos-12
|
|
67
|
+
release_suffix: x86_64-osx
|
|
68
|
+
|
|
69
|
+
env:
|
|
70
|
+
CARGO_BUILD_TARGET: ${{ matrix.job.target }}
|
|
71
|
+
|
|
72
|
+
steps:
|
|
73
|
+
- name: Install uv
|
|
74
|
+
uses: astral-sh/setup-uv@v3
|
|
75
|
+
|
|
76
|
+
- name: Install just
|
|
77
|
+
uses: extractions/setup-just@v2
|
|
78
|
+
|
|
79
|
+
- name: Code Checkout
|
|
80
|
+
uses: actions/checkout@v4
|
|
81
|
+
|
|
82
|
+
- name: Install musl-tools on Linux
|
|
83
|
+
run: sudo apt-get install --yes musl musl-dev musl-tools
|
|
84
|
+
if: ${{ matrix.job.os == 'ubuntu-latest' }}
|
|
85
|
+
|
|
86
|
+
- name: Install Rust toolchain
|
|
87
|
+
if: ${{ !matrix.job.cross }}
|
|
88
|
+
uses: dtolnay/rust-toolchain@stable
|
|
89
|
+
with:
|
|
90
|
+
targets: ${{ matrix.job.target }}
|
|
91
|
+
|
|
92
|
+
- name: Set up cross compiling tools
|
|
93
|
+
if: matrix.job.cross
|
|
94
|
+
uses: taiki-e/setup-cross-toolchain-action@v1
|
|
95
|
+
with:
|
|
96
|
+
target: ${{ matrix.job.target}}
|
|
97
|
+
|
|
98
|
+
- name: Show toolchain information
|
|
99
|
+
run: |-
|
|
100
|
+
rustup toolchain list
|
|
101
|
+
rustup default
|
|
102
|
+
rustup -V
|
|
103
|
+
rustc -V
|
|
104
|
+
cargo -V
|
|
105
|
+
uv --version
|
|
106
|
+
|
|
107
|
+
- uses: actions/download-artifact@v4
|
|
108
|
+
with:
|
|
109
|
+
name: wheels
|
|
110
|
+
path: ${{ github.workspace }}/dist
|
|
111
|
+
merge-multiple: true
|
|
112
|
+
|
|
113
|
+
- name: Build binary
|
|
114
|
+
run: just build-bin
|
|
115
|
+
|
|
116
|
+
- name: Rename
|
|
117
|
+
working-directory: ${{ github.workspace }}
|
|
118
|
+
run: |-
|
|
119
|
+
mv dist/bin/fujin_cli* dist/bin/fujin_cli-${{ matrix.job.release_suffix }}
|
|
120
|
+
|
|
121
|
+
- name: Upload built binary package
|
|
122
|
+
uses: actions/upload-artifact@v4
|
|
123
|
+
with:
|
|
124
|
+
name: binaries-${{ matrix.job.release_suffix }}
|
|
125
|
+
path: dist/bin/*
|
|
126
|
+
if-no-files-found: error
|
|
127
|
+
|
|
128
|
+
publish-to-pypi:
|
|
129
|
+
name: Publish to PyPI
|
|
130
|
+
runs-on: ubuntu-latest
|
|
131
|
+
permissions:
|
|
132
|
+
id-token: write
|
|
133
|
+
needs: [build-python-wheel-and-sdist, build-binaries]
|
|
134
|
+
steps:
|
|
135
|
+
- name: Checkout code
|
|
136
|
+
uses: actions/checkout@v4
|
|
137
|
+
|
|
138
|
+
- uses: actions/download-artifact@v4
|
|
139
|
+
with:
|
|
140
|
+
name: wheels
|
|
141
|
+
path: dist
|
|
142
|
+
|
|
143
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
144
|
+
|
|
145
|
+
release:
|
|
146
|
+
name: Create a GitHub release
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
permissions:
|
|
149
|
+
contents: write
|
|
150
|
+
needs: [build-python-wheel-and-sdist, build-binaries]
|
|
151
|
+
steps:
|
|
152
|
+
- name: Checkout code
|
|
153
|
+
uses: actions/checkout@v4
|
|
154
|
+
|
|
155
|
+
- uses: actions/download-artifact@v4
|
|
156
|
+
with:
|
|
157
|
+
path: dist
|
|
158
|
+
merge-multiple: true
|
|
159
|
+
|
|
160
|
+
- name: Generate Changelog
|
|
161
|
+
run: |
|
|
162
|
+
awk '/^## /{if (p) exit; p=1; next} p' ${{ github.workspace }}/CHANGELOG.md | tee ${{ github.workspace }}-CHANGELOG.txt
|
|
163
|
+
|
|
164
|
+
- name: Release
|
|
165
|
+
uses: softprops/action-gh-release@v2
|
|
166
|
+
with:
|
|
167
|
+
body_path: ${{ github.workspace }}-CHANGELOG.txt
|
|
168
|
+
files: dist/*
|
|
169
|
+
fail_on_unmatched_files: true
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.7.0] - 2024-11-22
|
|
8
|
+
|
|
9
|
+
### 🚀 Features
|
|
10
|
+
|
|
11
|
+
- Inject secrets via bitwarden and 1password (#29)
|
|
12
|
+
- Add certbot_email configuration for nginx
|
|
13
|
+
|
|
14
|
+
### 🚜 Refactor
|
|
15
|
+
|
|
16
|
+
- Move requirements copy to transfer_files
|
|
17
|
+
|
|
18
|
+
<!-- generated by git-cliff -->
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: fujin-cli
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Get your project up and running in a few minutes on your own vps.
|
|
5
5
|
Project-URL: Documentation, https://github.com/falcopackages/fujin#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/falcopackages/fujin/issues
|
|
7
7
|
Project-URL: Source, https://github.com/falcopackages/fujin
|
|
8
8
|
Author-email: Tobi DEGNON <tobidegnon@proton.me>
|
|
9
|
-
License-File: LICENSE.txt
|
|
10
9
|
Keywords: caddy,deployment,django,fastapi,litestar,python,systemd
|
|
11
10
|
Classifier: Development Status :: 3 - Alpha
|
|
12
11
|
Classifier: Intended Audience :: Developers
|
|
@@ -22,34 +21,48 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
|
22
21
|
Requires-Python: >=3.10
|
|
23
22
|
Requires-Dist: cappa>=0.24
|
|
24
23
|
Requires-Dist: fabric>=3.2.2
|
|
24
|
+
Requires-Dist: gevent[recommended]>=24.11.1
|
|
25
25
|
Requires-Dist: msgspec[toml]>=0.18.6
|
|
26
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
26
27
|
Requires-Dist: rich>=13.9.2
|
|
27
28
|
Description-Content-Type: text/markdown
|
|
28
29
|
|
|
29
30
|
# fujin
|
|
30
31
|
|
|
32
|
+
> [!IMPORTANT]
|
|
33
|
+
> This tool is currently contains minimal features and is a work-in-progress
|
|
34
|
+
|
|
35
|
+
<!-- content:start -->
|
|
36
|
+
|
|
37
|
+
`fujin` is a simple deployment tool that helps you get your project up and running on a VPS in minutes. It manages your app processes using [systemd](https://systemd.io) and runs your apps behind [caddy](https://caddyserver.com).
|
|
38
|
+
|
|
39
|
+
[](https://github.com/falcopackages/fujin/actions/workflows/publish.yml)
|
|
31
40
|
[](https://pypi.org/project/fujin-cli)
|
|
32
41
|
[](https://pypi.org/project/fujin-cli)
|
|
33
42
|
[](https://github.com/falcopackages/fujin/blob/main/LICENSE.txt)
|
|
34
43
|
[](https://pypi.org/project/fujin-cli)
|
|
35
|
-
-----
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
> This package currently contains minimal features and is a work-in-progress
|
|
45
|
+
## Features
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
- 🚀 One-command server bootstrap
|
|
48
|
+
- 🔄 Rollback broken deployments
|
|
49
|
+
- 🔐 Zero configuration SSL certificates
|
|
50
|
+
- 🔁 Swappable proxy ([caddy](https://caddyserver.com), [nginx](https://nginx.org/en/) and `dummy` to disable proxy)
|
|
51
|
+
- 🛠️ Secrets injection from password managers ([Bitwarden](https://bitwarden.com/), [1Password](https://1password.com), etc.)
|
|
52
|
+
- 📝 Easily customizable `systemd` and `proxy` configurations
|
|
53
|
+
- 👨💻 Remote application management and log streaming
|
|
54
|
+
- 🐍 Supports packaged python apps and self-contained binaries
|
|
43
55
|
|
|
44
|
-
|
|
56
|
+
For more details, check out the [documentation📚](https://fujin.oluwatobi.dev/en/latest/).
|
|
45
57
|
|
|
46
58
|
## Why?
|
|
47
59
|
|
|
48
60
|
I wanted [kamal](https://kamal-deploy.org/) but without Docker, and I thought the idea was fun. At its core, this project automates versions of this [tutorial](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu). If you've been a Django beginner
|
|
49
|
-
trying to get your app in production, you probably went through this.
|
|
61
|
+
trying to get your app in production, you probably went through this.
|
|
62
|
+
|
|
63
|
+
I'm using `caddy` here by default instead of `nginx` because it's configurable via an API and it's is a no-brainer for SSL certificates. `Systemd` is the default on most Linux distributions and does a good enough job.
|
|
50
64
|
|
|
51
|
-
Fujin was initially planned to be a Python-only project, but the core concepts can be applied to any language that can produce a single distributable file (e.g., Go, Rust).
|
|
52
|
-
I'm currently rocking SQLite in production for my side projects and ths setup is enough for my use case.
|
|
65
|
+
Fujin was initially planned to be a Python-only project, but the core concepts can be applied to any language that can produce a single distributable file (e.g., Go, Rust).
|
|
53
66
|
|
|
54
67
|
The goal is to automate deployment while leaving you in full control of your Linux box. It's not a CLI PaaS - it's simple and expects you to be able to SSH into your server and troubleshoot if necessary. For beginners, it makes the initial deployment easier while you get your hands dirty with Linux.
|
|
55
68
|
If you need a never-break, worry-free, set-it-and-forget-it setup that auto-scales and does all the magic, fujin probably isn't for you.
|
|
@@ -64,3 +77,5 @@ Fujin draws inspiration from the following tools for their developer experience.
|
|
|
64
77
|
## License
|
|
65
78
|
|
|
66
79
|
`fujin` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
|
|
80
|
+
|
|
81
|
+
<!-- content:end -->
|
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
# fujin
|
|
2
2
|
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> This tool is currently contains minimal features and is a work-in-progress
|
|
5
|
+
|
|
6
|
+
<!-- content:start -->
|
|
7
|
+
|
|
8
|
+
`fujin` is a simple deployment tool that helps you get your project up and running on a VPS in minutes. It manages your app processes using [systemd](https://systemd.io) and runs your apps behind [caddy](https://caddyserver.com).
|
|
9
|
+
|
|
10
|
+
[](https://github.com/falcopackages/fujin/actions/workflows/publish.yml)
|
|
3
11
|
[](https://pypi.org/project/fujin-cli)
|
|
4
12
|
[](https://pypi.org/project/fujin-cli)
|
|
5
13
|
[](https://github.com/falcopackages/fujin/blob/main/LICENSE.txt)
|
|
6
14
|
[](https://pypi.org/project/fujin-cli)
|
|
7
|
-
-----
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
> This package currently contains minimal features and is a work-in-progress
|
|
16
|
+
## Features
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
- 🚀 One-command server bootstrap
|
|
19
|
+
- 🔄 Rollback broken deployments
|
|
20
|
+
- 🔐 Zero configuration SSL certificates
|
|
21
|
+
- 🔁 Swappable proxy ([caddy](https://caddyserver.com), [nginx](https://nginx.org/en/) and `dummy` to disable proxy)
|
|
22
|
+
- 🛠️ Secrets injection from password managers ([Bitwarden](https://bitwarden.com/), [1Password](https://1password.com), etc.)
|
|
23
|
+
- 📝 Easily customizable `systemd` and `proxy` configurations
|
|
24
|
+
- 👨💻 Remote application management and log streaming
|
|
25
|
+
- 🐍 Supports packaged python apps and self-contained binaries
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
For more details, check out the [documentation📚](https://fujin.oluwatobi.dev/en/latest/).
|
|
17
28
|
|
|
18
29
|
## Why?
|
|
19
30
|
|
|
20
31
|
I wanted [kamal](https://kamal-deploy.org/) but without Docker, and I thought the idea was fun. At its core, this project automates versions of this [tutorial](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu). If you've been a Django beginner
|
|
21
|
-
trying to get your app in production, you probably went through this.
|
|
32
|
+
trying to get your app in production, you probably went through this.
|
|
33
|
+
|
|
34
|
+
I'm using `caddy` here by default instead of `nginx` because it's configurable via an API and it's is a no-brainer for SSL certificates. `Systemd` is the default on most Linux distributions and does a good enough job.
|
|
22
35
|
|
|
23
|
-
Fujin was initially planned to be a Python-only project, but the core concepts can be applied to any language that can produce a single distributable file (e.g., Go, Rust).
|
|
24
|
-
I'm currently rocking SQLite in production for my side projects and ths setup is enough for my use case.
|
|
36
|
+
Fujin was initially planned to be a Python-only project, but the core concepts can be applied to any language that can produce a single distributable file (e.g., Go, Rust).
|
|
25
37
|
|
|
26
38
|
The goal is to automate deployment while leaving you in full control of your Linux box. It's not a CLI PaaS - it's simple and expects you to be able to SSH into your server and troubleshoot if necessary. For beginners, it makes the initial deployment easier while you get your hands dirty with Linux.
|
|
27
39
|
If you need a never-break, worry-free, set-it-and-forget-it setup that auto-scales and does all the magic, fujin probably isn't for you.
|
|
@@ -36,3 +48,5 @@ Fujin draws inspiration from the following tools for their developer experience.
|
|
|
36
48
|
## License
|
|
37
49
|
|
|
38
50
|
`fujin` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
|
|
51
|
+
|
|
52
|
+
<!-- content:end -->
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
deploy
|
|
2
|
+
======
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
.. cappa:: fujin.commands.deploy.Deploy
|
|
6
|
+
:style: terminal
|
|
7
|
+
:terminal-width: 0
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
How it works
|
|
11
|
+
------------
|
|
12
|
+
|
|
13
|
+
Here's a high-level overview of what happens when you run the ``deploy`` command:
|
|
14
|
+
|
|
15
|
+
1. **Resolve secrets**: If you have defined a ``secrets`` configuration, it will be used to retrieve pull the ``secrets`` defined in your ``envfile``.
|
|
16
|
+
|
|
17
|
+
2. **Build the Application**: Your application is built using the ``build_command`` specified in your configuration.
|
|
18
|
+
|
|
19
|
+
3. **Transfer Files**: The environment variables file (``.env``) and the distribution file are transferred to the remote server. Optionally transfers ``requirements`` file (if specified).
|
|
20
|
+
|
|
21
|
+
4. **Install the Project**: Depending on the installation mode (Python package or binary), the project is installed on the remote server. For a Python package, a virtual environment is set up, dependencies are installed, and the distribution file (the wheel file) is then installed. For a binary, the binary file for the latest version is linked to the root of the application directory.
|
|
22
|
+
|
|
23
|
+
5. **Application Release**: If a ``release_command`` is specified in the configuration, it is executed at this stage.
|
|
24
|
+
|
|
25
|
+
6. **Configure and Start Services**: Configuration files for both ``systemd`` and the ``proxy`` (e.g., Caddy, by default) are generated or copied if previously exported. These configuration files are moved to their appropriate directories. A configuration reload is performed, and all relevant services are restarted.
|
|
26
|
+
|
|
27
|
+
7. **Update Version History**: The deployed version is recorded in the ``.versions`` file on the remote server.
|
|
28
|
+
|
|
29
|
+
8. **Prune Old Assets**: Old versions of the application are removed based on the ``versions_to_keep`` configuration.
|
|
30
|
+
|
|
31
|
+
9. **Completion**: A success message is displayed, and the URL to access the deployed project is provided.
|
|
32
|
+
|
|
33
|
+
Below is an example of the layout and structure of a deployed application:
|
|
34
|
+
|
|
35
|
+
.. tab-set::
|
|
36
|
+
|
|
37
|
+
.. tab-item:: python package
|
|
38
|
+
|
|
39
|
+
.. code-block:: shell
|
|
40
|
+
|
|
41
|
+
app_directory/
|
|
42
|
+
├── .env # Environment variables file
|
|
43
|
+
├── .appenv # Application-specific environment setup
|
|
44
|
+
├── .versions # Version tracking file
|
|
45
|
+
├── .venv/ # Virtual environment
|
|
46
|
+
├── v1.2.3/ # Versioned asset directory
|
|
47
|
+
│ ├── app-1.2.3-py3-none-any.whl # Distribution file
|
|
48
|
+
│ └── requirements.txt # Optional requirements file
|
|
49
|
+
├── v1.2.2/
|
|
50
|
+
│ └── ...
|
|
51
|
+
└── v1.2.1/
|
|
52
|
+
└── ...
|
|
53
|
+
|
|
54
|
+
.. tab-item:: binary
|
|
55
|
+
|
|
56
|
+
.. code-block:: shell
|
|
57
|
+
|
|
58
|
+
app_directory/
|
|
59
|
+
├── .env # Environment variables file
|
|
60
|
+
├── .appenv # Application-specific environment setup
|
|
61
|
+
├── .versions # Version tracking file
|
|
62
|
+
├── app_binary -> v1.2.3/app_binary # Symbolic link to current version
|
|
63
|
+
├── v1.2.3/ # Versioned asset directory
|
|
64
|
+
│ └── app_binary # Distribution file
|
|
65
|
+
├── v1.2.2/
|
|
66
|
+
│ └── ...
|
|
67
|
+
└── v1.2.1/
|
|
68
|
+
└── ...
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
.. fujin documentation master file, created by
|
|
2
|
-
sphinx-quickstart on Tue Oct 29 14:01:13 2024.
|
|
3
|
-
You can adapt this file completely to your liking, but it should at least
|
|
4
|
-
contain the root `toctree` directive.
|
|
5
|
-
|
|
6
1
|
fujin documentation
|
|
7
2
|
===================
|
|
8
3
|
|
|
@@ -15,8 +10,10 @@ fujin documentation
|
|
|
15
10
|
|
|
16
11
|
<script src="https://asciinema.org/a/687274.js" id="asciicast-687274" async="true"></script>
|
|
17
12
|
|
|
18
|
-
..
|
|
13
|
+
.. include:: ../README.md
|
|
19
14
|
:parser: myst_parser.sphinx_
|
|
15
|
+
:start-after: <!-- content:start -->
|
|
16
|
+
:end-before: <!-- content:end -->
|
|
20
17
|
|
|
21
18
|
.. toctree::
|
|
22
19
|
:maxdepth: 2
|
|
@@ -27,6 +24,7 @@ fujin documentation
|
|
|
27
24
|
tutorial
|
|
28
25
|
configuration
|
|
29
26
|
commands/index
|
|
27
|
+
secrets
|
|
30
28
|
hooks
|
|
31
29
|
changelog
|
|
32
30
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Installation
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
If you have `uv <https://docs.astral.sh/uv/getting-started/installation/>`_ installed, run:
|
|
5
|
+
|
|
6
|
+
.. code-block:: shell
|
|
7
|
+
|
|
8
|
+
uv tool install fujin-cli
|
|
9
|
+
|
|
10
|
+
If not, download a binary version from the GitHub `releases page <https://github.com/falcopackages/fujin/releases>`_ and move the downloaded file
|
|
11
|
+
to a directory in your PATH.
|
|
12
|
+
|
|
13
|
+
Here is an example of how to install the binary on x86 macOS:
|
|
14
|
+
|
|
15
|
+
.. code-block:: shell
|
|
16
|
+
|
|
17
|
+
curl -LsSfO https://github.com/falcopackages/fujin/releases/download/v0.6.0/fujin_cli-x86_64-osx
|
|
18
|
+
chmod +x fujin_cli-x86_64-osx
|
|
19
|
+
mv fujin_cli-x86_64-osx /usr/local/bin/fujin
|
|
20
|
+
|
|
21
|
+
.. note::
|
|
22
|
+
|
|
23
|
+
If you install ``fujin`` via the GitHub release, you can keep it up to date with ``fujin self update``.
|