Docker PostgreSQL Deployment Issues
Recently while working on server-side development, I had a requirement to deploy db-postgres. I encountered some pitfalls during the process, so I’m documenting them here.
Deploying postgres service can be done by directly using the postgres image, but when it involves initializing the database and disk mapping, I encountered the following error in actual operation:
cannot access '/docker-entrypoint-initdb.d/': Operation not permitted
The final solution was to add privileged: true
to docker-compose.
Some online sources mentioned mounting Volume with RW permissions or adding chmod when using custom images, but both approaches didn’t work in my testing. The only solution currently is the one mentioned above.
The problem is solved, but the related knowledge points are worth summarizing.
PostgreSQL Deployment Solutions
To deploy a PostgreSQL instance, you can use docker-compose to directly mount the official image and configure it in compose, or you can build your own image and then use compose for orchestration. For a single service, you can also use docker run directly.
Custom PostgreSQL Image Configuration
For custom PostgreSQL image configuration, the general setup is as follows:
MAINTAINER Alan He<alan@1991421.cn>
FROM postgres:latest
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD "bx*fF6xxxxxxxxgQwkG."
COPY ../init.sql /docker-entrypoint-initdb.d/
VOLUME /var/lib/postgresql/data
EXPOSE 5432
Explanation
Regarding the above configuration, you need to know the following information:
You cannot specify the image name in dockerfile; you need to use the -t flag when executing docker build to specify it
docker-compose can directly point to a dockerfile. In this case, it can be considered as the latest image, as shown below:
build: .
The
.
means docker-compose will look for theDockerfile
file in the current pathThe PostgreSQL-related parameters above are environment variables, so ENV is used here. ARG/ENV are different - ARG is for building the image and explicitly defines parameters that need to be passed during use. Writing it this way means that when actually using the custom image, you don’t need to pass parameters
dockerfile only explicitly exposes container ports; which specific host machine ports they bind to is handled by compose/docker cli
dockerfile/docker-compose
These two can sometimes be confusing. After going through this pitfall, I have a better understanding:
- dockerfile is for single container services. When the service itself requires special operations during startup, such as a database needing to initialize and execute certain SQL, dockerfile is very suitable, as in the problem described above.
- compose is for orchestrating multiple containers. Complex configurations within the containers themselves need to be solved within the container => image.
Docker Debugging
- Locally, for example, you can directly run and start it in WS IDE
- When running on the target server, if exceptions occur, you can use
docker logs containerId
to view the logs
Final Thoughts
Documenting for reference.