-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add --db-image
argument to wasp start db
command
#3182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Allows users to specify a custom Docker image when starting the development database. Usage: wasp start db --image postgres:15 This enables developers to test with different PostgreSQL versions or custom database images.
- Note default postgres image in help text - Add error handling for unrecognized arguments - Use fromMaybe to simplify image selection logic - Add comprehensive documentation in CLI and database docs
- Replace manual argument parsing with Options.Applicative parser - Move parser to top level as requested - Add note about PostgreSQL extensions use case in documentation - Remove redundant CLI documentation as requested
- Change StartDbArgs from newtype to data type - Move startDbArgsParser below the main start function - Parse arguments as the first operation in start function
Deploying wasp-docs-on-main with
|
Latest commit: |
658f0dc
|
Status: | ✅ Deploy successful! |
Preview URL: | https://059fd91c.wasp-docs-on-main.pages.dev |
Branch Preview URL: | https://db-image-arg.wasp-docs-on-main.pages.dev |
Tested with PostGIS and pgvector images, both work fine! |
e278763
to
dcdd083
Compare
--image
argument to wasp start db
command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the feature.
I want to request one main change: We should refactor the system in a way that the default case is just an instantiation of a particular image, not a special procedure.
In other words, we want wasp start db
to mean (as closely as possible) wasp start db --image postgres
, both in terms of how we implement it and how we communicate it with users. There are a few comments talking about what this means for different parts of our code.
Other than that, I found some small stuff: missing help text, function name, etc.
waspc/ChangeLog.md
Outdated
### 🔧 Small improvements | ||
|
||
- You can now specify which PostgreSQL image to use in `wasp start db` with the `--image` argument. ([#3182](https://github.com/wasp-lang/wasp/pull/3182)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd list this as a new feature, not a small improvement.
It may not be useful to everybody but it is a feature :)
waspc/cli/exe/Main.hs
Outdated
title " IN PROJECT", | ||
cmd " start Runs Wasp app in development mode, watching for file changes.", | ||
cmd " start db Starts managed development database for you.", | ||
cmd " start db [--image <image>]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include some examples for wasp start
in wasp db
?
web/docs/data-model/databases.md
Outdated
You can also specify a custom Docker image to use for the database with the `--image` option. This is particularly useful when you need PostgreSQL with specific extensions (like PostGIS for geographic data, pgvector for embeddings, etc.): | ||
|
||
```bash | ||
# Use default PostgreSQL image |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should say what the default is, maybe even communicate it as:
wasp start db
is a shorthand forwasp start db -- image postgres
start args = do | ||
startDbArgs <- | ||
parseArguments "wasp start db" startDbArgsParser args | ||
& either (E.throwError . CommandError "Invalid arguments") return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to change anything here, just FYI.
I rarely use &
in Haskell. I believe it's more idiomatic doing stuff from right to left (which is unfortunate) so I'm not used to seeing this.
Here's how I would probably write this:
start args = do
startDbArgs <-
either (E.throwError . CommandError "Invalid arguments") return $
parseArguments "wasp start db" startDbArgsParser args
Or even like this:
start args = do
startDbArgs <- case parseArguments "wasp start db" startDbArgsParser args of
Left err -> E.throwError $ CommandError "Invalid arguments" err
Right parsedArgs -> return parsedArgs
You can pick whatever you like the most, all options are perfectly valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opposite opinion: I think the current code with the &
is the best one.
While &
is not that popular as $
, I don't see any reason why one would not use it in appropriate places("appropriate" being the key here).
In Haskell, you anyway read both from left to right and right to left, it depends on the situation, so there is no golden rule here.
It does make sense to stick with how people normally write Haskell, so I agree one shoudln't go crazy with &
, but here I think its usage is perfect, because it allows you to read code in the right order -> business logic is in focus, error handling comes after (and is even nicely indented). So I can read it as do this, but if error this
and I think that is perfect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case it's written like that for consistency, like in here:
wasp/waspc/cli/src/Wasp/Cli/Command/CreateNewProject.hs
Lines 32 to 36 in 1129a07
createNewProject :: Arguments -> Command () | |
createNewProject args = do | |
newProjectArgs <- | |
parseArguments "wasp new" newProjectArgsParser args | |
& either Common.throwProjectCreationError return |
I think a good idea in general for this would be to start using Options.Applicative for all of our CLI argument parsing, not just occasionally.
++ ( if isJust customImage | ||
then [" ℹ Using custom Docker image: " <> dockerImage, ""] | ||
else [] | ||
) | ||
++ [ "Additional info:", | ||
" ℹ Connection URL, in case you might want to connect with external tools:", | ||
" " <> connectionUrl, | ||
" ℹ Database data is persisted in a docker volume with the following name" | ||
<> " (useful to know if you will want to delete it at some point):", | ||
" " <> dockerVolumeName | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point (and perhaps even at an earlier one), I think it makes sense to extract these messages into their own variables inside the where
block. There's a lot of nesting.
@cprecioso What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the nesting was basically unnecessary, now it's all in the top level. I don't really like extracting it somewhere else, and now it's simpler, so I think I'll leave it as-is.
"To run PostgreSQL dev database, Wasp needs `docker` installed and in PATH." | ||
throwIfDevDbPortIsAlreadyInUse | ||
|
||
let dockerImage = fromMaybe "postgres" customImage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we should do this part outside of the calling function and send the final image in as an argument:
startPostgresDevDb :: Path' Abs (Dir WaspProjectDir) -> String -> String -> Command ()
startPostgresDevDb waspProjectDir appName image = do
There isn't really a reason for this function to take in an optional and then
Also, I see the name was changed from "postgres" to "postgre." I believe this is incorrect: the official name of the project is "PostgreSQL" and its nickname is "Postgres." (wikipedia).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh weird thing about the Postgres thing, I didn't realize!
++ ( if isJust customImage | ||
then [" ℹ Using custom Docker image: " <> dockerImage, ""] | ||
else [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need any special text here. We should always say "Using Docker image ...."
The default case should just be a default value for something, not a special procedure. This means:
- We set the default value at the top of the "system."
- Everything else is completely agnostic on whether it's working with the default value or the custom value.
-- | Command-line arguments for `wasp start db` | ||
data StartDbArgs = StartDbArgs | ||
{ customDbImage :: Maybe String | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we have all this parsing logic in the same file, I suggest moving this datatype below start
.
Our rule is:
- Exported stuff before private stuff
- If
A
is used inB
,A
should come as soon as possible afterB
without breaking the first rule (I think Clean Code has a nice name for this rule, can't remember now)
Unfortunately, many files don't stick to this rule since we can't automate it (at least I think we can't) and sometimes forget. But when we remember, we should follow it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have super strict rule for this? If we do I have to admit I forgot it.
My rule is, make it read like a story (Clean Code also). Almost always that will match what you wrote above, but there could be some exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice stuff! Some good comments were already left by others, but I also left some of my own.
One thing I am wondering about is the workflow itself -> let's say somebody is using custom dev db, do they have to keep passing this arg all the time? Is that a bit cumbersome? I guess they will have to set up some kind of small shell script to serve as a runner so they don't have to repeat it.
I commented in Railway (or was it Fly) PR also on this. I wonder if it would make sense, from the DX perspective, to actually also have a central place to define a default database image, that would be used both in dev and when deploying. Since at the end, it is a property of the full stack app -> when you are building your wasp app, you are assuming some kind of database, and ideally you would use the same exact database setup both in dev and in prod. I am sure that might not always be so, but it would be nice if this primary use case is supported by us.
This doesn't have to be done in this issue, but I would like us to think/discuss about it, now that we are doing this.
-- | Command-line arguments for `wasp start db` | ||
data StartDbArgs = StartDbArgs | ||
{ customDbImage :: Maybe String | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have super strict rule for this? If we do I have to admit I forgot it.
My rule is, make it read like a story (Clean Code also). Almost always that will match what you wrote above, but there could be some exceptions.
start args = do | ||
startDbArgs <- | ||
parseArguments "wasp start db" startDbArgsParser args | ||
& either (E.throwError . CommandError "Invalid arguments") return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opposite opinion: I think the current code with the &
is the best one.
While &
is not that popular as $
, I don't see any reason why one would not use it in appropriate places("appropriate" being the key here).
In Haskell, you anyway read both from left to right and right to left, it depends on the situation, so there is no golden rule here.
It does make sense to stick with how people normally write Haskell, so I agree one shoudln't go crazy with &
, but here I think its usage is perfect, because it allows you to read code in the right order -> business logic is in focus, error handling comes after (and is even nicely indented). So I can read it as do this, but if error this
and I think that is perfect.
Yes, I agree. This also makes me feel like what @infomiho once said about having a deployment config file might also make sense. As you said, I think it might be out-of-scope for this PR, but we could start looking into it. (If/when we conclude that custom DB images are a feature that people do use) |
@sodic @Martinsos ready |
I do think they are needed for sure, the custom DB images. But sure more data will be helpful. There is one older related issue: #169 . And I know Miho did some work on it in the meantime where i also aprticipated but can't find it right now, I asked him to link it there. EDIT: I also created issue for it here: #3193 . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of comments, but once you resolve them, I am good with merging!
" supplied migration name or asking for one.", | ||
" start [--db-image <image>] Alias for `wasp start db`.", | ||
" Starts managed development database for you.", | ||
" Optionally specify a custom Docker image." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not the same as for wasp start db
(missing "with --db-image). I would add it here or remove it up there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get this comment, can you clarify? I do handle the argument in both cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha sorry, I should have been more verbose! So CLI docs for wasp start db
are very similar, but a bit different, and there is no reason for them to be different, so I was suggesting to make them the same. THe difference is in "with --db-image" part).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh understood, my eyes were skipping over that haha
--image
argument to wasp start db
command--db-image
argument to wasp start db
command
wasp db start
#1414Adds an optional
--db-image
argument to thewasp start db
command, allowing users to specify a custom Docker image for their development database.This is part of #3174. We're adding
ask-the-documents
to the repo, which needs a specific PostgreSQL extension. This way we can more easily test the app locally.Changes
--db-image
argument parsingwasp start db
to accept and use custom Docker imagesUsage
Note
🤖 Generated with Claude Code
and 👨🏻 reviewed and edited by a person