Skip to content

Commit d56c5ed

Browse files
base-starter
1 parent 0f289cf commit d56c5ed

10 files changed

Lines changed: 43 additions & 42 deletions

File tree

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ DOMAIN=localhost
66
# DOMAIN=localhost.tiangolo.com
77

88
# Used by the backend to generate links in emails to the frontend
9-
FRONTEND_HOST=http://localhost:5173
9+
FRONTEND_HOST=http://localhost:5174
1010
# In staging and production, set this env var to the frontend host, e.g.
1111
# FRONTEND_HOST=https://dashboard.example.com
1212

@@ -17,7 +17,7 @@ PROJECT_NAME="Full Stack FastAPI Project"
1717
STACK_NAME=full-stack-fastapi-project
1818

1919
# Backend
20-
BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5173,https://localhost,https://localhost:5173,http://localhost.tiangolo.com"
20+
BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5174,https://localhost,https://localhost:5174,http://localhost.tiangolo.com"
2121
SECRET_KEY=changethis
2222
FIRST_SUPERUSER=admin@example.com
2323
FIRST_SUPERUSER_PASSWORD=changethis

backend/Dockerfile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ ENV PATH="/app/.venv/bin:$PATH"
2222

2323
# Install dependencies
2424
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
25+
COPY uv.lock pyproject.toml /app/
26+
2527
RUN --mount=type=cache,target=/root/.cache/uv \
26-
--mount=type=bind,source=uv.lock,target=uv.lock \
27-
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
2828
uv sync --frozen --no-install-workspace --package app
2929

3030
COPY ./backend/scripts /app/backend/scripts
@@ -36,8 +36,6 @@ COPY ./backend/app /app/backend/app
3636
# Sync the project
3737
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
3838
RUN --mount=type=cache,target=/root/.cache/uv \
39-
--mount=type=bind,source=uv.lock,target=uv.lock \
40-
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
4139
uv sync --frozen --package app
4240

4341
WORKDIR /app/backend/

backend/app/core/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Settings(BaseSettings):
3434
SECRET_KEY: str = secrets.token_urlsafe(32)
3535
# 60 minutes * 24 hours * 8 days = 8 days
3636
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8
37-
FRONTEND_HOST: str = "http://localhost:5173"
37+
FRONTEND_HOST: str = "http://localhost:5174"
3838
ENVIRONMENT: Literal["local", "staging", "production"] = "local"
3939

