localghost 1.0.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.
- localghost-1.0.0/LICENSE +21 -0
- localghost-1.0.0/PKG-INFO +194 -0
- localghost-1.0.0/README.md +166 -0
- localghost-1.0.0/pyproject.toml +66 -0
- localghost-1.0.0/src/localghost/.dockerignore +3 -0
- localghost-1.0.0/src/localghost/Dockerfile +5 -0
- localghost-1.0.0/src/localghost/__init__.py +1 -0
- localghost-1.0.0/src/localghost/cli.py +735 -0
- localghost-1.0.0/src/localghost/compose.py +72 -0
- localghost-1.0.0/src/localghost/feedback.py +93 -0
- localghost-1.0.0/src/localghost/generator.py +598 -0
- localghost-1.0.0/src/localghost/proxy_compose.yaml +45 -0
- localghost-1.0.0/src/localghost/proxy_compose_https.yaml +50 -0
- localghost-1.0.0/src/localghost/routes.py +88 -0
- localghost-1.0.0/src/localghost/runner.py +541 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/.traefik.yml +12 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/ca.go +487 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/ca_test.go +299 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/cmd/bootstrap/main.go +30 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/docker.go +261 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/docker_test.go +225 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/go.mod +5 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/go.sum +2 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/provider.go +550 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/provider_test.go +338 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/storage.go +298 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/LICENSE +201 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/config.go +20 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/http_config.go +134 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/marshaler.go +15 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/middlewares.go +231 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/plugins.go +5 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/tcp_config.go +57 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/tcp_middlewares.go +16 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/tls/certificate.go +12 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/tls/tls.go +38 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/types/domains.go +8 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/types/tls.go +11 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/github.com/traefik/genconf/dynamic/udp_config.go +35 -0
- localghost-1.0.0/src/localghost/traefik_plugin/src/github.com/SmileyChris/traefik-localghost-ca/vendor/modules.txt +5 -0
- localghost-1.0.0/src/localghost/trust.py +200 -0
localghost-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SmileyChris
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: localghost
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Localghost serves local applications at friendly .localhost URLs
|
|
5
|
+
Keywords: localghost,localhost,docker,compose,traefik,development,proxy
|
|
6
|
+
Author: SmileyChris
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development
|
|
19
|
+
Requires-Dist: click>=8.2,<9
|
|
20
|
+
Requires-Dist: rich>=13.9,<15
|
|
21
|
+
Requires-Dist: ruamel-yaml>=0.18.10,<0.19
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Project-URL: Homepage, https://github.com/SmileyChris/localghost
|
|
24
|
+
Project-URL: Documentation, https://github.com/SmileyChris/localghost/tree/main/docs
|
|
25
|
+
Project-URL: Repository, https://github.com/SmileyChris/localghost
|
|
26
|
+
Project-URL: Issues, https://github.com/SmileyChris/localghost/issues
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# Localghost
|
|
30
|
+
|
|
31
|
+
Localghost gives local Docker Compose projects and host-native development
|
|
32
|
+
servers friendly `.localhost` URLs. The `localghost` command keeps one small,
|
|
33
|
+
loopback-only [Traefik](https://traefik.io/traefik/) proxy running while each
|
|
34
|
+
application keeps its own lifecycle.
|
|
35
|
+
|
|
36
|
+
This is local-development infrastructure, not a production proxy configuration.
|
|
37
|
+
The proxy's Compose project and shared network are both named `localghost`;
|
|
38
|
+
containers connect through the
|
|
39
|
+
shared `localghost` Docker network.
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
You need Docker Engine or Docker Desktop, Docker Compose 5.x (CI tests 5.1.4),
|
|
44
|
+
[uv](https://docs.astral.sh/uv/getting-started/installation/), and loopback
|
|
45
|
+
port 80 available. Start the proxy without cloning this repository:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
uvx localghost
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Open [http://traefik.localhost](http://traefik.localhost) for the dashboard.
|
|
52
|
+
The command creates or reconciles the proxy and waits for it to become healthy.
|
|
53
|
+
When it is already running, it also lists active routes and where they come
|
|
54
|
+
from: a Compose project and service, or a host application's checkout path. To
|
|
55
|
+
stop and remove it later, run:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
uvx localghost down
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
To inspect the proxy without starting or reconciling it, run:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
uvx localghost --status
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Optional trusted HTTPS
|
|
68
|
+
|
|
69
|
+
HTTP is always available. On an interactive first start, `localghost` offers to
|
|
70
|
+
enable HTTPS; it explains the trust-store change before `mkcert` asks for
|
|
71
|
+
system authorization. You can also opt in explicitly:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
uvx localghost trust
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The command bootstraps a local constrained CA in Docker, exports only its
|
|
78
|
+
public root to your local state directory, and installs that root through
|
|
79
|
+
`mkcert` into the system and NSS stores. Private root and intermediate keys are
|
|
80
|
+
not exported. It also handles detected Zen browser NSS profiles. If `mkcert` is
|
|
81
|
+
not installed, the prompt is declined, or setup fails, the proxy remains
|
|
82
|
+
HTTP-only and prints the same command for retrying.
|
|
83
|
+
|
|
84
|
+
Running `trust` while the proxy is already running reconciles it to HTTPS after
|
|
85
|
+
the root is installed. When the proxy is stopped, `trust` only changes trust
|
|
86
|
+
state; run `localghost` when you are ready to start it.
|
|
87
|
+
|
|
88
|
+
Use `uvx localghost trust --status` to show the public-root fingerprint and
|
|
89
|
+
current mode. To return to HTTP-only operation and remove this exact root from the
|
|
90
|
+
managed stores:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
uvx localghost trust --remove
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`uvx` may reuse a cached CLI release. Fetch the newest published release when
|
|
97
|
+
you need it with:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
uvx --refresh localghost
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
See [Operating the proxy](docs/operations.md#upgrade) for reproducible,
|
|
104
|
+
version-specific use.
|
|
105
|
+
|
|
106
|
+
## Connect an application
|
|
107
|
+
|
|
108
|
+
Compose uses the checkout directory as the project name. If that name is unique
|
|
109
|
+
and contains only lowercase letters, digits, and hyphens, no configuration is
|
|
110
|
+
needed.
|
|
111
|
+
|
|
112
|
+
Attach the service to the shared network and opt into Traefik:
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
services:
|
|
116
|
+
web:
|
|
117
|
+
networks:
|
|
118
|
+
- default
|
|
119
|
+
- localghost
|
|
120
|
+
labels:
|
|
121
|
+
- "traefik.enable=true"
|
|
122
|
+
- "traefik.docker.network=localghost"
|
|
123
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web.rule=Host(`${COMPOSE_PROJECT_NAME}.localhost`)"
|
|
124
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.entrypoints=websecure"
|
|
125
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.rule=Host(`${COMPOSE_PROJECT_NAME}.localhost`)"
|
|
126
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.service=${COMPOSE_PROJECT_NAME}-web"
|
|
127
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.tls=true"
|
|
128
|
+
- "traefik.http.services.${COMPOSE_PROJECT_NAME}-web.loadbalancer.server.port=8000"
|
|
129
|
+
|
|
130
|
+
networks:
|
|
131
|
+
localghost:
|
|
132
|
+
external: true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The application must listen on `0.0.0.0:8000` inside its container. A checkout
|
|
136
|
+
directory named `my-project` is available at `http://my-project.localhost` after
|
|
137
|
+
`docker compose up -d`, without DNS or `/etc/hosts` changes.
|
|
138
|
+
|
|
139
|
+
See [Integrating applications](docs/integrating-applications.md) for the full
|
|
140
|
+
contract, explicit service association, secondary services, multiple checkouts,
|
|
141
|
+
and framework settings.
|
|
142
|
+
|
|
143
|
+
Or generate Compose configuration with `uvx localghost generate`; see
|
|
144
|
+
[Generating a local override](docs/generating-an-override.md). Use
|
|
145
|
+
`generate --mode host` when you want to keep and manage a bridge Compose file.
|
|
146
|
+
|
|
147
|
+
## Run a host application
|
|
148
|
+
|
|
149
|
+
For a Django or Vite development server running directly on your machine, use
|
|
150
|
+
the foreground `run` command instead. It writes no files to the checkout:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
uvx localghost run
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
It detects the development command, creates a temporary bridge, and serves the
|
|
157
|
+
application at `http://<project>.localhost` until the command exits. Use
|
|
158
|
+
`--dry-run` to inspect the command and generated bridge YAML, or provide your
|
|
159
|
+
own command with an explicit port:
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
uvx localghost run --port 3000 -- npm run dev
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When running the tool from another checkout, point it at the application:
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
uv run localghost run --directory /path/to/application
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
See [Run a host-native server](docs/generating-an-override.md#run-a-host-native-server)
|
|
172
|
+
for framework detection, port selection, and Django settings.
|
|
173
|
+
|
|
174
|
+
## Documentation
|
|
175
|
+
|
|
176
|
+
- [Architecture](docs/architecture.md) — ownership, discovery, networking, and
|
|
177
|
+
hostname conventions
|
|
178
|
+
- [Integrating applications](docs/integrating-applications.md) — complete
|
|
179
|
+
Compose examples and application requirements
|
|
180
|
+
- [Generating Compose configuration](docs/generating-an-override.md) — add an
|
|
181
|
+
existing service or scaffold a Dockerfile or host-native application
|
|
182
|
+
- [Operating the proxy](docs/operations.md) — lifecycle, upgrades, ports, and
|
|
183
|
+
inspection
|
|
184
|
+
- [Troubleshooting](docs/troubleshooting.md) — common failures and diagnostic
|
|
185
|
+
commands
|
|
186
|
+
- [Security and trust](docs/security.md) — Docker socket and package-trust
|
|
187
|
+
risks
|
|
188
|
+
- [Development and releases](docs/development.md) — fixtures, tests, CI, and
|
|
189
|
+
release-candidate checks
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Localghost
|
|
2
|
+
|
|
3
|
+
Localghost gives local Docker Compose projects and host-native development
|
|
4
|
+
servers friendly `.localhost` URLs. The `localghost` command keeps one small,
|
|
5
|
+
loopback-only [Traefik](https://traefik.io/traefik/) proxy running while each
|
|
6
|
+
application keeps its own lifecycle.
|
|
7
|
+
|
|
8
|
+
This is local-development infrastructure, not a production proxy configuration.
|
|
9
|
+
The proxy's Compose project and shared network are both named `localghost`;
|
|
10
|
+
containers connect through the
|
|
11
|
+
shared `localghost` Docker network.
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
You need Docker Engine or Docker Desktop, Docker Compose 5.x (CI tests 5.1.4),
|
|
16
|
+
[uv](https://docs.astral.sh/uv/getting-started/installation/), and loopback
|
|
17
|
+
port 80 available. Start the proxy without cloning this repository:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
uvx localghost
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Open [http://traefik.localhost](http://traefik.localhost) for the dashboard.
|
|
24
|
+
The command creates or reconciles the proxy and waits for it to become healthy.
|
|
25
|
+
When it is already running, it also lists active routes and where they come
|
|
26
|
+
from: a Compose project and service, or a host application's checkout path. To
|
|
27
|
+
stop and remove it later, run:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
uvx localghost down
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
To inspect the proxy without starting or reconciling it, run:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
uvx localghost --status
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Optional trusted HTTPS
|
|
40
|
+
|
|
41
|
+
HTTP is always available. On an interactive first start, `localghost` offers to
|
|
42
|
+
enable HTTPS; it explains the trust-store change before `mkcert` asks for
|
|
43
|
+
system authorization. You can also opt in explicitly:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
uvx localghost trust
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The command bootstraps a local constrained CA in Docker, exports only its
|
|
50
|
+
public root to your local state directory, and installs that root through
|
|
51
|
+
`mkcert` into the system and NSS stores. Private root and intermediate keys are
|
|
52
|
+
not exported. It also handles detected Zen browser NSS profiles. If `mkcert` is
|
|
53
|
+
not installed, the prompt is declined, or setup fails, the proxy remains
|
|
54
|
+
HTTP-only and prints the same command for retrying.
|
|
55
|
+
|
|
56
|
+
Running `trust` while the proxy is already running reconciles it to HTTPS after
|
|
57
|
+
the root is installed. When the proxy is stopped, `trust` only changes trust
|
|
58
|
+
state; run `localghost` when you are ready to start it.
|
|
59
|
+
|
|
60
|
+
Use `uvx localghost trust --status` to show the public-root fingerprint and
|
|
61
|
+
current mode. To return to HTTP-only operation and remove this exact root from the
|
|
62
|
+
managed stores:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
uvx localghost trust --remove
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`uvx` may reuse a cached CLI release. Fetch the newest published release when
|
|
69
|
+
you need it with:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
uvx --refresh localghost
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
See [Operating the proxy](docs/operations.md#upgrade) for reproducible,
|
|
76
|
+
version-specific use.
|
|
77
|
+
|
|
78
|
+
## Connect an application
|
|
79
|
+
|
|
80
|
+
Compose uses the checkout directory as the project name. If that name is unique
|
|
81
|
+
and contains only lowercase letters, digits, and hyphens, no configuration is
|
|
82
|
+
needed.
|
|
83
|
+
|
|
84
|
+
Attach the service to the shared network and opt into Traefik:
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
services:
|
|
88
|
+
web:
|
|
89
|
+
networks:
|
|
90
|
+
- default
|
|
91
|
+
- localghost
|
|
92
|
+
labels:
|
|
93
|
+
- "traefik.enable=true"
|
|
94
|
+
- "traefik.docker.network=localghost"
|
|
95
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web.rule=Host(`${COMPOSE_PROJECT_NAME}.localhost`)"
|
|
96
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.entrypoints=websecure"
|
|
97
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.rule=Host(`${COMPOSE_PROJECT_NAME}.localhost`)"
|
|
98
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.service=${COMPOSE_PROJECT_NAME}-web"
|
|
99
|
+
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.tls=true"
|
|
100
|
+
- "traefik.http.services.${COMPOSE_PROJECT_NAME}-web.loadbalancer.server.port=8000"
|
|
101
|
+
|
|
102
|
+
networks:
|
|
103
|
+
localghost:
|
|
104
|
+
external: true
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The application must listen on `0.0.0.0:8000` inside its container. A checkout
|
|
108
|
+
directory named `my-project` is available at `http://my-project.localhost` after
|
|
109
|
+
`docker compose up -d`, without DNS or `/etc/hosts` changes.
|
|
110
|
+
|
|
111
|
+
See [Integrating applications](docs/integrating-applications.md) for the full
|
|
112
|
+
contract, explicit service association, secondary services, multiple checkouts,
|
|
113
|
+
and framework settings.
|
|
114
|
+
|
|
115
|
+
Or generate Compose configuration with `uvx localghost generate`; see
|
|
116
|
+
[Generating a local override](docs/generating-an-override.md). Use
|
|
117
|
+
`generate --mode host` when you want to keep and manage a bridge Compose file.
|
|
118
|
+
|
|
119
|
+
## Run a host application
|
|
120
|
+
|
|
121
|
+
For a Django or Vite development server running directly on your machine, use
|
|
122
|
+
the foreground `run` command instead. It writes no files to the checkout:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
uvx localghost run
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
It detects the development command, creates a temporary bridge, and serves the
|
|
129
|
+
application at `http://<project>.localhost` until the command exits. Use
|
|
130
|
+
`--dry-run` to inspect the command and generated bridge YAML, or provide your
|
|
131
|
+
own command with an explicit port:
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
uvx localghost run --port 3000 -- npm run dev
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
When running the tool from another checkout, point it at the application:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
uv run localghost run --directory /path/to/application
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
See [Run a host-native server](docs/generating-an-override.md#run-a-host-native-server)
|
|
144
|
+
for framework detection, port selection, and Django settings.
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
- [Architecture](docs/architecture.md) — ownership, discovery, networking, and
|
|
149
|
+
hostname conventions
|
|
150
|
+
- [Integrating applications](docs/integrating-applications.md) — complete
|
|
151
|
+
Compose examples and application requirements
|
|
152
|
+
- [Generating Compose configuration](docs/generating-an-override.md) — add an
|
|
153
|
+
existing service or scaffold a Dockerfile or host-native application
|
|
154
|
+
- [Operating the proxy](docs/operations.md) — lifecycle, upgrades, ports, and
|
|
155
|
+
inspection
|
|
156
|
+
- [Troubleshooting](docs/troubleshooting.md) — common failures and diagnostic
|
|
157
|
+
commands
|
|
158
|
+
- [Security and trust](docs/security.md) — Docker socket and package-trust
|
|
159
|
+
risks
|
|
160
|
+
- [Development and releases](docs/development.md) — fixtures, tests, CI, and
|
|
161
|
+
release-candidate checks
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "localghost"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Localghost serves local applications at friendly .localhost URLs"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{ name = "SmileyChris" }]
|
|
10
|
+
keywords = ["localghost", "localhost", "docker", "compose", "traefik", "development", "proxy"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 5 - Production/Stable",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Programming Language :: Python :: 3.14",
|
|
21
|
+
"Topic :: Software Development",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"click>=8.2,<9",
|
|
25
|
+
"rich>=13.9,<15",
|
|
26
|
+
"ruamel-yaml>=0.18.10,<0.19",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/SmileyChris/localghost"
|
|
31
|
+
Documentation = "https://github.com/SmileyChris/localghost/tree/main/docs"
|
|
32
|
+
Repository = "https://github.com/SmileyChris/localghost"
|
|
33
|
+
Issues = "https://github.com/SmileyChris/localghost/issues"
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
localghost = "localghost.cli:cli"
|
|
37
|
+
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"pytest>=8.4,<10",
|
|
41
|
+
"pytest-cov>=6,<8",
|
|
42
|
+
"ruff>=0.11,<1",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[build-system]
|
|
46
|
+
requires = ["uv_build>=0.11.28,<0.12"]
|
|
47
|
+
build-backend = "uv_build"
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
addopts = "-q"
|
|
51
|
+
testpaths = ["tests"]
|
|
52
|
+
|
|
53
|
+
[tool.coverage.run]
|
|
54
|
+
branch = true
|
|
55
|
+
source = ["localghost"]
|
|
56
|
+
|
|
57
|
+
[tool.coverage.report]
|
|
58
|
+
fail_under = 95
|
|
59
|
+
show_missing = true
|
|
60
|
+
|
|
61
|
+
[tool.ruff]
|
|
62
|
+
line-length = 88
|
|
63
|
+
target-version = "py311"
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint]
|
|
66
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Local development proxy helpers."""
|