Software environment:
- CentOS 7.0
- Docker 18.06.0-ce
Following is the docker image
- Mysql 5.7
- Gerrit 2.15.3
- Nginx 1.15.2-alpine
Assume that the current server ip address is (all three software are on the same server)
192.168.0.1
Note: When using docker image, it is strongly recommended to fix the mirror version number of the container instead of lastest.
This ensures that it works correctly in any environment, because different versions of mirrors may be configured differently. I have been in the pit for a long time.
Local directory structure (configuration directory containing mysql gerrit nginx 3 software):
├── docker-compose.yml ├── gerrit │ └── review_site ├── mysql │ └── db └── nginx ├── logs └── nginx.conf
1. Configure docker-compose.yml file:
First configure Gerrit and Mysql, and then Nginx:
version: "3" services: db: image: "mysql:5.7" ports: - "3306:3306" restart: always volumes: - /data/mysql/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=XXXX gerrit: depends_on: - db image: "openfrontier/gerrit:2.15.3" ports: - "29418:29418" - "8080:8080" volumes: - /data/gerrit/review_site:/var/gerrit/review_site environment: - AUTH_TYPE=HTTP - WEBURL=http://192.168.0.1:8080 - DATABASE_TYPE=mysql - DATABASE_HOSTNAME=db - DATABASE_PORT=3306 - DATABASE_DATABASE=gerrit - DATABASE_USERNAME=gerrit - DATABASE_PASSWORD=gerrit
2. Start db database container first:
Priority must be given to starting the Mysql database here, because you need to create the gerrit database and operate the accounts of the gerrit database.
$ docker-compose up db
3. Configure the database:
After the database container is started, it enters the container with the root account:
$ docker-compose up db
Container names can be viewed through docker-compose ps
Enter mysql console with root account
root@d73a4491dba4:/# mysql -u root -p
Create gerrit database and set character set utf-8
mysql> CREATE database Database name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Create gerrit account and password (name self-defined, mainly for gerrit database access) and set access permissions to gerrit database
Here, for testing purposes, I set up the database, account number and password as gerrit.
mysql> grant all privileges on gerrit.* to gerrit@'%' identified by 'gerrit';
Immediate refresh permission
mysql> flush privileges;
In the new version of mysql, the default value of timestamp needs to be configured manually. If the local test is not set, gerrit always makes errors when creating tables
Exception in thread "main" com.google.gwtorm.server.OrmException: Cannot apply SQL CREATE TABLE account_group_members_audit ( added_by INT DEFAULT 0 NOT NULL, removed_by INT, removed_on TIMESTAMP NULL DEFAULT NULL, account_id INT DEFAULT 0 NOT NULL, group_id INT DEFAULT 0 NOT NULL, added_on TIMESTAMP NOT NULL ,PRIMARY KEY(account_id,group_id,added_on) ) at com.google.gwtorm.jdbc.JdbcExecutor.execute(JdbcExecutor.java:44) at com.google.gwtorm.jdbc.JdbcSchema.createRelations(JdbcSchema.java:134) at com.google.gwtorm.jdbc.JdbcSchema.updateSchema(JdbcSchema.java:104) at com.google.gerrit.server.schema.SchemaCreator.create(SchemaCreator.java:81) at com.google.gerrit.server.schema.SchemaUpdater.update(SchemaUpdater.java:108) at com.google.gerrit.pgm.init.BaseInit$SiteRun.upgradeSchema(BaseInit.java:386) at com.google.gerrit.pgm.init.BaseInit.run(BaseInit.java:143) at com.google.gerrit.pgm.util.AbstractProgram.main(AbstractProgram.java:61) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.google.gerrit.launcher.GerritLauncher.invokeProgram(GerritLauncher.java:204) at com.google.gerrit.launcher.GerritLauncher.mainImpl(GerritLauncher.java:108) at com.google.gerrit.launcher.GerritLauncher.main(GerritLauncher.java:63) at Main.main(Main.java:24) Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Invalid default value for 'added_on' at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at com.mysql.jdbc.Util.getInstance(Util.java:408) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2497) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2455) at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:839) at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:739) at com.google.gwtorm.jdbc.JdbcExecutor.execute(JdbcExecutor.java:42) ... 15 more
This can be solved by using MySQL root user login and setting global explicit_defaults_for_timestamp=1; as follows:
mysql> set global explicit_defaults_for_timestamp=1;
Database Configuration Completed, Exit
mysql> exit
4. You can start gerrit
$ docker-compose up gerrit
If the following words appear, the gerrit startup is successful
[main] INFO org.eclipse.jetty.server.Server : Started @22467ms [main] INFO com.google.gerrit.pgm.Daemon : Gerrit Code Review 2.15.3 ready
5. Because we use HTTP authentication, we need to configure reverse proxy:
First, configure the docker-compose.yml file a nd modify the content under gerrit service:
Add environment variables: HTTPD_LISTEN URL = proxy-http:/*:8080/
Modify environment variables: WEBURL=http://192.168.0.1:8080 is WEBURL=http://192.168.0.1
That is to say, remove the port number.
As follows:
version: "3" services: db: ... gerrit: ... environment: - AUTH_TYPE=HTTP - HTTPD_LISTENURL=proxy-http://*:8080/ - WEBURL=http://192.168.0.1 ...
b. Then prepare the nginx.conf file
This file is the configuration file of the Nginx server. You can get the default configuration file from the nginx container, and then modify it:
Here's how to do it from Nginx's official docker mirror website
$ docker run --name tmp-nginx-container -d nginx:1.15.2-alpine $ docker cp tmp-nginx-container:/etc/nginx/nginx.conf /host/path/nginx.conf $ docker rm -f tmp-nginx-container
The file/host/path/nginx.conf is a default configuration file that we can modify directly:
Add server (add start - --- add end) in the http section:
... http { #add start server { listen *:80; server_name gerrit; location / { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/passwd; proxy_pass http://gerrit:8080/; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; } } #add end ... } ...
Explain several important points:
- server_name gerrit;
- proxy_pass http://gerrit:8080/;
Ser_name is generally used to specify the ip address or domain name, but here we use the docker container, and multiple containers run together, and the service name in docker-compose.yml is directly used for interconnection between containers, so gerrit is used here.
This is particularly important, I have been using the ip address before, gerrit has been unable to access the normal, drop pit for 2 days.
- auth_basic_user_file /etc/nginx/passwd;
Configure the authentication file for HTTP login, which saves the user account password and is created by the htpasswd command.
After the nginx.conf file is configured, it is placed in the local / data/nginx/nginx.conf, referring to the directory structure at the beginning of this article.
d. Create an authentication file passwd
$ htpasswd -c /data/gerrit/review_site/etc/passwd Full name
Enter your password after you return (the specific use of the htpasswd command can be Baidu itself).
e. Start the Nginx container
Add Nginx container configuration code in docker-compose.yml:
nginx: depends_on: - gerrit image: "nginx:1.15.2-alpine" ports: - "80:80" volumes: - /data/nginx/nginx.conf:/etc/nginx/nginx.conf - /data/gerrit/review_site/etc/passwd:/etc/nginx/passwd
The passwd file here is created and saved locally by htpasswd and mounted in the Nginx container with volumes
Then you can start the Nginx container:
$ docker-compose up nginx
Or stop the Gerrit/Mysql container before you start the whole process:
$ docker-compose down $ docker-compose up
If there are no errors in the startup process, the build is successful.
Client (another machine) accesses http://192.168.0.1
First, the Nginx server gets and pops up the input user name password window. After entering the account password (created by the htpasswd command above), it will be forwarded by Nginx to http://192.168.0.1:8080.
Finally, attach the complete configuration of docker-compose.yml nginx.conf (gerrit.config doesn't need to be modified independently, because when the container runs, it will be overwritten by environment variables in the docker-compose.yml file):
docker-compose.yml:
version: "3" services: db: image: "mysql:5.7" ports: - "3306:3306" restart: always volumes: - /data/mysql/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=XXX gerrit: depends_on: - db image: "openfrontier/gerrit:2.15.3" ports: - "29418:29418" - "8080:8080" volumes: - /data/gerrit/review_site:/var/gerrit/review_site environment: - AUTH_TYPE=HTTP - HTTPD_LISTENURL=proxy-http://*:8080/ - WEBURL=http://192.168.0.1 - DATABASE_TYPE=mysql - DATABASE_HOSTNAME=db - DATABASE_PORT=3306 - DATABASE_DATABASE=gerrit - DATABASE_USERNAME=gerrit - DATABASE_PASSWORD=gerrit nginx: depends_on: - gerrit image: "nginx:1.15.2-alpine" ports: - "80:80" volumes: - /data/nginx/nginx.conf:/etc/nginx/nginx.conf - /data/gerrit/review_site/etc/passwd:/etc/nginx/passwd
nginx.conf:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { #add start server { listen *:80; server_name gerrit; location / { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/passwd; proxy_pass http://gerrit:8080/; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; } } #add end include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; }
The above involves account number, password, IP address, file path, please modify according to your actual situation.