PostgreSQL 13 will reach its end-of-life on November 13, 2025. So we're
upgrading before that happens.
We're also upgrading to PostgreSQL 14 in our CI. In this case, we're
using the default distribution (Trixie, as of October 2025); it doesn't
affect the development or production environments, so it's OK if use the
default one.
Debian 13 (Trixie) has become the default distribution for postgres
Docker images. However, we're using Debian 12 (Bookworm) for our Ruby
image. While it isn't strictly necessary, it makes sense to use the same
distribution in the two Docker images we depend on.
We had three files that were almost identical, and we can use
environment variables to specify the differences.
Note we're using the `PGUSER` and `PGPASSWORD` variables, since these
variables will automatically be used by the PostgreSQL client when we
have a blank `username` and `password` keys in the `database.yml` file
(which we did until now). The difference between these variables and the
`POSTGRES_USER` and `POSTGRES_PASSWORD` variables is that the `PG`
variables are used by the client connecting to the database, while the
`POSTGRES_` variables are used by the Docker postgresql image when
creating the database superuser.
For consistency with the code in our github workflows (and everywhere
else in the postgres world), we're respecting this double standard. The
fact that there are two different names for what's basically the same
thing makes the code confusing, though, particularly when running the
docker-compose commands, since we get the password from an environment
variable but we have to assign two different environment variables with
it.
So we're accepting both `PGPASSWORD` and `POSTGRES_PASSWORD` variables
in the database configuration file. This way, developers using
docker-compose can use `POSTGRES_PASSWORD` for everything and it'll work
fine. We're also making `PGPASSWORD` default to `POSTGRES_PASSWORD` so
we don't get a warning if we only set `POSTGRES_PASSWORD`:
```
WARN[0000] The "PGPASSWORD" variable is not set. Defaulting to a blank
string.
```
Also note we're using `DB_HOST` instead of `PGHOST` because that's the
variable Rails currently uses by default for new applications [1].
Finally, note we're using `.presence` in the `ENV` calls in the
database.yml file. The `PGPASSWORD` variable was set to an empty string
when running docker-compose, so using `ENV["PGPASSWORD"] ||` wouldn't
work.
[1] https://github.com/rails/rails/blob/c90a8701e5/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt#L22
Using a recent version of Docker Compose, we were getting a warning:
```
docker-compose.yml: the attribute `version` is obsolete, it will be
ignored, please remove it to avoid potential confusion
```
This attribute is obsolete since Docker Compose 1.27, released in 2020,
so most developers won't be affected by this change. Developers using
really old versions of Docker Compose might have to upgrade their Docker
Compose.
We're using version 13 because it's the one included in Debian Bullseye,
which is the operating system we currently use in our Dockerfile.
For consistency, we're using the same version in GitHub Actions.
Note this image requires setting a password. Otherwise we get an error:
> Database is uninitialized and superuser password is not specified.
> You must specify POSTGRES_PASSWORD to a non-empty value for the
> superuser. For example, "-e POSTGRES_PASSWORD=password" on
> "docker run".
Since now we're setting a password in the postgres service, we also need
to provide the `PGPASSWORD` environment variable (or to specify the
password in the `database.yml` file, which we do for GitLab since it
uses a separate database configuration file). Otherwise we get an error:
```
PG::ConnectionBad: connection to server at "::1", port 5432 failed:
fe_sendauth: no password supplied (PG::ConnectionBad)
```
When creating the Dockerfile, we run `npm install`, which creates a
`node_modules` folder inside the working directory.
However, when using docker-compose, we overwrite the contents of that
working directory (/var/www/consul) with the contents of the host
machine's working directory. This means that, unless the `npm install`
command is run on the host machine to create a `node_modules` folder on
the host machine (which would pretty much defeat the point of using
Docker), the container won't have a `node_modules` folder and the
application won't run.
So we're defining a volume in docker-compose.yml to make sure we keep
the container's `node_modules` folder.
It was added in commit 1db5a00ea, probably due to the Capistrano
configuration of the developer who wrote the code. On my machine, docker
compose crashed due to these lines.
We aren't sure why this option was added; only that it was added with
macos and windows developers in mind.
Since we aren't sure about it, we're using the default `consistent`
option instead.
We were getting an error since we started using the postgres 9.6 image:
```
Attaching to app_1, database_1
database_1 | Error: Database is uninitialized and superuser password is not specified.
database_1 | You must specify POSTGRES_PASSWORD to a non-empty value for the
database_1 | superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".
database_1 |
database_1 | You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
database_1 | connections without a password. This is *not* recommended.
database_1 |
database_1 | See PostgreSQL documentation about "trust":
database_1 | https://www.postgresql.org/docs/current/auth-trust.html
```
The following parameters have been added to deploy-secrets.yml:
* **use_rvm**: yes/no
* **ruby_version**: Ruby version for rvm. Defaults to 2.3.2
* **repository**: Git repository. Defaults to the oficial repository
* **branch**: Branch to deploy. Defaults to master
* **rails_env**: Defaults to the stage.
Fixed migrations that required admin rights. Now first check if the postgress extensions are available. If so finish without doing nothin.
Added support for passenger.
The following enhancements have been made to docker/docker-compose
* Fixed bug when building the image.
* docker-compose up starts the server
* Scaffolding inside the container respect the ownership of the files
outside it
* Volumes are tagged as 'delegated' in order to improve performance for
mac/windoze users.
* bundler stores packages in a volume. This whay new packages can be
added without rebuilding the image:
```bash
docker-compose run app bundle install
```