A docker run command is read the way your shell and then the docker CLI read it. The shell part comes first: quotes, backslash escapes, $'...' strings and line continuations are resolved, and the input is cut into separate commands at new lines, ; and &&, so each docker run in a pasted script becomes a service. The options are then read with docker's own flag table: -dit is three switches, -p80:80 and --publish=80:80 mean the same as -p 80:80, a switch such as --init never takes the next word, and the first word that is not an option is the image. Everything after the image is the container's command, which is why docker run nginx -p 80:80 publishes nothing; that case gets a warning.
Each option becomes the Compose Specification key for the same engine setting, and where the two tools behave differently, the file follows docker run. A named volume is declared with name: set to itself, because Compose otherwise creates a new, empty <project>_pgdata and the database appears to have lost its data. A network docker run joined must already exist, so it is declared external: true, unless the same input creates it with docker network create. --env-file becomes env_file with format: raw, the parser docker run uses. Memory and CPU limits use the service-level mem_limit and cpus from the core specification rather than the optional deploy.resources; --gpus becomes the device reservation under deploy that Docker Compose applies without Swarm. Ports are always quoted, because 22:22 unquoted is the number 1342 to a YAML 1.1 parser, and there is no version: key, which the specification marks obsolete.
Dollar signs need the most care. Compose substitutes $VARIABLE in every value, so a literal $, such as one in a single-quoted password or in a health check like pg_isready -U $POSTGRES_USER, is written as $$ and the container still receives one $. A $VARIABLE your shell would have expanded stays a variable, which Compose fills in from the environment or a .env file, and $(pwd) at the start of a bind mount becomes ., the folder that holds compose.yaml. Options with no Compose equivalent, such as -d, --rm, --cidfile and anything docker does not recognise, are listed as ignored with the reason. Shell loops, functions and variables assigned earlier in a script are not followed, and PowerShell is read only as far as its backtick line continuations.