4040
BACKEND_CORS_ORIGINS: Annotated[

compose.override.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ services:
1010
volumes:
1111
- /var/run/docker.sock:/var/run/docker.sock
1212
ports:
13-
- "80:80"
14-
- "8090:8080"
13+
- "81:80"
14+
- "8091:8080"
1515
# Duplicate the command from compose.yml to add --api.insecure=true
1616
command:
1717
# Enable Docker in Traefik, so that it reads labels from Docker services
@@ -48,17 +48,17 @@ services:
4848
db:
4949
restart: "no"
5050
ports:
51-
- "5432:5432"
51+
- "5433:5432"
5252

5353
adminer:
5454
restart: "no"
5555
ports:
56-
- "8080:8080"
56+
- "8082:8080"
5757

5858
backend:
5959
restart: "no"
6060
ports:
61-
- "8000:8000"
61+
- "8001:8000"
6262
build:
6363
context: .
6464
dockerfile: backend/Dockerfile
@@ -90,18 +90,18 @@ services:
9090
mailcatcher:
9191
image: schickling/mailcatcher
9292
ports:
93-
- "1080:1080"
94-
- "1025:1025"
93+
- "1081:1080"
94+
- "1026:1025"
9595

9696
frontend:
9797
restart: "no"
9898
ports:
99-
- "5173:80"
99+
- "5174:80"
100100
build:
101101
context: .
102102
dockerfile: frontend/Dockerfile
103103
args:
104-
- VITE_API_URL=http://localhost:8000
104+
- VITE_API_URL=http://localhost:8001
105105
- NODE_ENV=development
106106

107107
playwright:
@@ -127,7 +127,7 @@ services:
127127
- ./frontend/blob-report:/app/frontend/blob-report
128128
- ./frontend/test-results:/app/frontend/test-results
129129
ports:
130-
- 9323:9323
130+
- 9324:9323
131131

132132
networks:
133133
traefik-public:

compose.traefik.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ services:
33
image: traefik:3.6
44
ports:
55
# Listen on port 80, default for HTTP, necessary to redirect to HTTPS
6-
- 80:80
6+
- 81:80
77
# Listen on port 443, default for HTTPS
8-
- 443:443
8+
- 444:443
99
restart: always
1010
labels:
1111
# Enable Traefik for this service, to make it available in the public network

development.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ docker compose watch
1010

1111
* Now you can open your browser and interact with these URLs:
1212

13-
Frontend, built with Docker, with routes handled based on the path: <http://localhost:5173>
13+
Frontend, built with Docker, with routes handled based on the path: <http://localhost:5174>
1414

15-
Backend, JSON based web API based on OpenAPI: <http://localhost:8000>
15+
Backend, JSON based web API based on OpenAPI: <http://localhost:8001>
1616

17-
Automatic interactive documentation with Swagger UI (from the OpenAPI backend): <http://localhost:8000/docs>
17+
Automatic interactive documentation with Swagger UI (from the OpenAPI backend): <http://localhost:8001/docs>
1818

19-
Adminer, database web administration: <http://localhost:8080>
19+
Adminer, database web administration: <http://localhost:8082>
2020

21-
Traefik UI, to see how the routes are being handled by the proxy: <http://localhost:8090>
21+
Traefik UI, to see how the routes are being handled by the proxy: <http://localhost:8091>
2222

2323
**Note**: The first time you start your stack, it might take a minute for it to be ready. While the backend waits for the database to be ready and configures everything. You can check the logs to monitor it.
2424

@@ -44,13 +44,13 @@ This is useful for:
4444
* Verifying email content and formatting
4545
* Debugging email-related functionality without sending real emails
4646

47-
The backend is automatically configured to use Mailcatcher when running with Docker Compose locally (SMTP on port 1025). All captured emails can be viewed at <http://localhost:1080>.
47+
The backend is automatically configured to use Mailcatcher when running with Docker Compose locally (SMTP on port 1025). All captured emails can be viewed at <http://localhost:1081>.
4848

4949
## Local Development
5050

5151
The Docker Compose files are configured so that each of the services is available in a different port in `localhost`.
5252

53-
For the backend and frontend, they use the same port that would be used by their local development server, so, the backend is at `http://localhost:8000` and the frontend at `http://localhost:5173`.
53+
For the backend and frontend, they use the same port that would be used by their local development server, so, the backend is at `http://localhost:8001` and the frontend at `http://localhost:5174`.
5454

5555
This way, you could turn off a Docker Compose service and start its local development service, and everything would keep working, because it all uses the same ports.
5656

@@ -76,7 +76,7 @@ And then you can run the local development server for the backend:
7676

7777
```bash
7878
cd backend
79-
fastapi dev app/main.py
79+
fastapi dev app/main.py --port 8001
8080
```
8181

8282
## Docker Compose in `localhost.tiangolo.com`
@@ -188,19 +188,19 @@ The production or staging URLs would use these same paths, but with your own dom
188188

189189
Development URLs, for local development.
190190

191-
Frontend: <http://localhost:5173>
191+
Frontend: <http://localhost:5174>
192192

193-
Backend: <http://localhost:8000>
193+
Backend: <http://localhost:8001>
194194

195-
Automatic Interactive Docs (Swagger UI): <http://localhost:8000/docs>
195+
Automatic Interactive Docs (Swagger UI): <http://localhost:8001/docs>
196196

197-
Automatic Alternative Docs (ReDoc): <http://localhost:8000/redoc>
197+
Automatic Alternative Docs (ReDoc): <http://localhost:8001/redoc>
198198

199-
Adminer: <http://localhost:8080>
199+
Adminer: <http://localhost:8082>
200200

201-
Traefik UI: <http://localhost:8090>
201+
Traefik UI: <http://localhost:8091>
202202

203-
MailCatcher: <http://localhost:1080>
203+
MailCatcher: <http://localhost:1081>
204204

205205
### Development URLs with `localhost.tiangolo.com` Configured
206206

@@ -214,8 +214,8 @@ Automatic Interactive Docs (Swagger UI): <http://api.localhost.tiangolo.com/docs
214214

215215
Automatic Alternative Docs (ReDoc): <http://api.localhost.tiangolo.com/redoc>
216216

217-
Adminer: <http://localhost.tiangolo.com:8080>
217+
Adminer: <http://localhost.tiangolo.com:8082>
218218

219-
Traefik UI: <http://localhost.tiangolo.com:8090>
219+
Traefik UI: <http://localhost.tiangolo.com:8091>
220220

221-
MailCatcher: <http://localhost.tiangolo.com:1080>
221+
MailCatcher: <http://localhost.tiangolo.com:1081>

frontend/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ bun install
1313
bun run dev
1414
```
1515

16-
* Then open your browser at http://localhost:5173/.
16+
* Then open your browser at http://localhost:5174/.
1717

1818
Notice that this live server is not running inside Docker, it's for local development, and that is the recommended workflow. Once you are happy with your frontend, you can build the frontend Docker image and start it, to test it in a production-like environment. But building the image at every change will not be as productive as running the local development server with live reload.
1919

frontend/playwright.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default defineConfig({
2424
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
2525
use: {
2626
/* Base URL to use in actions like `await page.goto('/')`. */
27-
baseURL: 'http://localhost:5173',
27+
baseURL: 'http://localhost:5174',
2828

2929
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
3030
trace: 'on-first-retry',
@@ -85,7 +85,7 @@ export default defineConfig({
8585
/* Run your local dev server before starting the tests */
8686
webServer: {
8787
command: 'bun run dev',
88-
url: 'http://localhost:5173',
88+
url: 'http://localhost:5174',
8989
reuseExistingServer: !process.env.CI,
9090
},
9191
});

frontend/tests/reset-password.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ test("User can reset password successfully using the link", async ({
5959
let url = await page.getAttribute(selector, "href")
6060

6161
// TODO: update var instead of doing a replace
62-
url = url!.replace("http://localhost/", "http://localhost:5173/")
62+
url = url!.replace("http://localhost/", "http://localhost:5174/")
6363

6464
// Set the new password and confirm it
6565
await page.goto(url)
@@ -111,7 +111,7 @@ test("Weak new password validation", async ({ page, request }) => {
111111

112112
const selector = 'a[href*="/reset-password?token="]'
113113
let url = await page.getAttribute(selector, "href")
114-
url = url!.replace("http://localhost/", "http://localhost:5173/")
114+
url = url!.replace("http://localhost/", "http://localhost:5174/")
115115

116116
// Set a weak new password
117117
await page.goto(url)

frontend/vite.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ export default defineConfig({
1919
react(),
2020
tailwindcss(),
2121
],
22+
server: {
23+
port: 5174,
24+
},
2225
})

0 commit comments

Comments
 (0)