fujin-cli 0.11.5__tar.gz → 0.12.1__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.11.5 → fujin_cli-0.12.1}/CHANGELOG.md +9 -16
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/PKG-INFO +1 -1
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/index.rst +1 -0
- fujin_cli-0.12.1/docs/integrations.rst +149 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/pyproject.toml +5 -5
- fujin_cli-0.12.1/src/fujin/__init__.py +1 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/__main__.py +3 -2
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/_base.py +2 -1
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/deploy.py +1 -1
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/config.py +3 -1
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/connection.py +2 -2
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/hooks.py +3 -2
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/systemd.py +1 -1
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/templates/simple.service +0 -1
- {fujin_cli-0.11.5/src/fujin/templates/gunicorn → fujin_cli-0.12.1/src/fujin/templates}/web.service +4 -4
- {fujin_cli-0.11.5/src/fujin/templates/gunicorn → fujin_cli-0.12.1/src/fujin/templates}/web.socket +1 -1
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/uv.lock +1 -1
- fujin_cli-0.11.5/src/fujin/__init__.py +0 -0
- fujin_cli-0.11.5/src/fujin/templates/granian/web.service +0 -22
- fujin_cli-0.11.5/src/fujin/templates/web.service +0 -22
- fujin_cli-0.11.5/src/fujin/templates/web.socket +0 -11
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/.github/workflows/publish.yml +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/.gitignore +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/.pre-commit-config.yaml +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/.readthedocs.yaml +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/LICENSE.txt +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/README.md +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/Vagrantfile +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/changelog.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/app.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/config.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/deploy.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/docs.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/down.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/index.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/init.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/printenv.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/proxy.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/prune.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/redeploy.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/rollback.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/server.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/commands/up.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/conf.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/configuration.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/hooks.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/installation.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/requirements.txt +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/secrets.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/docs/tutorial.rst +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/README.md +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/bookstore/__init__.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/bookstore/__main__.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/bookstore/asgi.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/bookstore/settings.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/bookstore/urls.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/bookstore/wsgi.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/fujin.toml +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/manage.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/pyproject.toml +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/django/bookstore/requirements.txt +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/golang/pocketbase/.env.prod +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/examples/golang/pocketbase/fujin.toml +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/justfile +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/__init__.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/app.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/config.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/docs.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/down.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/init.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/printenv.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/proxy.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/prune.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/redeploy.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/rollback.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/server.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/commands/up.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/errors.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/proxies/__init__.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/proxies/caddy.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/proxies/dummy.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/proxies/nginx.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/secrets/__init__.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/secrets/bitwarden.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/secrets/dopppler.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/secrets/onepassword.py +0 -0
- {fujin_cli-0.11.5 → fujin_cli-0.12.1}/src/fujin/secrets/system.py +0 -0
|
@@ -4,43 +4,36 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [0.
|
|
7
|
+
## [0.12.1] - 2025-03-12
|
|
8
8
|
|
|
9
9
|
### 🐛 Bug Fixes
|
|
10
10
|
|
|
11
|
-
-
|
|
11
|
+
- Force .venv removal on deploy
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
### Cfeat
|
|
13
|
+
### 📚 Documentation
|
|
16
14
|
|
|
17
|
-
-
|
|
15
|
+
- Document integration with ci ci platforms
|
|
18
16
|
|
|
19
|
-
## [0.
|
|
17
|
+
## [0.12.0] - 2025-03-08
|
|
20
18
|
|
|
21
19
|
### 🚀 Features
|
|
22
20
|
|
|
21
|
+
- Add process name to systemd service
|
|
22
|
+
- Add fujin version info
|
|
23
23
|
- Set system as the default secrets adapter
|
|
24
|
-
|
|
25
|
-
## [0.11.1] - 2025-03-08
|
|
24
|
+
- Add system secret reader
|
|
26
25
|
|
|
27
26
|
### 🐛 Bug Fixes
|
|
28
27
|
|
|
29
28
|
- Env content parse logic
|
|
30
29
|
|
|
31
|
-
## [0.11.0] - 2025-03-08
|
|
32
|
-
|
|
33
|
-
### 🚀 Features
|
|
34
|
-
|
|
35
|
-
- Add system secret reader
|
|
36
|
-
|
|
37
30
|
### 🚜 Refactor
|
|
38
31
|
|
|
39
32
|
- Rename env_content to env
|
|
40
33
|
|
|
41
34
|
### 📚 Documentation
|
|
42
35
|
|
|
43
|
-
- Apply a more
|
|
36
|
+
- Apply a more consistent writing style
|
|
44
37
|
|
|
45
38
|
### ⚙️ Miscellaneous Tasks
|
|
46
39
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fujin-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.1
|
|
4
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
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Integrations
|
|
2
|
+
------------
|
|
3
|
+
|
|
4
|
+
This guide explains how to integrate Fujin with CI/CD platforms for automated deployments.
|
|
5
|
+
|
|
6
|
+
CI/CD Integration Setup
|
|
7
|
+
=======================
|
|
8
|
+
|
|
9
|
+
To integrate Fujin with CI/CD platforms like GitLab CI or GitHub Actions, follow these steps:
|
|
10
|
+
|
|
11
|
+
1. SSH Key Setup
|
|
12
|
+
****************
|
|
13
|
+
|
|
14
|
+
You have two options for SSH authentication:
|
|
15
|
+
|
|
16
|
+
**Option 1: Use your existing SSH key (Recommended)**
|
|
17
|
+
- If you're already using Fujin with this host on your laptop, you already have a working SSH key
|
|
18
|
+
- Copy your private key to use in your CI/CD environment
|
|
19
|
+
|
|
20
|
+
**Option 2: Generate a new deployment key**
|
|
21
|
+
- Generate a new SSH key pair specifically for CI/CD:
|
|
22
|
+
|
|
23
|
+
.. code-block:: bash
|
|
24
|
+
|
|
25
|
+
ssh-keygen -t ed25519 -C "deployment@example.com" -f deployment_key
|
|
26
|
+
|
|
27
|
+
- Add the public key to your server's authorized keys:
|
|
28
|
+
|
|
29
|
+
.. code-block:: bash
|
|
30
|
+
|
|
31
|
+
ssh-copy-id -i deployment_key.pub user@your-server.com
|
|
32
|
+
|
|
33
|
+
2. Configure CI/CD Environment Variables
|
|
34
|
+
****************************************
|
|
35
|
+
|
|
36
|
+
Add your private SSH key as a CI/CD environment variable:
|
|
37
|
+
|
|
38
|
+
- In GitLab: Go to Settings → CI/CD → Variables
|
|
39
|
+
- In GitHub: Go to Settings → Secrets and variables → Actions
|
|
40
|
+
|
|
41
|
+
Create a variable named ``SSH_PRIVATE_KEY`` with the contents of your private key.
|
|
42
|
+
|
|
43
|
+
3. Configure Host Environment Variables
|
|
44
|
+
***************************************
|
|
45
|
+
|
|
46
|
+
Instead of using an environment file, use the ``env`` property in your host configuration:
|
|
47
|
+
|
|
48
|
+
.. code-block:: toml
|
|
49
|
+
:caption: fujin.toml
|
|
50
|
+
|
|
51
|
+
[host]
|
|
52
|
+
domain_name = "example.com"
|
|
53
|
+
user = "deploy"
|
|
54
|
+
# Use this instead of envfile for CI/CD environments
|
|
55
|
+
env = """
|
|
56
|
+
DEBUG=False
|
|
57
|
+
SECRET_KEY=$SECRET_KEY
|
|
58
|
+
DATABASE_URL=$DATABASE_URL
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
For sensitive values, use the secrets feature to fetch from environment variables:
|
|
62
|
+
|
|
63
|
+
.. code-block:: toml
|
|
64
|
+
:caption: fujin.toml
|
|
65
|
+
|
|
66
|
+
[secrets]
|
|
67
|
+
adapter = "system" # Use system environment variables
|
|
68
|
+
|
|
69
|
+
The secret values will be substituted from the CI/CD environment variables. See the `secrets documentation </secrets.html>`_ for other secret manager options like Bitwarden, 1Password, or Doppler.
|
|
70
|
+
|
|
71
|
+
Gitlab CI / CD
|
|
72
|
+
==============
|
|
73
|
+
|
|
74
|
+
Here's a complete example for GitLab CI/CD:
|
|
75
|
+
|
|
76
|
+
.. code-block:: yaml
|
|
77
|
+
:caption: gitlab-ci.yml
|
|
78
|
+
|
|
79
|
+
stages:
|
|
80
|
+
- deploy
|
|
81
|
+
|
|
82
|
+
deploy:
|
|
83
|
+
stage: deploy
|
|
84
|
+
image: alpine:latest
|
|
85
|
+
before_script:
|
|
86
|
+
- mkdir -p ~/.ssh
|
|
87
|
+
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
|
|
88
|
+
- chmod 600 ~/.ssh/id_rsa
|
|
89
|
+
- ssh-keyscan -H example.com >> ~/.ssh/known_hosts
|
|
90
|
+
script:
|
|
91
|
+
- curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
92
|
+
- $HOME/.local/bin/uv tool install --upgrade fujin-cli
|
|
93
|
+
- $HOME/.local/bin/fujin --version
|
|
94
|
+
- $HOME/.local/bin/fujin deploy
|
|
95
|
+
tags:
|
|
96
|
+
- production
|
|
97
|
+
only:
|
|
98
|
+
- main
|
|
99
|
+
|
|
100
|
+
Make sure to:
|
|
101
|
+
1. Set ``SSH_PRIVATE_KEY`` in your GitLab CI/CD variables
|
|
102
|
+
2. Set any secret environment variables needed by your application
|
|
103
|
+
3. Replace ``example.com`` with your actual server domain in the ssh-keyscan command
|
|
104
|
+
|
|
105
|
+
Github Actions
|
|
106
|
+
==============
|
|
107
|
+
|
|
108
|
+
Here's a complete example for GitHub Actions:
|
|
109
|
+
|
|
110
|
+
.. code-block:: yaml
|
|
111
|
+
:caption: .github/workflows/deploy.yml
|
|
112
|
+
|
|
113
|
+
name: Deploy Application
|
|
114
|
+
|
|
115
|
+
on:
|
|
116
|
+
push:
|
|
117
|
+
branches: [ main ]
|
|
118
|
+
|
|
119
|
+
jobs:
|
|
120
|
+
deploy:
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
|
|
123
|
+
steps:
|
|
124
|
+
- uses: actions/checkout@v3
|
|
125
|
+
|
|
126
|
+
- name: Set up SSH
|
|
127
|
+
run: |
|
|
128
|
+
mkdir -p ~/.ssh
|
|
129
|
+
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
|
130
|
+
chmod 600 ~/.ssh/id_rsa
|
|
131
|
+
ssh-keyscan -H example.com >> ~/.ssh/known_hosts
|
|
132
|
+
|
|
133
|
+
- name: Install uv
|
|
134
|
+
uses: astral-sh/setup-uv@v5
|
|
135
|
+
|
|
136
|
+
- name: Install Fujin
|
|
137
|
+
run: uv tool install --upgrade fujin-cli
|
|
138
|
+
|
|
139
|
+
- name: Deploy with Fujin
|
|
140
|
+
run: fujin deploy
|
|
141
|
+
env:
|
|
142
|
+
# Add your application's secret environment variables here
|
|
143
|
+
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
|
144
|
+
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
|
|
145
|
+
|
|
146
|
+
Make sure to:
|
|
147
|
+
1. Create the ``SSH_PRIVATE_KEY`` secret in your GitHub repository
|
|
148
|
+
2. Create any application secret variables in your GitHub repository
|
|
149
|
+
3. Replace ``example.com`` with your actual server domain in the ssh-keyscan command
|
|
@@ -7,7 +7,7 @@ requires = [
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "fujin-cli"
|
|
10
|
-
version = "0.
|
|
10
|
+
version = "0.12.1"
|
|
11
11
|
description = "Get your project up and running in a few minutes on your own vps."
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
keywords = [
|
|
@@ -152,7 +152,7 @@ lint.isort.required-imports = [
|
|
|
152
152
|
lint.pyupgrade.keep-runtime-typing = true
|
|
153
153
|
|
|
154
154
|
[tool.bumpversion]
|
|
155
|
-
current_version = "0.
|
|
155
|
+
current_version = "0.12.1"
|
|
156
156
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
157
157
|
serialize = [
|
|
158
158
|
"{major}.{minor}.{patch}",
|
|
@@ -177,9 +177,9 @@ search = 'version = "{current_version}"'
|
|
|
177
177
|
replace = 'version = "{new_version}"'
|
|
178
178
|
|
|
179
179
|
[[tool.bumpversion.files]]
|
|
180
|
-
filename = "src/fujin/
|
|
181
|
-
replace = '
|
|
182
|
-
search = '
|
|
180
|
+
filename = "src/fujin/__init__.py"
|
|
181
|
+
replace = '__version__ = "{new_version}"'
|
|
182
|
+
search = '__version__ = "{current_version}"'
|
|
183
183
|
|
|
184
184
|
[tool.mypy]
|
|
185
185
|
check_untyped_defs = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.12.1"
|
|
@@ -7,6 +7,7 @@ import sys
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
9
|
import cappa
|
|
10
|
+
import fujin
|
|
10
11
|
|
|
11
12
|
from fujin.commands.app import App
|
|
12
13
|
from fujin.commands.config import ConfigCMD
|
|
@@ -50,9 +51,9 @@ class Fujin:
|
|
|
50
51
|
def main():
|
|
51
52
|
alias_cmd = _parse_aliases()
|
|
52
53
|
if alias_cmd:
|
|
53
|
-
cappa.invoke(Fujin, argv=alias_cmd, version=
|
|
54
|
+
cappa.invoke(Fujin, argv=alias_cmd, version=fujin.__version__)
|
|
54
55
|
else:
|
|
55
|
-
cappa.invoke(Fujin, version=
|
|
56
|
+
cappa.invoke(Fujin, version=fujin.__version__)
|
|
56
57
|
|
|
57
58
|
|
|
58
59
|
def _parse_aliases() -> list[str] | None:
|
|
@@ -2,6 +2,7 @@ import importlib
|
|
|
2
2
|
from contextlib import contextmanager
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from functools import cached_property
|
|
5
|
+
from typing import Generator
|
|
5
6
|
|
|
6
7
|
import cappa
|
|
7
8
|
|
|
@@ -47,7 +48,7 @@ class BaseCommand:
|
|
|
47
48
|
yield conn
|
|
48
49
|
|
|
49
50
|
@contextmanager
|
|
50
|
-
def app_environment(self) -> Connection:
|
|
51
|
+
def app_environment(self) -> Generator[Connection, None, None]:
|
|
51
52
|
with self.connection() as conn:
|
|
52
53
|
with conn.cd(self.app_dir):
|
|
53
54
|
with conn.prefix("source .appenv"):
|
|
@@ -100,7 +100,7 @@ export PATH=".venv/bin:$PATH"
|
|
|
100
100
|
conn.run(f"echo '{appenv.strip()}' > {self.app_dir}/.appenv")
|
|
101
101
|
versioned_assets_dir = f"{self.app_dir}/v{version}"
|
|
102
102
|
if not skip_setup:
|
|
103
|
-
conn.run("rm -rf .venv")
|
|
103
|
+
conn.run("sudo rm -rf .venv")
|
|
104
104
|
conn.run("uv venv")
|
|
105
105
|
if self.config.requirements:
|
|
106
106
|
conn.run(f"uv pip install -r {versioned_assets_dir}/requirements.txt")
|
|
@@ -149,7 +149,9 @@ Path to the production environment file that will be copied to the host.
|
|
|
149
149
|
|
|
150
150
|
env
|
|
151
151
|
~~~
|
|
152
|
-
A string containing the production environment variables
|
|
152
|
+
A string containing the production environment variables. In combination with the secrets manager, this is most useful when
|
|
153
|
+
you want to automate deployment through a CI/CD platform like GitLab CI or GitHub Actions. For an example of how to do this,
|
|
154
|
+
check out the `integrations guide </integrations.html>`_
|
|
153
155
|
|
|
154
156
|
.. important::
|
|
155
157
|
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from contextlib import contextmanager
|
|
4
4
|
from functools import partial
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING, Generator
|
|
6
6
|
|
|
7
7
|
import cappa
|
|
8
8
|
from fabric import Connection
|
|
@@ -32,7 +32,7 @@ def _get_watchers(host: HostConfig) -> list[Responder]:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@contextmanager
|
|
35
|
-
def host_connection(host: HostConfig) -> Connection:
|
|
35
|
+
def host_connection(host: HostConfig) -> Generator[Connection, None, None]:
|
|
36
36
|
connect_kwargs = None
|
|
37
37
|
if host.key_filename:
|
|
38
38
|
connect_kwargs = {"key_filename": str(host.key_filename)}
|
|
@@ -10,6 +10,7 @@ try:
|
|
|
10
10
|
except ImportError:
|
|
11
11
|
from enum import Enum
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
class StrEnum(str, Enum):
|
|
14
15
|
pass
|
|
15
16
|
|
|
@@ -36,9 +37,9 @@ class HookManager:
|
|
|
36
37
|
if not hooks_folder.exists():
|
|
37
38
|
return
|
|
38
39
|
self.hooks = {
|
|
39
|
-
h
|
|
40
|
+
h: f"./{hooks_folder / h.value}"
|
|
40
41
|
for h in Hook
|
|
41
|
-
if (hooks_folder / h.value).exists()
|
|
42
|
+
if (hooks_folder / h.value).exists()
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
def _run_hook(self, type_: Hook) -> None:
|
|
@@ -102,7 +102,7 @@ class ProcessManager:
|
|
|
102
102
|
body = (
|
|
103
103
|
local_config.read_text()
|
|
104
104
|
if local_config.exists() and not ignore_local
|
|
105
|
-
else template.format(**context, command=command)
|
|
105
|
+
else template.format(**context, command=command, process_name=name)
|
|
106
106
|
)
|
|
107
107
|
files.append((name, body))
|
|
108
108
|
# if using unix then we are sure a web process was defined and the proxy is not dummy
|
{fujin_cli-0.11.5/src/fujin/templates/gunicorn → fujin_cli-0.12.1/src/fujin/templates}/web.service
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# All options are documented here https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
|
|
2
2
|
# Inspiration was taken from here https://docs.gunicorn.org/en/stable/deploy.html#systemd
|
|
3
3
|
[Unit]
|
|
4
|
-
Description={app_name}
|
|
4
|
+
Description={app_name} {process_name}
|
|
5
5
|
Requires={app_name}.socket
|
|
6
6
|
After=network.target
|
|
7
7
|
|
|
8
8
|
[Service]
|
|
9
|
-
Type=notify
|
|
10
|
-
NotifyAccess=main
|
|
9
|
+
#Type=notify
|
|
10
|
+
#NotifyAccess=main
|
|
11
11
|
User={user}
|
|
12
12
|
Group={user}
|
|
13
13
|
RuntimeDirectory={app_name}
|
|
@@ -22,4 +22,4 @@ PrivateTmp=true
|
|
|
22
22
|
ProtectSystem=strict
|
|
23
23
|
|
|
24
24
|
[Install]
|
|
25
|
-
WantedBy=multi-user.target
|
|
25
|
+
WantedBy=multi-user.target
|
|
File without changes
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# All options are documented here https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
|
|
2
|
-
# Inspiration was taken from here https://docs.gunicorn.org/en/stable/deploy.html#systemd
|
|
3
|
-
[Unit]
|
|
4
|
-
Description={app_name} daemon
|
|
5
|
-
After=network.target
|
|
6
|
-
|
|
7
|
-
[Service]
|
|
8
|
-
User={user}
|
|
9
|
-
Group={user}
|
|
10
|
-
RuntimeDirectory={app_name}
|
|
11
|
-
WorkingDirectory={app_dir}
|
|
12
|
-
ExecStart={app_dir}/{command}
|
|
13
|
-
EnvironmentFile={app_dir}/.env
|
|
14
|
-
ExecReload=/bin/kill -s HUP $MAINPID
|
|
15
|
-
KillMode=mixed
|
|
16
|
-
TimeoutStopSec=5
|
|
17
|
-
PrivateTmp=true
|
|
18
|
-
# if your app does not need administrative capabilities, let systemd know
|
|
19
|
-
ProtectSystem=strict
|
|
20
|
-
|
|
21
|
-
[Install]
|
|
22
|
-
WantedBy=multi-user.target
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# All options are documented here https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
|
|
2
|
-
# Inspiration was taken from here https://docs.gunicorn.org/en/stable/deploy.html#systemd
|
|
3
|
-
[Unit]
|
|
4
|
-
Description={app_name} daemon
|
|
5
|
-
After=network.target
|
|
6
|
-
|
|
7
|
-
[Service]
|
|
8
|
-
User={user}
|
|
9
|
-
Group={user}
|
|
10
|
-
RuntimeDirectory={app_name}
|
|
11
|
-
WorkingDirectory={app_dir}
|
|
12
|
-
ExecStart={app_dir}/{command}
|
|
13
|
-
EnvironmentFile={app_dir}/.env
|
|
14
|
-
ExecReload=/bin/kill -s HUP $MAINPID
|
|
15
|
-
KillMode=mixed
|
|
16
|
-
TimeoutStopSec=5
|
|
17
|
-
PrivateTmp=true
|
|
18
|
-
# if your app does not need administrative capabilities, let systemd know
|
|
19
|
-
ProtectSystem=strict
|
|
20
|
-
|
|
21
|
-
[Install]
|
|
22
|
-
WantedBy=multi-user.target
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|